class Thin::NTLMWrapper
Constants
- AUTHORIZATION_MESSAGE
- AUTHORIZATION_MESSAGE_LENGTH
- CONTENT_LENGTH
- CONTENT_TYPE
- CONTENT_TYPE_AUTH
- HTTP_AUTHORIZATION
- NTLM_ALLOWED_PACKAGE
- NTLM_REQUEST_PACKAGE
- REMOTE_USER
- WWW_AUTHENTICATE
Public Class Methods
new(app, connection)
click to toggle source
# File lib/thin/ntlm/connection.rb, line 30 def initialize(app, connection) @app = app @connection = WeakRef.new(connection) end
Public Instance Methods
acquire(package = 'NTLM')
click to toggle source
Acquires new OS credentials handle
# File lib/thin/ntlm/connection.rb, line 93 def acquire(package = 'NTLM') cleanup @ntlm = Win32::SSPI::NegotiateServer.new(package) @ntlm.acquire_credentials_handle @ntlm end
call(env)
click to toggle source
# File lib/thin/ntlm/connection.rb, line 55 def call(env) # check if browser wants to reauthenticate if @authenticated_as && http_authorization(env) @authenticated_as = nil end # require authentication unless @authenticated_as ntlm_start @authentication_stage ||= 1 result = process(env) return result unless @authenticated_as ntlm_stop end # pass thru env[REMOTE_USER] = @authenticated_as @app.call(env) end
can_persist!()
click to toggle source
# File lib/thin/ntlm/connection.rb, line 43 def can_persist! @connection.can_persist! end
cleanup()
click to toggle source
Frees credentials handle, if acquired
# File lib/thin/ntlm/connection.rb, line 101 def cleanup if @ntlm @ntlm.cleanup rescue nil @ntlm = nil end nil end
deferred?(env)
click to toggle source
# File lib/thin/ntlm/connection.rb, line 35 def deferred?(env) @app.respond_to?(:deferred?) && @app.deferred?(env) end
ntlm_start()
click to toggle source
# File lib/thin/ntlm/connection.rb, line 47 def ntlm_start @connection.ntlm_start end
ntlm_stop()
click to toggle source
# File lib/thin/ntlm/connection.rb, line 51 def ntlm_stop @connection.ntlm_stop end
persistent?()
click to toggle source
# File lib/thin/ntlm/connection.rb, line 39 def persistent? @connection.request.persistent? end
process(env)
click to toggle source
Processes current authentication stage Returns rack response if authentication is incomplete Sets @authenticated_as to username if authentication successful
# File lib/thin/ntlm/connection.rb, line 112 def process(env) case @authentication_stage when 1 # we are waiting for type1 message package, t1 = token(env) return request_auth(NTLM_REQUEST_PACKAGE, false) if t1.nil? return request_auth unless persistent? begin acquire(package) t2 = @ntlm.accept_security_context(t1) rescue return request_auth end request_auth("#{package} #{t2}", false, 2) when 2 # we are waiting for type3 message package, t3 = token(env) return request_auth(NTLM_REQUEST_PACKAGE, false) if t3.nil? return request_auth unless package == @ntlm.package return request_auth unless persistent? begin t2 = @ntlm.accept_security_context(t3) @authenticated_as = @ntlm.get_username_from_context @authentication_stage = nil # in case IE wants to reauthenticate rescue return request_auth end return request_auth unless @authenticated_as cleanup else raise "Invalid value for @authentication_stage=#{@authentication_stage} detected" end end
request_auth(auth = nil, finished = true, next_stage = 1)
click to toggle source
Returns response with authentication request to the client
# File lib/thin/ntlm/connection.rb, line 145 def request_auth(auth = nil, finished = true, next_stage = 1) @authentication_stage = next_stage can_persist! unless finished head = {} head[WWW_AUTHENTICATE] = auth if auth head[CONTENT_TYPE] = CONTENT_TYPE_AUTH head[CONTENT_LENGTH] = AUTHORIZATION_MESSAGE_LENGTH [401, head, [AUTHORIZATION_MESSAGE]] end
token(env)
click to toggle source
Returns token type and value from HTTP-Authorization header
# File lib/thin/ntlm/connection.rb, line 86 def token(env) auth = http_authorization(env) return [nil, nil] unless auth && auth.match(/\A(#{NTLM_ALLOWED_PACKAGE}) (.*)\Z/) [$1, Base64.decode64($2.strip)] end