lib/net/ntlm.rb in rubyntlm-0.5.1 vs lib/net/ntlm.rb in rubyntlm-0.5.2
- old
+ new
@@ -69,10 +69,30 @@
MAX64 = 0xffffffffffffffff
class << self
+ # Valid format for LAN Manager hex digest portion: 32 hexadecimal characters.
+ LAN_MANAGER_HEX_DIGEST_REGEXP = /[0-9a-f]{32}/i
+ # Valid format for NT LAN Manager hex digest portion: 32 hexadecimal characters.
+ NT_LAN_MANAGER_HEX_DIGEST_REGEXP = /[0-9a-f]{32}/i
+ # Valid format for an NTLM hash composed of `'<LAN Manager hex digest>:<NT LAN Manager hex digest>'`.
+ DATA_REGEXP = /\A#{LAN_MANAGER_HEX_DIGEST_REGEXP}:#{NT_LAN_MANAGER_HEX_DIGEST_REGEXP}\z/
+
+ # Takes a string and determines whether it is a valid NTLM Hash
+ # @param [String] the string to validate
+ # @return [Boolean] whether or not the string is a valid NTLM hash
+ def is_ntlm_hash?(data)
+ decoded_data = data.dup
+ decoded_data = EncodeUtil.decode_utf16le(decoded_data)
+ if DATA_REGEXP.match(decoded_data)
+ true
+ else
+ false
+ end
+ end
+
# Conver the value to a 64-Bit Little Endian Int
# @param [String] val The string to convert
def pack_int64le(val)
[val & 0x00000000ffffffff, val >> 32].pack("V2")
end
@@ -127,13 +147,18 @@
end
# Generate a NTLMv2 Hash
# @param [String] user The username
# @param [String] password The password
- # @param [String] target The domain or workstaiton to authenticate to
+ # @param [String] target The domain or workstation to authenticate to
# @option opt :unicode (false) Unicode encode the domain
def ntlmv2_hash(user, password, target, opt={})
- ntlmhash = ntlm_hash(password, opt)
+ if is_ntlm_hash? password
+ decoded_password = EncodeUtil.decode_utf16le(password)
+ ntlmhash = [decoded_password.upcase[33,65]].pack('H32')
+ else
+ ntlmhash = ntlm_hash(password, opt)
+ end
userdomain = user.upcase + target
unless opt[:unicode]
userdomain = EncodeUtil.encode_utf16le(userdomain)
end
OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, ntlmhash, userdomain)