class HTTPClient::NegotiateAuth

NegotiateAuth depends on ‘ruby/ntlm’ module.
Used in WWWAuth and ProxyAuth.
Authentication filter for handling Negotiate/NTLM negotiation.

def challenge(uri, param_str)

Challenge handler: remember URL and challenge token for response.
def challenge(uri, param_str)
  return false unless NTLMEnabled
  if param_str.nil? or @challenge[uri].nil?
    c = @challenge[uri] = {}
    c[:state] = :init
    c[:authphrase] = ""
  else
    c = @challenge[uri]
    c[:state] = :response
    c[:authphrase] = param_str
  end
  true
end

def get(req)

See ruby/ntlm for negotiation state transition.
Response handler: returns credential.
def get(req)
  return nil unless NTLMEnabled
  target_uri = req.header.request_uri
  domain_uri, param = @challenge.find { |uri, v|
    Util.uri_part_of(target_uri, uri)
  }
  return nil unless param
  user, passwd = Util.hash_find_value(@auth) { |uri, auth_data|
    Util.uri_part_of(target_uri, uri)
  }
  unless user
    user, passwd = @auth_default
  end
  return nil unless user
  domain = nil
  domain, user = user.split("\\") if user.index("\\")
  state = param[:state]
  authphrase = param[:authphrase]
  case state
  when :init
    t1 = Net::NTLM::Message::Type1.new
    t1.domain = domain
    return t1.encode64
  when :response
    t2 = Net::NTLM::Message.decode64(authphrase)
    param = {:user => user, :password => passwd}
    param[:domain] = domain if domain
    t3 = t2.response(param, @ntlm_opt.dup)
    @challenge.delete(domain_uri)
    return t3.encode64
  end
  nil
end

def initialize(scheme = "Negotiate")

Creates new NegotiateAuth filter.
def initialize(scheme = "Negotiate")
  @auth = {}
  @auth_default = nil
  @challenge = {}
  @scheme = scheme
  @set = false
  @ntlm_opt = {
    :ntlmv2 => true
  }
end

def reset_challenge

server sends '*Authentication' again.
Resets challenge state. Do not send '*Authorization' header until the
def reset_challenge
  @challenge.clear
end

def set(uri, user, passwd)

uri == nil for generic purpose (allow to use user/password for any URL).
Set authentication credential.
def set(uri, user, passwd)
  @set = true
  if uri
    uri = Util.uri_dirname(uri)
    @auth[uri] = [user, passwd]
  else
    @auth_default = [user, passwd]
  end
end

def set?

have we marked this as set - ie that it's valid to use in this context?
def set?
  @set == true
end