class WIKK::Web_Auth

Provides common authentication mechanism for all our cgis. @attr_reader [String] user , the remote user's user name @attr_reader [String] session , the persistent Session record for this user

Constants

VERSION

Attributes

session[R]
user[R]

Public Class Methods

authenticated?(cgi) click to toggle source

way of checking without doing a full login sequence. @param cgi [CGI] Which carries the client data, cookies, and PUT/POST form data. @return [Boolean] authenticated == true.

# File lib/wikk_web_auth.rb, line 44
    def self.authenticated?(cgi)
  begin
      session = CGI::Session.new(cgi, Web_Auth.session_config({'new_session' => false}) )
      authenticated = (session != nil && session['session_expires'] > Time.now && session['auth'] == true && session['ip'] == cgi.remote_addr)
      session.close #Writes back the session data
      return authenticated
  rescue ArgumentError => error # if no old session to find.
      begin
      @log = Syslog::Logger.syslog
    rescue
      @log = Syslog::Logger.new("authlib.rbx")
    end
    @log.error(error.message)
    return false
  end
end
logout(cgi) click to toggle source

get the session reference and delete the session. @param cgi [CGI] Which carries the client data, cookies, and PUT/POST form data.

# File lib/wikk_web_auth.rb, line 63
def self.logout(cgi)
  begin
      session = CGI::Session.new(cgi, Web_Auth.session_config({'new_session' => false}))
      session.delete if session != nil
  rescue ArgumentError => error # if no old session
      begin
      @log = Syslog::Logger.syslog
    rescue
      @log = Syslog::Logger.new("authlib.rbx")
    end
    @log.error(error.message)
  end
end
new(cgi, config, return_url = nil) click to toggle source

Create new Web_Auth instance, and proceed through authentication process by creating a login web form, if the user isn't authenticated. @param cgi [CGI] Which carries the client data, cookies, and PUT/POST form data. @param config [WIKK::Configuration|Hash] the location of the password file is embedded here. @param return_url [String] If we successfully authenticate, return here. @return [WIKK::Web_Auth]

# File lib/wikk_web_auth.rb, line 23
    def initialize(cgi, config, return_url = nil)
  if config.class == Hash
    sym = config.each_with_object({}) { |(k,v),h| h[k.to_sym] = v }
    @config = Struct.new(*(k = sym.keys)).new(*sym.values_at(*k))
  else
      @config = config
    end
      @cgi = cgi
  @user = ''
  @session = nil
      begin
    @log = Syslog::Logger.syslog
  rescue
    @log = Syslog::Logger.new("authlib.rbx")
  end
  authenticate(return_url) 
end
session_config(extra_arguments = {}) click to toggle source

Generate the new Session's config parameters, mixing in and/or overriding the preset values. @param extra_arguments [Hash] Extra arguments that get added to the hash, or override values with the same key. @return [Hash] The configuration hash.

# File lib/wikk_web_auth.rb, line 97
def self.session_config(extra_arguments = {})
  return {
    'database_manager' => CGI::Session::PStore,  # use PStore
    'session_key' => '_wikk_rb_sess_id',              # custom session key
    #'session_id' => ?,
    'session_expires' => (Time.now + 86400),     # 1 day timeout
    'prefix' => 'pstore_sid_',  # PStore option
    'tmpdir' => '/tmp',  # PStore option
    #new_session => ?,#boolean
    #no_hidden => ?,
    #session_domain => ?,
    #session_secure => ?,
    #session_path => ?,
    #no_cookies => ?, #boolean
    #suffix => ?
  }.merge(extra_arguments)
end

Public Instance Methods

authenticate(return_url = nil) click to toggle source

Test to see if we are already authenticated, and if not, generate an HTML login page. @param return_url [String] We return here if we sucessfully login

# File lib/wikk_web_auth.rb, line 121
def authenticate(return_url = nil)
  begin
    @session = CGI::Session.new(@cgi, Web_Auth.session_config({'new_session' => false})) #Look for existing session.
    return gen_html_login_page(return_url) if @session == nil
  rescue ArgumentError => error # if no old session
    return gen_html_login_page(return_url)
  rescue Exception => error
    raise Exception, "Authenticate, CGI::Session.new " + error.message
  end
  
  @session['auth'] = false if @session['session_expires'] < Time.now || #Session has expired
                              @session['ip'] != @cgi.remote_addr || #Not coming from same IP address
                              CGI::escapeHTML(@cgi['logout']) != '' #Are trying to logout
                              
  return if(@session['auth'] == true) #if this is true, then we have already authenticated this session.

  if (challenge = @session['seed']) != '' #see if we are looking at a login response.
    @user = CGI::escapeHTML(@cgi['Username'])
    response = CGI::escapeHTML(@cgi['Response'])
    if  @user != '' && response != '' && authorized?(@user, challenge, response)
      @session['auth'] = true #Response valid.
      @session['user'] = @user
      @session['ip'] = @cgi.remote_addr
      @session['seed'] = '' #Don't use the same one twice.
      @session.close 
      return
    end
  end

  @session.delete #Start a new session.
  gen_html_login_page(return_url)
  @session.close if @session != nil #Saves the session state.
end
authenticated?() click to toggle source

Test to see if user authenticated, @return [Boolean] i.e @authenticated's value.

# File lib/wikk_web_auth.rb, line 162
def authenticated?
  @session != nil && @session['session_expires'] > Time.now && @session['auth'] == true && session['ip'] == @cgi.remote_addr
end
authorized?(user, challenge, received_hash) click to toggle source

Checks password file to see if the response from the user matches generating a hash from the password locally. @param user [String] Who the remote user claims to be @param challenge [String] Random string we sent to this user, and they used in hashing their password. @param received_hash [String] The hex_SHA256(password + challenge) string that the user sent back. @return [Boolean] True for authorization test suceeded.

# File lib/wikk_web_auth.rb, line 82
def authorized?(user, challenge, received_hash)
 begin
   return WIKK::Password.valid_sha256_response?(user, @config, challenge, received_hash)
 rescue IndexError => error #User didn't exist
   @log.error("authorized?(#{user}): " + error.message)
   return false
 rescue Exception => error #Something else
   @log.error("authorized?(#{user}): " + error.message)
   return false
 end
end
gen_html_login_page(return_url = nil) click to toggle source

Used by calling cgi to generate a standard login page @param return_url [String] We return here if we sucessfully login

# File lib/wikk_web_auth.rb, line 169
def gen_html_login_page(return_url = nil)
  session_options = Web_Auth.session_config()
  @session = CGI::Session.new(@cgi, session_options) #Start a new session for future authentications.
  raise "gen_html_login_page: @session == nil" if @session == nil
  challenge = WIKK::AES_256.gen_key_to_s
  session_state_init('auth' => false, 'seed' => challenge, 'ip' => @cgi.remote_addr, 'session_expires' => session_options['session_expires'])
  @cgi.header("type"=>"text/html")
  @cgi.out do
    @cgi.html do
      @cgi.head{ @cgi.title{"login"} + html_nocache + html_script() } +
      @cgi.body {  html_login_form(user, challenge, return_url) + "\n" }
    end
  end
  @session.update
end
html_logout_form(cgi_dir) click to toggle source

Used by calling cgi to generate logout with this form. @param cgi_dir [String] directory holding the login.rbx cgi. @return [String] Html logout form.

# File lib/wikk_web_auth.rb, line 200
    def html_logout_form(cgi_dir)
      <<-EOHTMLF2
      <form NAME="login" ACTION="#{cgi_dir}/login.rbx" METHOD="post">
      <input TYPE="submit" NAME="logout" VALUE="logout" >
      </form>
      EOHTMLF2
    end
html_reload(url = nil) click to toggle source

Used by calling cgi to inject a return URL into the html response. Called by calling cgi, when constructing their html headers. @param url [String] URL to redirect to. @return [String] The HTML meta header, or “”, if url is empty.

# File lib/wikk_web_auth.rb, line 189
def html_reload(url = nil)
  if url != nil && url != ''
    "<meta http-equiv=\"Refresh\" content=\"0; URL=#{url}\">\n"
  else
    ""
  end
end
logout() click to toggle source

clean up the session, setting @authenticated to false and deleting the session state.

# File lib/wikk_web_auth.rb, line 156
def logout 
  @session.delete if @session != nil
end
session_state_init(session_options = {}) click to toggle source
# File lib/wikk_web_auth.rb, line 115
def session_state_init(session_options = {})
  session_options.each { |k,v| @session[k] = v }
end

Private Instance Methods

html_login_form(user, challenge, return_url='') click to toggle source

Generate html login form. @param user [String] user's login name. @param challenge [String] Random bytes to add to password, before sending back to server. @param return_url [String] Pass the url we want to return to if the login succeeds. @return [String] Login form to embed in html response to user.

# File lib/wikk_web_auth.rb, line 234
    def html_login_form(user, challenge, return_url='')
    <<-EOHTMLF
    <form NAME="login" ACTION="/ruby/login.rbx" METHOD="post">
    <input TYPE="hidden" NAME="Challenge" VALUE="#{challenge}"> 
    <input TYPE="hidden" NAME="Response" VALUE="">
    <input TYPE="hidden" NAME="ReturnURL" VALUE="#{return_url}">
    <table>
    <tr><th>User name</th><td><input TYPE="text" NAME="Username" VALUE="#{user}" SIZE="32" MAXLENGTH="32"></td></tr>
    <tr><th>Password</th><td><input TYPE="password" NAME="Password" VALUE="" SIZE="32" MAXLENGTH="32"></td></tr>
    <tr><td>&nbsp;</td><td>
      <input ONCLICK="sendhash(); return false;" TYPE="submit" NAME="login" VALUE="Login">
      <input TYPE="button" NAME="Cancel" VALUE="   Cancel   " 
      ONCLICK="document.login.Username.value='';document.login.Password.value=';return false;'">
    </td></tr>
    </table>
    </form>
    <script LANGUAGE="javascript" TYPE="text/javascript">
          document.login.Username.focus();
    </script>
    EOHTMLF
    end
html_nocache() click to toggle source

Generate no cache metadata header record. @return [String] Html no-cache meta tag

# File lib/wikk_web_auth.rb, line 258
def html_nocache
  "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">"
end
html_script() click to toggle source

Login form javascript helper to SHA256 Hash a password and the challenge string sent by the server. @return [String] Javascript to embed in html response.

# File lib/wikk_web_auth.rb, line 211
    def html_script
      <<-EOHTML
      <script type="text/javascript" src="/js/sha256.js"></script>

      <script language="JavaScript">
      function sendhash() {
          str = document.login.Password.value +
              document.login.Challenge.value;

          document.login.Response.value = hex_sha256(str);
          document.login.Password.value = "";
          document.login.Challenge.value = "";
          document.login.submit();
      }
      </script>
      EOHTML
    end