class Net::NTLM::Message::Type3

@private false

Public Class Methods

create(arg, opt ={}) click to toggle source

Builds a Type 3 packet @note All options must be properly encoded with either unicode or oem encoding @return [Type3] @option arg [String] :lm_response The LM hash @option arg [String] :ntlm_response The NTLM hash @option arg [String] :domain The domain to authenticate to @option arg [String] :workstation The name of the calling workstation @option arg [String] :session_key The session key @option arg [Integer] :flag Flags for the packet

# File lib/net/ntlm/message/type3.rb, line 29
def create(arg, opt ={})
  t = new
  t.lm_response = arg[:lm_response]
  t.ntlm_response = arg[:ntlm_response]
  t.domain = arg[:domain]
  t.user = arg[:user]

  if arg[:workstation]
    t.workstation = arg[:workstation]
  end

  if arg[:session_key]
    t.enable(:session_key)
    t.session_key = arg[:session_key]
  end

  if arg[:flag]
    t.enable(:session_key)
    t.enable(:flag)
    t.flag = arg[:flag]
  end
  t
end

Public Instance Methods

blank_password?(server_challenge) click to toggle source

@param server_challenge (see password?)

# File lib/net/ntlm/message/type3.rb, line 55
def blank_password?(server_challenge)
  password?('', server_challenge)
end
ntlm_version() click to toggle source

@return [Symbol]

# File lib/net/ntlm/message/type3.rb, line 77
def ntlm_version
  if ntlm_response.size == 24 && lm_response[0,8] != "\x00"*8 && lm_response[8,16] == "\x00"*16
    :ntlm2_session
  elsif ntlm_response.size == 24
    :ntlmv1
  elsif ntlm_response.size > 24
    :ntlmv2
  end
end
password?(password, server_challenge) click to toggle source

@param password [String] @param server_challenge [String] The server's {Type2#challenge challenge} from the

{Type2} message for which this object is a response.

@return [true] if password was the password used to generate this

{Type3} message

@return [false] otherwise

# File lib/net/ntlm/message/type3.rb, line 65
def password?(password, server_challenge)
  case ntlm_version
  when :ntlm2_session
    ntlm2_session_password?(password, server_challenge)
  when :ntlmv2
    ntlmv2_password?(password, server_challenge)
  else
    raise
  end
end

Private Instance Methods

ntlm2_session_password?(password, server_challenge) click to toggle source
# File lib/net/ntlm/message/type3.rb, line 89
def ntlm2_session_password?(password, server_challenge)
  hash = ntlm_response
  _lm, empty_hash = NTLM.ntlm2_session(
    {
      :ntlm_hash => NTLM.ntlm_hash(password),
      :challenge => server_challenge,
    },
    {
      :client_challenge => lm_response[0,8]
    }
  )
  hash == empty_hash
end
ntlmv2_password?(password, server_challenge) click to toggle source
# File lib/net/ntlm/message/type3.rb, line 103
def ntlmv2_password?(password, server_challenge)

  # The first 16 bytes of the ntlm_response are the HMAC of the blob
  # that follows it.
  blob = Blob.new
  blob.parse(ntlm_response[16..-1])

  empty_hash = NTLM.ntlmv2_response(
    {
      # user and domain came from the serialized data here, so
      # they're already unicode
      :ntlmv2_hash => NTLM.ntlmv2_hash(user, '', domain, :unicode => true),
      :challenge => server_challenge,
      :target_info => blob.target_info
    },
    {
      :client_challenge => blob.challenge,
      # The blob's timestamp is already in milliseconds since 1601,
      # so convert it back to epoch time first
      :timestamp => (blob.timestamp / 10_000_000) - NTLM::TIME_OFFSET,
    }
  )

  empty_hash == ntlm_response
end