rubyntlm 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -3
  3. data/.rspec +2 -2
  4. data/.travis.yml +10 -11
  5. data/CHANGELOG.md +5 -5
  6. data/Gemfile +3 -3
  7. data/LICENSE +19 -19
  8. data/Rakefile +22 -22
  9. data/lib/net/ntlm.rb +266 -263
  10. data/lib/net/ntlm/blob.rb +28 -28
  11. data/lib/net/ntlm/channel_binding.rb +65 -0
  12. data/lib/net/ntlm/client.rb +65 -65
  13. data/lib/net/ntlm/client/session.rb +237 -223
  14. data/lib/net/ntlm/encode_util.rb +49 -49
  15. data/lib/net/ntlm/exceptions.rb +14 -0
  16. data/lib/net/ntlm/field.rb +34 -34
  17. data/lib/net/ntlm/field_set.rb +129 -129
  18. data/lib/net/ntlm/int16_le.rb +25 -25
  19. data/lib/net/ntlm/int32_le.rb +24 -24
  20. data/lib/net/ntlm/int64_le.rb +25 -25
  21. data/lib/net/ntlm/message.rb +129 -129
  22. data/lib/net/ntlm/message/type0.rb +16 -16
  23. data/lib/net/ntlm/message/type1.rb +18 -18
  24. data/lib/net/ntlm/message/type2.rb +102 -102
  25. data/lib/net/ntlm/message/type3.rb +131 -131
  26. data/lib/net/ntlm/security_buffer.rb +47 -47
  27. data/lib/net/ntlm/string.rb +34 -34
  28. data/lib/net/ntlm/target_info.rb +89 -0
  29. data/lib/net/ntlm/version.rb +11 -11
  30. data/rubyntlm.gemspec +28 -28
  31. data/spec/lib/net/ntlm/blob_spec.rb +16 -16
  32. data/spec/lib/net/ntlm/channel_binding_spec.rb +17 -0
  33. data/spec/lib/net/ntlm/client/session_spec.rb +68 -68
  34. data/spec/lib/net/ntlm/client_spec.rb +64 -64
  35. data/spec/lib/net/ntlm/encode_util_spec.rb +16 -16
  36. data/spec/lib/net/ntlm/field_set_spec.rb +33 -33
  37. data/spec/lib/net/ntlm/field_spec.rb +34 -34
  38. data/spec/lib/net/ntlm/int16_le_spec.rb +17 -17
  39. data/spec/lib/net/ntlm/int32_le_spec.rb +18 -18
  40. data/spec/lib/net/ntlm/int64_le_spec.rb +18 -18
  41. data/spec/lib/net/ntlm/message/type0_spec.rb +20 -20
  42. data/spec/lib/net/ntlm/message/type1_spec.rb +131 -131
  43. data/spec/lib/net/ntlm/message/type2_spec.rb +132 -132
  44. data/spec/lib/net/ntlm/message/type3_spec.rb +225 -225
  45. data/spec/lib/net/ntlm/message_spec.rb +16 -16
  46. data/spec/lib/net/ntlm/security_buffer_spec.rb +64 -64
  47. data/spec/lib/net/ntlm/string_spec.rb +72 -72
  48. data/spec/lib/net/ntlm/target_info_spec.rb +76 -0
  49. data/spec/lib/net/ntlm/version_spec.rb +27 -27
  50. data/spec/lib/net/ntlm_spec.rb +127 -127
  51. data/spec/spec_helper.rb +22 -22
  52. data/spec/support/certificates/sha_256_hash.pem +19 -0
  53. data/spec/support/shared/examples/net/ntlm/field_shared.rb +25 -25
  54. data/spec/support/shared/examples/net/ntlm/fieldset_shared.rb +239 -239
  55. data/spec/support/shared/examples/net/ntlm/int_shared.rb +43 -43
  56. data/spec/support/shared/examples/net/ntlm/message_shared.rb +35 -35
  57. metadata +12 -3
@@ -1,25 +1,25 @@
1
- module Net
2
- module NTLM
3
-
4
- class Int32LE < Field
5
- def initialize(opt)
6
- super(opt)
7
- @size = 4
8
- end
9
-
10
- def parse(str, offset=0)
11
- if @active and str.size >= offset + @size
12
- @value = str.slice(offset, @size).unpack("V")[0]
13
- @size
14
- else
15
- 0
16
- end
17
- end
18
-
19
- def serialize
20
- [@value].pack("V") if @active
21
- end
22
- end
23
-
24
- end
1
+ module Net
2
+ module NTLM
3
+
4
+ class Int32LE < Field
5
+ def initialize(opt)
6
+ super(opt)
7
+ @size = 4
8
+ end
9
+
10
+ def parse(str, offset=0)
11
+ if @active and str.size >= offset + @size
12
+ @value = str.slice(offset, @size).unpack("V")[0]
13
+ @size
14
+ else
15
+ 0
16
+ end
17
+ end
18
+
19
+ def serialize
20
+ [@value].pack("V") if @active
21
+ end
22
+ end
23
+
24
+ end
25
25
  end
@@ -1,26 +1,26 @@
1
- module Net
2
- module NTLM
3
-
4
- class Int64LE < Field
5
- def initialize(opt)
6
- super(opt)
7
- @size = 8
8
- end
9
-
10
- def parse(str, offset=0)
11
- if @active and str.size >= offset + @size
12
- d, u = str.slice(offset, @size).unpack("V2")
13
- @value = (u * 0x100000000 + d)
14
- @size
15
- else
16
- 0
17
- end
18
- end
19
-
20
- def serialize
21
- [@value & 0x00000000ffffffff, @value >> 32].pack("V2") if @active
22
- end
23
- end
24
-
25
- end
1
+ module Net
2
+ module NTLM
3
+
4
+ class Int64LE < Field
5
+ def initialize(opt)
6
+ super(opt)
7
+ @size = 8
8
+ end
9
+
10
+ def parse(str, offset=0)
11
+ if @active and str.size >= offset + @size
12
+ d, u = str.slice(offset, @size).unpack("V2")
13
+ @value = (u * 0x100000000 + d)
14
+ @size
15
+ else
16
+ 0
17
+ end
18
+ end
19
+
20
+ def serialize
21
+ [@value & 0x00000000ffffffff, @value >> 32].pack("V2") if @active
22
+ end
23
+ end
24
+
25
+ end
26
26
  end
@@ -1,129 +1,129 @@
1
- module Net
2
- module NTLM
3
-
4
- SSP_SIGN = "NTLMSSP\0"
5
-
6
- FLAGS = {
7
- :UNICODE => 0x00000001,
8
- :OEM => 0x00000002,
9
- :REQUEST_TARGET => 0x00000004,
10
- :MBZ9 => 0x00000008,
11
- :SIGN => 0x00000010,
12
- :SEAL => 0x00000020,
13
- :NEG_DATAGRAM => 0x00000040,
14
- :NETWARE => 0x00000100,
15
- :NTLM => 0x00000200,
16
- :NEG_NT_ONLY => 0x00000400,
17
- :MBZ7 => 0x00000800,
18
- :DOMAIN_SUPPLIED => 0x00001000,
19
- :WORKSTATION_SUPPLIED => 0x00002000,
20
- :LOCAL_CALL => 0x00004000,
21
- :ALWAYS_SIGN => 0x00008000,
22
- :TARGET_TYPE_DOMAIN => 0x00010000,
23
- :NTLM2_KEY => 0x00080000,
24
- :TARGET_INFO => 0x00800000,
25
- :KEY128 => 0x20000000,
26
- :KEY_EXCHANGE => 0x40000000,
27
- :KEY56 => 0x80000000
28
- }.freeze
29
-
30
- FLAG_KEYS = FLAGS.keys.sort{|a, b| FLAGS[a] <=> FLAGS[b] }
31
-
32
- DEFAULT_FLAGS = {
33
- :TYPE1 => FLAGS[:UNICODE] | FLAGS[:OEM] | FLAGS[:REQUEST_TARGET] | FLAGS[:NTLM] | FLAGS[:ALWAYS_SIGN] | FLAGS[:NTLM2_KEY],
34
- :TYPE2 => FLAGS[:UNICODE],
35
- :TYPE3 => FLAGS[:UNICODE] | FLAGS[:REQUEST_TARGET] | FLAGS[:NTLM] | FLAGS[:ALWAYS_SIGN] | FLAGS[:NTLM2_KEY]
36
- }
37
-
38
-
39
- # @private false
40
- class Message < FieldSet
41
- class << Message
42
- def parse(str)
43
- m = Type0.new
44
- m.parse(str)
45
- case m.type
46
- when 1
47
- t = Type1.new.parse(str)
48
- when 2
49
- t = Type2.new.parse(str)
50
- when 3
51
- t = Type3.new.parse(str)
52
- else
53
- raise ArgumentError, "unknown type: #{m.type}"
54
- end
55
- t
56
- end
57
-
58
- def decode64(str)
59
- parse(Base64.decode64(str))
60
- end
61
- end
62
-
63
- # @return [self]
64
- def parse(str)
65
- super
66
-
67
- while has_disabled_fields? && serialize.size < str.size
68
- # enable the next disabled field
69
- self.class.names.find { |name| !self[name].active && enable(name) }
70
- super
71
- end
72
-
73
- self
74
- end
75
-
76
- def has_flag?(flag)
77
- (self[:flag].value & FLAGS[flag]) == FLAGS[flag]
78
- end
79
-
80
- def set_flag(flag)
81
- self[:flag].value |= FLAGS[flag]
82
- end
83
-
84
- def dump_flags
85
- FLAG_KEYS.each{ |k| print(k, "=", has_flag?(k), "\n") }
86
- end
87
-
88
- def serialize
89
- deflag
90
- super + security_buffers.map{|n, f| f.value}.join
91
- end
92
-
93
- def encode64
94
- Base64.encode64(serialize).gsub(/\n/, '')
95
- end
96
-
97
- def decode64(str)
98
- parse(Base64.decode64(str))
99
- end
100
-
101
- alias head_size size
102
-
103
- def data_size
104
- security_buffers.inject(0){|sum, a| sum += a[1].data_size}
105
- end
106
-
107
- def size
108
- head_size + data_size
109
- end
110
-
111
-
112
- def security_buffers
113
- @alist.find_all{|n, f| f.instance_of?(SecurityBuffer)}
114
- end
115
-
116
- def deflag
117
- security_buffers.inject(head_size){|cur, a|
118
- a[1].offset = cur
119
- cur += a[1].data_size
120
- }
121
- end
122
-
123
- def data_edge
124
- security_buffers.map{ |n, f| f.active ? f.offset : size}.min
125
- end
126
-
127
- end
128
- end
129
- end
1
+ module Net
2
+ module NTLM
3
+
4
+ SSP_SIGN = "NTLMSSP\0"
5
+
6
+ FLAGS = {
7
+ :UNICODE => 0x00000001,
8
+ :OEM => 0x00000002,
9
+ :REQUEST_TARGET => 0x00000004,
10
+ :MBZ9 => 0x00000008,
11
+ :SIGN => 0x00000010,
12
+ :SEAL => 0x00000020,
13
+ :NEG_DATAGRAM => 0x00000040,
14
+ :NETWARE => 0x00000100,
15
+ :NTLM => 0x00000200,
16
+ :NEG_NT_ONLY => 0x00000400,
17
+ :MBZ7 => 0x00000800,
18
+ :DOMAIN_SUPPLIED => 0x00001000,
19
+ :WORKSTATION_SUPPLIED => 0x00002000,
20
+ :LOCAL_CALL => 0x00004000,
21
+ :ALWAYS_SIGN => 0x00008000,
22
+ :TARGET_TYPE_DOMAIN => 0x00010000,
23
+ :NTLM2_KEY => 0x00080000,
24
+ :TARGET_INFO => 0x00800000,
25
+ :KEY128 => 0x20000000,
26
+ :KEY_EXCHANGE => 0x40000000,
27
+ :KEY56 => 0x80000000
28
+ }.freeze
29
+
30
+ FLAG_KEYS = FLAGS.keys.sort{|a, b| FLAGS[a] <=> FLAGS[b] }
31
+
32
+ DEFAULT_FLAGS = {
33
+ :TYPE1 => FLAGS[:UNICODE] | FLAGS[:OEM] | FLAGS[:REQUEST_TARGET] | FLAGS[:NTLM] | FLAGS[:ALWAYS_SIGN] | FLAGS[:NTLM2_KEY],
34
+ :TYPE2 => FLAGS[:UNICODE],
35
+ :TYPE3 => FLAGS[:UNICODE] | FLAGS[:REQUEST_TARGET] | FLAGS[:NTLM] | FLAGS[:ALWAYS_SIGN] | FLAGS[:NTLM2_KEY]
36
+ }
37
+
38
+
39
+ # @private false
40
+ class Message < FieldSet
41
+ class << Message
42
+ def parse(str)
43
+ m = Type0.new
44
+ m.parse(str)
45
+ case m.type
46
+ when 1
47
+ t = Type1.new.parse(str)
48
+ when 2
49
+ t = Type2.new.parse(str)
50
+ when 3
51
+ t = Type3.new.parse(str)
52
+ else
53
+ raise ArgumentError, "unknown type: #{m.type}"
54
+ end
55
+ t
56
+ end
57
+
58
+ def decode64(str)
59
+ parse(Base64.decode64(str))
60
+ end
61
+ end
62
+
63
+ # @return [self]
64
+ def parse(str)
65
+ super
66
+
67
+ while has_disabled_fields? && serialize.size < str.size
68
+ # enable the next disabled field
69
+ self.class.names.find { |name| !self[name].active && enable(name) }
70
+ super
71
+ end
72
+
73
+ self
74
+ end
75
+
76
+ def has_flag?(flag)
77
+ (self[:flag].value & FLAGS[flag]) == FLAGS[flag]
78
+ end
79
+
80
+ def set_flag(flag)
81
+ self[:flag].value |= FLAGS[flag]
82
+ end
83
+
84
+ def dump_flags
85
+ FLAG_KEYS.each{ |k| print(k, "=", has_flag?(k), "\n") }
86
+ end
87
+
88
+ def serialize
89
+ deflag
90
+ super + security_buffers.map{|n, f| f.value}.join
91
+ end
92
+
93
+ def encode64
94
+ Base64.encode64(serialize).gsub(/\n/, '')
95
+ end
96
+
97
+ def decode64(str)
98
+ parse(Base64.decode64(str))
99
+ end
100
+
101
+ alias head_size size
102
+
103
+ def data_size
104
+ security_buffers.inject(0){|sum, a| sum += a[1].data_size}
105
+ end
106
+
107
+ def size
108
+ head_size + data_size
109
+ end
110
+
111
+
112
+ def security_buffers
113
+ @alist.find_all{|n, f| f.instance_of?(SecurityBuffer)}
114
+ end
115
+
116
+ def deflag
117
+ security_buffers.inject(head_size){|cur, a|
118
+ a[1].offset = cur
119
+ cur += a[1].data_size
120
+ }
121
+ end
122
+
123
+ def data_edge
124
+ security_buffers.map{ |n, f| f.active ? f.offset : size}.min
125
+ end
126
+
127
+ end
128
+ end
129
+ end
@@ -1,16 +1,16 @@
1
- module Net
2
- module NTLM
3
- class Message
4
-
5
- # sub class definitions
6
- class Type0 < Message
7
- string :sign, {:size => 8, :value => SSP_SIGN}
8
- int32LE :type, {:value => 0}
9
- end
10
-
11
-
12
- end
13
- end
14
- end
15
-
16
-
1
+ module Net
2
+ module NTLM
3
+ class Message
4
+
5
+ # sub class definitions
6
+ class Type0 < Message
7
+ string :sign, {:size => 8, :value => SSP_SIGN}
8
+ int32LE :type, {:value => 0}
9
+ end
10
+
11
+
12
+ end
13
+ end
14
+ end
15
+
16
+
@@ -1,18 +1,18 @@
1
- module Net
2
- module NTLM
3
- class Message
4
-
5
- # @private false
6
- class Type1 < Message
7
-
8
- string :sign, {:size => 8, :value => SSP_SIGN}
9
- int32LE :type, {:value => 1}
10
- int32LE :flag, {:value => DEFAULT_FLAGS[:TYPE1] }
11
- security_buffer :domain, {:value => ""}
12
- security_buffer :workstation, {:value => Socket.gethostname }
13
- string :os_version, {:size => 8, :value => "", :active => false }
14
-
15
- end
16
- end
17
- end
18
- end
1
+ module Net
2
+ module NTLM
3
+ class Message
4
+
5
+ # @private false
6
+ class Type1 < Message
7
+
8
+ string :sign, {:size => 8, :value => SSP_SIGN}
9
+ int32LE :type, {:value => 1}
10
+ int32LE :flag, {:value => DEFAULT_FLAGS[:TYPE1] }
11
+ security_buffer :domain, {:value => ""}
12
+ security_buffer :workstation, {:value => Socket.gethostname }
13
+ string :os_version, {:size => 8, :value => "", :active => false }
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,102 +1,102 @@
1
- module Net
2
- module NTLM
3
- class Message
4
-
5
- # @private false
6
- class Type2 < Message
7
-
8
- string :sign, { :size => 8, :value => SSP_SIGN }
9
- int32LE :type, { :value => 2 }
10
- security_buffer :target_name, { :size => 0, :value => "" }
11
- int32LE :flag, { :value => DEFAULT_FLAGS[:TYPE2] }
12
- int64LE :challenge, { :value => 0}
13
- int64LE :context, { :value => 0, :active => false }
14
- security_buffer :target_info, { :value => "", :active => false }
15
- string :os_version, { :size => 8, :value => "", :active => false }
16
-
17
- # Generates a Type 3 response based on the Type 2 Information
18
- # @return [Type3]
19
- # @option arg [String] :username The username to authenticate with
20
- # @option arg [String] :password The user's password
21
- # @option arg [String] :domain ('') The domain to authenticate to
22
- # @option opt [String] :workstation (Socket.gethostname) The name of the calling workstation
23
- # @option opt [Boolean] :use_default_target (false) Use the domain supplied by the server in the Type 2 packet
24
- # @note An empty :domain option authenticates to the local machine.
25
- # @note The :use_default_target has precedence over the :domain option
26
- def response(arg, opt = {})
27
- usr = arg[:user]
28
- pwd = arg[:password]
29
- domain = arg[:domain] ? arg[:domain].upcase : ""
30
- if usr.nil? or pwd.nil?
31
- raise ArgumentError, "user and password have to be supplied"
32
- end
33
-
34
- if opt[:workstation]
35
- ws = opt[:workstation]
36
- else
37
- ws = Socket.gethostname
38
- end
39
-
40
- if opt[:client_challenge]
41
- cc = opt[:client_challenge]
42
- else
43
- cc = rand(MAX64)
44
- end
45
- cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
46
- opt[:client_challenge] = cc
47
-
48
- if has_flag?(:OEM) and opt[:unicode]
49
- usr = NTLM::EncodeUtil.decode_utf16le(usr)
50
- pwd = NTLM::EncodeUtil.decode_utf16le(pwd)
51
- ws = NTLM::EncodeUtil.decode_utf16le(ws)
52
- domain = NTLM::EncodeUtil.decode_utf16le(domain)
53
- opt[:unicode] = false
54
- end
55
-
56
- if has_flag?(:UNICODE) and !opt[:unicode]
57
- usr = NTLM::EncodeUtil.encode_utf16le(usr)
58
- pwd = NTLM::EncodeUtil.encode_utf16le(pwd)
59
- ws = NTLM::EncodeUtil.encode_utf16le(ws)
60
- domain = NTLM::EncodeUtil.encode_utf16le(domain)
61
- opt[:unicode] = true
62
- end
63
-
64
- if opt[:use_default_target]
65
- domain = self.target_name
66
- end
67
-
68
- ti = self.target_info
69
-
70
- chal = self[:challenge].serialize
71
-
72
- if opt[:ntlmv2]
73
- ar = {:ntlmv2_hash => NTLM::ntlmv2_hash(usr, pwd, domain, opt), :challenge => chal, :target_info => ti}
74
- lm_res = NTLM::lmv2_response(ar, opt)
75
- ntlm_res = NTLM::ntlmv2_response(ar, opt)
76
- elsif has_flag?(:NTLM2_KEY)
77
- ar = {:ntlm_hash => NTLM::ntlm_hash(pwd, opt), :challenge => chal}
78
- lm_res, ntlm_res = NTLM::ntlm2_session(ar, opt)
79
- else
80
- ar = {:lm_hash => NTLM::lm_hash(pwd), :challenge => chal}
81
- lm_res = NTLM::lm_response(ar)
82
- ar = {:ntlm_hash => NTLM::ntlm_hash(pwd, opt), :challenge => chal}
83
- ntlm_res = NTLM::ntlm_response(ar)
84
- end
85
-
86
- Type3.create({
87
- :lm_response => lm_res,
88
- :ntlm_response => ntlm_res,
89
- :domain => domain,
90
- :user => usr,
91
- :workstation => ws,
92
- :flag => self.flag
93
- })
94
- end
95
-
96
- end
97
-
98
- end
99
- end
100
- end
101
-
102
-
1
+ module Net
2
+ module NTLM
3
+ class Message
4
+
5
+ # @private false
6
+ class Type2 < Message
7
+
8
+ string :sign, { :size => 8, :value => SSP_SIGN }
9
+ int32LE :type, { :value => 2 }
10
+ security_buffer :target_name, { :size => 0, :value => "" }
11
+ int32LE :flag, { :value => DEFAULT_FLAGS[:TYPE2] }
12
+ int64LE :challenge, { :value => 0}
13
+ int64LE :context, { :value => 0, :active => false }
14
+ security_buffer :target_info, { :value => "", :active => false }
15
+ string :os_version, { :size => 8, :value => "", :active => false }
16
+
17
+ # Generates a Type 3 response based on the Type 2 Information
18
+ # @return [Type3]
19
+ # @option arg [String] :username The username to authenticate with
20
+ # @option arg [String] :password The user's password
21
+ # @option arg [String] :domain ('') The domain to authenticate to
22
+ # @option opt [String] :workstation (Socket.gethostname) The name of the calling workstation
23
+ # @option opt [Boolean] :use_default_target (false) Use the domain supplied by the server in the Type 2 packet
24
+ # @note An empty :domain option authenticates to the local machine.
25
+ # @note The :use_default_target has precedence over the :domain option
26
+ def response(arg, opt = {})
27
+ usr = arg[:user]
28
+ pwd = arg[:password]
29
+ domain = arg[:domain] ? arg[:domain].upcase : ""
30
+ if usr.nil? or pwd.nil?
31
+ raise ArgumentError, "user and password have to be supplied"
32
+ end
33
+
34
+ if opt[:workstation]
35
+ ws = opt[:workstation]
36
+ else
37
+ ws = Socket.gethostname
38
+ end
39
+
40
+ if opt[:client_challenge]
41
+ cc = opt[:client_challenge]
42
+ else
43
+ cc = rand(MAX64)
44
+ end
45
+ cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
46
+ opt[:client_challenge] = cc
47
+
48
+ if has_flag?(:OEM) and opt[:unicode]
49
+ usr = NTLM::EncodeUtil.decode_utf16le(usr)
50
+ pwd = NTLM::EncodeUtil.decode_utf16le(pwd)
51
+ ws = NTLM::EncodeUtil.decode_utf16le(ws)
52
+ domain = NTLM::EncodeUtil.decode_utf16le(domain)
53
+ opt[:unicode] = false
54
+ end
55
+
56
+ if has_flag?(:UNICODE) and !opt[:unicode]
57
+ usr = NTLM::EncodeUtil.encode_utf16le(usr)
58
+ pwd = NTLM::EncodeUtil.encode_utf16le(pwd)
59
+ ws = NTLM::EncodeUtil.encode_utf16le(ws)
60
+ domain = NTLM::EncodeUtil.encode_utf16le(domain)
61
+ opt[:unicode] = true
62
+ end
63
+
64
+ if opt[:use_default_target]
65
+ domain = self.target_name
66
+ end
67
+
68
+ ti = self.target_info
69
+
70
+ chal = self[:challenge].serialize
71
+
72
+ if opt[:ntlmv2]
73
+ ar = {:ntlmv2_hash => NTLM::ntlmv2_hash(usr, pwd, domain, opt), :challenge => chal, :target_info => ti}
74
+ lm_res = NTLM::lmv2_response(ar, opt)
75
+ ntlm_res = NTLM::ntlmv2_response(ar, opt)
76
+ elsif has_flag?(:NTLM2_KEY)
77
+ ar = {:ntlm_hash => NTLM::ntlm_hash(pwd, opt), :challenge => chal}
78
+ lm_res, ntlm_res = NTLM::ntlm2_session(ar, opt)
79
+ else
80
+ ar = {:lm_hash => NTLM::lm_hash(pwd), :challenge => chal}
81
+ lm_res = NTLM::lm_response(ar)
82
+ ar = {:ntlm_hash => NTLM::ntlm_hash(pwd, opt), :challenge => chal}
83
+ ntlm_res = NTLM::ntlm_response(ar)
84
+ end
85
+
86
+ Type3.create({
87
+ :lm_response => lm_res,
88
+ :ntlm_response => ntlm_res,
89
+ :domain => domain,
90
+ :user => usr,
91
+ :workstation => ws,
92
+ :flag => self.flag
93
+ })
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+ end
100
+ end
101
+
102
+