daily pastebin goal
44%
SHARE
TWEET

Untitled

a guest Mar 16th, 2018 77 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. require 'krb5_auth'
  2.  
  3. module Rack
  4.   module Auth
  5.     class Kerberos
  6.       # The version of the rack-auth-kerberos library.
  7.       VERSION = '0.2.0'
  8.  
  9.       # Creates a new Rack::Kerberos object. The +user_field+ and +password_field+
  10.       # are the params looked for in the call method. The defaults are 'username'
  11.       # and 'password', respectively.
  12.       #
  13.       # If the optional +realm+ parameter is supplied it will override the
  14.       # default realm specified in your krb5.conf file.
  15.       #
  16.       # The realm is automatically appended to the username if not already
  17.       # present. This makes it easier for application developers, i.e. they can
  18.       # supply a username with or without a realm and it will Just Work (TM).
  19.       #
  20.       def initialize(app, user_field = 'username', password_field = 'password', realm = nil)
  21.         @app = app
  22.         @user_field = user_field
  23.         @password_field = password_field
  24.         @kerberos = Krb5Auth::Krb5.new
  25.  
  26.         if realm
  27.           @realm = realm
  28.         else
  29.           @realm = @kerberos.get_default_realm
  30.         end
  31.       end
  32.  
  33.       # The call method we've defined first checks to see if the AUTH_USER
  34.       # environment variable is set. If it is, we assume that the user has
  35.       # already been authenticated and move on.
  36.       #
  37.       # If AUTH_USER is not set, and AUTH_FAIL is not set, we then attempt
  38.       # to authenticate the user against the Kerberos server. If successful
  39.       # then AUTH_USER is set to the username.
  40.       #
  41.       # If unsuccessful then AUTH_USER is set to nil and AUTH_FAIL is
  42.       # set to an appropriate error message.
  43.       #
  44.       # It is then up to the application to check for the presence of AUTH_USER
  45.       # and/or AUTH_FAIL and act as necessary.
  46.       #
  47.       def call(env)
  48.         request = Rack::Request.new(env)
  49.  
  50.         user = request.params[@user_field]
  51.         password = request.params[@password_field]
  52.  
  53.         # Only authenticate user if both the username and password fields are present
  54.         unless user && password
  55.           return @app.call(env)
  56.         end
  57.  
  58.         # Automatically append the realm if not already present
  59.         user_with_realm = user.dup
  60.         user_with_realm += "@#{@realm}" unless user.include?('@')
  61.  
  62.         # Do not authenticate if either one of these is set
  63.         if env['AUTH_USER'] || env['AUTH_FAIL']
  64.           return @app.call(env)
  65.         end
  66.  
  67.         begin
  68.           @kerberos.get_init_creds_password(user_with_realm, password)
  69.          
  70.           env['AUTH_USER'] = user
  71.           env['AUTH_TYPE'] = "Kerberos Password"
  72.           env['AUTH_TYPE_USER'] = user_with_realm
  73.           env['AUTH_TYPE_THIS_REQUEST'] = "Kerberos Password"
  74.           env['AUTH_DATETIME'] = Time.now.utc
  75.          
  76.           env.delete('AUTH_FAIL')
  77.         rescue Krb5Auth::Krb5::Exception => err
  78.           case err.message
  79.             when /client not found/i
  80.               msg = "Invalid userid '#{user}'"
  81.             when /integrity check failed/i
  82.               msg = "Invalid password for '#{user}'"
  83.             else
  84.               msg = "Error attempting to validate userid and password"
  85.           end
  86.  
  87.           env.delete('AUTH_USER')
  88.           env['AUTH_FAIL'] = msg
  89.         rescue => err
  90.           env.delete('AUTH_USER')
  91.           env['AUTH_FAIL'] = "Unexpected failure during Kerberos authentication"
  92.         ensure
  93.           @kerberos.close
  94.         end
  95.  
  96.         @app.call(env)
  97.       end
  98.     end
  99.   end
  100. end
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top