Guest User

Untitled

a guest
Mar 16th, 2018
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.36 KB | None | 0 0
  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
Add Comment
Please, Sign In to add comment