Module: Net::NTLM

### Home Classes Methods

### In Files

- lib/net/ntlm.rb
- lib/net/ntlm_http.rb

### Namespace

- CLASS Net::NTLM::Field
- CLASS Net::NTLM::FieldSet
- CLASS Net::NTLM::Int16LE
- CLASS Net::NTLM::Int32LE
- CLASS Net::NTLM::Int64LE
- CLASS Net::NTLM::Message
- CLASS Net::NTLM::SecurityBuffer
- CLASS Net::NTLM::String

### Methods

- ::apply_des
- ::decode_utf16le
- ::encode_utf16le
- ::gen_keys
- ::lm_hash
- ::lm_response
- ::lmv2_response
- ::ntlm2_session
- ::ntlm_hash
- ::ntlm_response
- ::ntlmv2_hash
- ::ntlmv2_response
- ::pack_int64le
- ::split7
- ::swap16

### Files

- README

### Class/Module Index

Quicksearch

- Net
- Net::HTTP
- Net::HTTPHeader
- Net::HTTPRequest
- Net::NTLM
- Net::NTLM::Field
- Net::NTLM::FieldSet
- Net::NTLM::Int16LE
- Net::NTLM::Int32LE
- Net::NTLM::Int64LE
- Net::NTLM::Message
- Net::NTLM::Message::Type1
- Net::NTLM::Message::Type2
- Net::NTLM::Message::Type3
- Net::NTLM::SecurityBuffer
- Net::NTLM::String

No matching classes.

# Net::NTLM

### Constants

BLOB_SIGN
Blob
DEFAULT_FLAGS
FLAGS
FLAG_KEYS
LM_MAGIC
MAX64
SSP_SIGN
SecurityBuffer
TIME_OFFSET

### Public Class Methods

apply_des(plain, keys) click to toggle source

    # File lib/net/ntlm.rb, line 130
    def apply_des(plain, keys)
      dec = OpenSSL::Cipher::DES.new
      keys.map {|k|
        dec.key = k
        dec.encrypt.update(plain)
      }
    end

decode_utf16le(str) click to toggle source

    # File lib/net/ntlm.rb, line 98
    def decode_utf16le(str)
      Kconv.kconv(swap16(str), Kconv::ASCII, Kconv::UTF16)
    end

encode_utf16le(str) click to toggle source

    # File lib/net/ntlm.rb, line 102
    def encode_utf16le(str)
      swap16(Kconv.kconv(str, Kconv::UTF16, Kconv::ASCII))
    end

gen_keys(str) click to toggle source

    # File lib/net/ntlm.rb, line 122
    def gen_keys(str)
      split7(str).map{ |str7|
        bits = split7(str7.unpack("B*")[0]).inject('')\
          {|ret, tkn| ret += tkn + (tkn.gsub('1', '').size % 2).to_s }
        [bits].pack("B*")
      }
    end

lm_hash(password) click to toggle source

    # File lib/net/ntlm.rb, line 138
    def lm_hash(password)
      keys = gen_keys password.upcase.ljust(14, "\00"")
      apply_des(LM_MAGIC, keys).join
    end

lm_response(arg) click to toggle source

responses

    # File lib/net/ntlm.rb, line 161
    def lm_response(arg)
      begin
        hash = arg[:lm_hash]
        chal = arg[:challenge]
      rescue
        raise ArgumentError
      end
      chal = NTL::pack_int64le(chal) if chal.is_a?(Integer)
      keys = gen_keys hash.ljust(21, "\00"")
      apply_des(chal, keys).join
    end

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

    # File lib/net/ntlm.rb, line 215
    def lmv2_response(arg, opt = {})
      key = arg[:ntlmv2_hash]
      chal = arg[:challenge]

      chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)

      if opt[:client_challenge]
        cc  = opt[:client_challenge]
      else
        cc = rand(MAX64)
      end
      cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)

      OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + cc) + cc
    end

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

    # File lib/net/ntlm.rb, line 231
    def ntlm2_session(arg, opt = {})
      begin
        passwd_hash = arg[:ntlm_hash]
        chal = arg[:challenge]
      rescue
        raise ArgumentError
      end

      if opt[:client_challenge]
        cc  = opt[:client_challenge]
      else
        cc = rand(MAX64)
      end
      cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)

      keys = gen_keys passwd_hash.ljust(21, "\00"")
      session_hash = OpenSSL::Digest::MD5.digest(chal + cc).slice(0, 8)
      response = apply_des(session_hash, keys).join
      [cc.ljust(24, "\00""), response]
    end

ntlm_hash(password, opt = {}) click to toggle source

    # File lib/net/ntlm.rb, line 143
    def ntlm_hash(password, opt = {})
      pwd = password.dup
      unless opt[:unicode]
        pwd = encode_utf16le(pwd)
      end
      OpenSSL::Digest::MD4.digest pwd
    end

ntlm_response(arg) click to toggle source

    # File lib/net/ntlm.rb, line 173
    def ntlm_response(arg)
      hash = arg[:ntlm_hash]
      chal = arg[:challenge]
      chal = NTL::pack_int64le(chal) if chal.is_a?(Integer)
      keys = gen_keys hash.ljust(21, "\00"")
      apply_des(chal, keys).join
    end

ntlmv2_hash(user, password, target, opt={}) click to toggle source

    # File lib/net/ntlm.rb, line 151
    def ntlmv2_hash(user, password, target, opt={})
      ntlmhash = ntlm_hash(password, opt)
      userdomain = (user + target).upcase
      unless opt[:unicode]
        userdomain = encode_utf16le(userdomain)
      end
      OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, ntlmhash, userdomain)
    end

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

    # File lib/net/ntlm.rb, line 181
    def ntlmv2_response(arg, opt = {})
      begin
        key = arg[:ntlmv2_hash]
        chal = arg[:challenge]
        ti = arg[:target_info]
      rescue
        raise ArgumentError
      end
      chal = NTL::pack_int64le(chal) if chal.is_a?(Integer)

      if opt[:client_challenge]
        cc  = opt[:client_challenge]
      else
        cc = rand(MAX64)
      end
      cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)

      if opt[:timestamp]
        ts = opt[:timestamp]
      else
        ts = Time.now.to_i
      end
      # epoch -> milsec from Jan 1, 1601

      ts = 10000000 * (ts + TIME_OFFSET)

      blob = Blob.new
      blob.timestamp = ts
      blob.challenge = cc
      blob.target_info = ti

      bb = blob.serialize
      OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + bb) + bb
    end

pack_int64le(val) click to toggle source

    # File lib/net/ntlm.rb, line 106
    def pack_int64le(val)
        [val & 0x00000000ffffffff, val >> 32].pack("V2")
    end

split7(str) click to toggle source

    # File lib/net/ntlm.rb, line 114
    def split7(str)
      s = str.dup
      until s.empty?
        (ret ||= []).push s.slice!(0, 7)
      end
      ret
    end

swap16(str) click to toggle source

    # File lib/net/ntlm.rb, line 110
    def swap16(str)
      str.unpack("v*").pack("n*")
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.