rubyntlm 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -3
  3. data/README.md +9 -2
  4. data/Rakefile +8 -0
  5. data/examples/http.rb +1 -1
  6. data/lib/net/ntlm.rb +10 -9
  7. data/lib/net/ntlm/blob.rb +17 -6
  8. data/lib/net/ntlm/client.rb +61 -0
  9. data/lib/net/ntlm/client/session.rb +223 -0
  10. data/lib/net/ntlm/encode_util.rb +2 -2
  11. data/lib/net/ntlm/field_set.rb +9 -5
  12. data/lib/net/ntlm/message.rb +23 -9
  13. data/lib/net/ntlm/message/type1.rb +1 -26
  14. data/lib/net/ntlm/message/type2.rb +11 -37
  15. data/lib/net/ntlm/message/type3.rb +77 -14
  16. data/lib/net/ntlm/version.rb +1 -1
  17. data/rubyntlm.gemspec +3 -2
  18. data/spec/lib/net/ntlm/blob_spec.rb +1 -1
  19. data/spec/lib/net/ntlm/client/session_spec.rb +68 -0
  20. data/spec/lib/net/ntlm/client_spec.rb +64 -0
  21. data/spec/lib/net/ntlm/encode_util_spec.rb +3 -3
  22. data/spec/lib/net/ntlm/field_set_spec.rb +4 -4
  23. data/spec/lib/net/ntlm/field_spec.rb +5 -5
  24. data/spec/lib/net/ntlm/message/type1_spec.rb +99 -10
  25. data/spec/lib/net/ntlm/message/type2_spec.rb +68 -24
  26. data/spec/lib/net/ntlm/message/type3_spec.rb +207 -2
  27. data/spec/lib/net/ntlm/security_buffer_spec.rb +8 -8
  28. data/spec/lib/net/ntlm/string_spec.rb +14 -14
  29. data/spec/lib/net/ntlm/version_spec.rb +7 -6
  30. data/spec/lib/net/ntlm_spec.rb +20 -22
  31. data/spec/spec_helper.rb +1 -2
  32. data/spec/support/shared/examples/net/ntlm/field_shared.rb +3 -3
  33. data/spec/support/shared/examples/net/ntlm/fieldset_shared.rb +34 -34
  34. data/spec/support/shared/examples/net/ntlm/int_shared.rb +8 -8
  35. data/spec/support/shared/examples/net/ntlm/message_shared.rb +3 -3
  36. metadata +36 -16
@@ -4,13 +4,13 @@ describe Net::NTLM::EncodeUtil do
4
4
 
5
5
  context '#encode_utf16le' do
6
6
  it 'should convert an ASCII string to UTF' do
7
- Net::NTLM::EncodeUtil.encode_utf16le('Test').should == "T\x00e\x00s\x00t\x00"
7
+ expect(Net::NTLM::EncodeUtil.encode_utf16le('Test')).to eq("T\x00e\x00s\x00t\x00")
8
8
  end
9
9
  end
10
10
 
11
11
  context '#decode_utf16le' do
12
12
  it 'should convert a UTF string to ASCII' do
13
- Net::NTLM::EncodeUtil.decode_utf16le("T\x00e\x00s\x00t\x00").should == 'Test'
13
+ expect(Net::NTLM::EncodeUtil.decode_utf16le("T\x00e\x00s\x00t\x00")).to eq('Test')
14
14
  end
15
15
  end
16
- end
16
+ end
@@ -18,16 +18,16 @@ describe Net::NTLM::FieldSet do
18
18
  end
19
19
 
20
20
  it 'should serialize all the fields' do
21
- fieldset_object.serialize.should == 'TestFoo'
21
+ expect(fieldset_object.serialize).to eq('TestFoo')
22
22
  end
23
23
 
24
24
  it 'should parse a string across the fields' do
25
25
  fieldset_object.parse('FooBarBaz')
26
- fieldset_object.serialize.should == 'FooBarB'
26
+ expect(fieldset_object.serialize).to eq('FooBarB')
27
27
  end
28
28
 
29
29
  it 'should return an aggregate size of all the fields' do
30
- fieldset_object.size.should == 7
30
+ expect(fieldset_object.size).to eq(7)
31
31
  end
32
32
  end
33
- end
33
+ end
@@ -7,12 +7,12 @@ describe Net::NTLM::Field do
7
7
  context 'with no size specified' do
8
8
  let (:field_without_size) { Net::NTLM::Field.new({ :value => 'Foo', :active => true }) }
9
9
  it 'should set size to 0 if not active' do
10
- field_without_size.size.should == 0
10
+ expect(field_without_size.size).to eq(0)
11
11
  end
12
12
 
13
13
  it 'should return 0 if active but no size specified' do
14
14
  field_without_size.active = true
15
- field_without_size.size.should == 0
15
+ expect(field_without_size.size).to eq(0)
16
16
  end
17
17
  end
18
18
 
@@ -20,15 +20,15 @@ describe Net::NTLM::Field do
20
20
  let (:field_with_size) { Net::NTLM::Field.new({ :value => 'Foo', :active => true, :size => 100 }) }
21
21
 
22
22
  it 'should return the size provided in the initialize options if active' do
23
- field_with_size.size.should == 100
23
+ expect(field_with_size.size).to eq(100)
24
24
  end
25
25
 
26
26
  it 'should still return 0 if not active' do
27
27
  field_with_size.active = false
28
- field_with_size.size.should == 0
28
+ expect(field_with_size.size).to eq(0)
29
29
  end
30
30
  end
31
31
 
32
32
 
33
33
 
34
- end
34
+ end
@@ -7,7 +7,7 @@ describe Net::NTLM::Message::Type1 do
7
7
  { :name => :flag, :class => Net::NTLM::Int32LE, :value => Net::NTLM::DEFAULT_FLAGS[:TYPE1], :active => true },
8
8
  { :name => :domain, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
9
9
  { :name => :workstation, :class => Net::NTLM::SecurityBuffer, :value => Socket.gethostname, :active => true },
10
- { :name => :padding, :class => Net::NTLM::String, :value => '', :active => false },
10
+ { :name => :os_version, :class => Net::NTLM::String, :value => '', :active => false },
11
11
  ]
12
12
  flags = [
13
13
  :UNICODE,
@@ -24,19 +24,108 @@ describe Net::NTLM::Message::Type1 do
24
24
 
25
25
  it 'should deserialize' do
26
26
  t1 = Net::NTLM::Message.decode64(type1_packet)
27
- t1.class.should == Net::NTLM::Message::Type1
28
- t1.domain.should == ''
29
- t1.flag.should == 557575
30
- t1.padding.should == ''
31
- t1.sign.should == "NTLMSSP\0"
32
- t1.type.should == 1
33
- t1.workstation.should == ''
27
+ expect(t1.class).to eq(Net::NTLM::Message::Type1)
28
+ expect(t1.domain).to eq('')
29
+ expect(t1.flag).to eq(557575)
30
+ expect(t1.os_version).to eq('')
31
+ expect(t1.sign).to eq("NTLMSSP\0")
32
+ expect(t1.type).to eq(1)
33
+ expect(t1.workstation).to eq('')
34
34
  end
35
35
 
36
36
  it 'should serialize' do
37
37
  t1 = Net::NTLM::Message::Type1.new
38
38
  t1.workstation = ''
39
- t1.encode64.should == type1_packet
39
+ expect(t1.encode64).to eq(type1_packet)
40
40
  end
41
41
 
42
- end
42
+ describe '.parse' do
43
+ subject(:message) { described_class.parse(data) }
44
+ # http://davenport.sourceforge.net/ntlm.html#appendixC7
45
+ context 'NTLM2 Session Response Authentication; NTLM2 Signing and Sealing Using the 128-bit NTLM2 Session Response User Session Key With Key Exchange Negotiated' do
46
+ let(:data) do
47
+ ['4e544c4d5353500001000000b78208e000000000000000000000000000000000'].pack('H*')
48
+ end
49
+
50
+ it 'should set the magic' do
51
+ expect(message.sign).to eql(Net::NTLM::SSP_SIGN)
52
+ end
53
+ it 'should set the type' do
54
+ expect(message.type).to eq(1)
55
+ end
56
+ it 'should set the flags' do
57
+ expect(message.flag).to eq(0xe00882b7)
58
+ expect(message).to have_flag(:UNICODE)
59
+ expect(message).to have_flag(:OEM)
60
+ expect(message).to have_flag(:REQUEST_TARGET)
61
+ expect(message).to have_flag(:SIGN)
62
+ expect(message).to have_flag(:SEAL)
63
+ expect(message).to have_flag(:NTLM)
64
+ expect(message).to have_flag(:ALWAYS_SIGN)
65
+ expect(message).to have_flag(:NTLM2_KEY)
66
+ expect(message).to have_flag(:KEY128)
67
+ expect(message).to have_flag(:KEY_EXCHANGE)
68
+ expect(message).to have_flag(:KEY56)
69
+ end
70
+ it 'should have empty workstation' do
71
+ expect(message.workstation).to be_empty
72
+ end
73
+ it 'should have empty domain' do
74
+ expect(message.domain).to be_empty
75
+ end
76
+
77
+ end
78
+
79
+ # http://davenport.sourceforge.net/ntlm.html#appendixC9
80
+ context 'NTLMv2 Authentication; NTLM1 Signing and Sealing Using the 40-bit NTLMv2 User Session Key' do
81
+ let(:data) { ['4e544c4d53535000010000003782000000000000000000000000000000000000'].pack('H*') }
82
+
83
+ it 'should set the magic' do
84
+ expect(message.sign).to eql(Net::NTLM::SSP_SIGN)
85
+ end
86
+ it 'should set the type' do
87
+ expect(message.type).to eq(1)
88
+ end
89
+ it 'should set the flags' do
90
+ expect(message.flag).to eq(0x00008237)
91
+ expect(message).to have_flag(:UNICODE)
92
+ expect(message).to have_flag(:OEM)
93
+ expect(message).to have_flag(:REQUEST_TARGET)
94
+ expect(message).to have_flag(:SIGN)
95
+ expect(message).to have_flag(:SEAL)
96
+ expect(message).to have_flag(:NTLM)
97
+ expect(message).to have_flag(:ALWAYS_SIGN)
98
+ end
99
+ it 'should have empty workstation' do
100
+ expect(message.workstation).to be_empty
101
+ end
102
+ it 'should have empty domain' do
103
+ expect(message.domain).to be_empty
104
+ end
105
+ end
106
+
107
+ context 'NTLMv2 with OS version' do
108
+ let(:data) { ['4e544c4d5353500001000000978208e2000000000000000000000000000000000602f0230000000f'].pack('H*') }
109
+
110
+ it 'should set the magic' do
111
+ expect(message.sign).to eql(Net::NTLM::SSP_SIGN)
112
+ end
113
+ it 'should set the type' do
114
+ expect(message.type).to eq(1)
115
+ end
116
+ it 'should have empty workstation' do
117
+ expect(message.workstation).to be_empty
118
+ end
119
+ it 'should have empty domain' do
120
+ expect(message.domain).to be_empty
121
+ end
122
+
123
+ it 'should set OS version info' do
124
+ expect(message.os_version).to eq(['0602f0230000000f'].pack('H*'))
125
+ end
126
+
127
+ end
128
+
129
+ end
130
+
131
+ end
@@ -11,7 +11,7 @@ describe Net::NTLM::Message::Type2 do
11
11
  { :name => :flag, :class => Net::NTLM::Int32LE, :value => Net::NTLM::DEFAULT_FLAGS[:TYPE2], :active => true },
12
12
  { :name => :target_name, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
13
13
  { :name => :target_info, :class => Net::NTLM::SecurityBuffer, :value => '', :active => false },
14
- { :name => :padding, :class => Net::NTLM::String, :value => '', :active => false },
14
+ { :name => :os_version, :class => Net::NTLM::String, :value => '', :active => false },
15
15
  ]
16
16
  flags = [
17
17
  :UNICODE
@@ -24,24 +24,22 @@ describe Net::NTLM::Message::Type2 do
24
24
 
25
25
  it 'should deserialize' do
26
26
  t2 = Net::NTLM::Message.decode64(type2_packet)
27
- t2.class.should == Net::NTLM::Message::Type2
28
- t2.challenge.should == 14872292244261496103
29
- t2.context.should == 0
30
- t2.flag.should == 42631685
31
- if "".respond_to?(:force_encoding)
32
- t2.padding.should == ("\x06\x01\xB1\x1D\0\0\0\x0F".force_encoding('ASCII-8BIT'))
33
- end
34
- t2.sign.should == "NTLMSSP\0"
27
+ expect(t2.class).to eq(Net::NTLM::Message::Type2)
28
+ expect(t2.challenge).to eq(14872292244261496103)
29
+ expect(t2.context).to eq(0)
30
+ expect(t2.flag).to eq(42631685)
31
+ expect(t2.os_version).to eq(['0601b11d0000000f'].pack('H*'))
32
+ expect(t2.sign).to eq("NTLMSSP\0")
35
33
 
36
34
  t2_target_info = Net::NTLM::EncodeUtil.decode_utf16le(t2.target_info)
37
35
  if RUBY_VERSION == "1.8.7"
38
- t2_target_info.should == "\x02\x1CVAGRANT-2008R2\x01\x1CVAGRANT-2008R2\x04\x1Cvagrant-2008R2\x03\x1Cvagrant-2008R2\a\b\e$(D+&\e(B\0\0"
36
+ expect(t2_target_info).to eq("\x02\x1CVAGRANT-2008R2\x01\x1CVAGRANT-2008R2\x04\x1Cvagrant-2008R2\x03\x1Cvagrant-2008R2\a\b\e$(D+&\e(B\0\0")
39
37
  else
40
- t2_target_info.should == "\u0002\u001CVAGRANT-2008R2\u0001\u001CVAGRANT-2008R2\u0004\u001Cvagrant-2008R2\u0003\u001Cvagrant-2008R2\a\b፤ᐝ❴ǎ\0\0"
38
+ expect(t2_target_info).to eq("\u0002\u001CVAGRANT-2008R2\u0001\u001CVAGRANT-2008R2\u0004\u001Cvagrant-2008R2\u0003\u001Cvagrant-2008R2\a\b፤ᐝ❴ǎ\0\0")
41
39
  end
42
40
 
43
- Net::NTLM::EncodeUtil.decode_utf16le(t2.target_name).should == "VAGRANT-2008R2"
44
- t2.type.should == 2
41
+ expect(Net::NTLM::EncodeUtil.decode_utf16le(t2.target_name)).to eq("VAGRANT-2008R2")
42
+ expect(t2.type).to eq(2)
45
43
  end
46
44
 
47
45
  it 'should serialize' do
@@ -51,16 +49,16 @@ describe Net::NTLM::Message::Type2 do
51
49
  t2.challenge = source.challenge
52
50
  t2.context = source.context
53
51
  t2.flag = source.flag
54
- t2.padding = source.padding
52
+ t2.os_version = source.os_version
55
53
  t2.sign = source.sign
56
54
  t2.target_info = source.target_info
57
55
  t2.target_name = source.target_name
58
56
  t2.type = source.type
59
57
  t2.enable(:context)
60
58
  t2.enable(:target_info)
61
- t2.enable(:padding)
59
+ t2.enable(:os_version)
62
60
 
63
- t2.encode64.should == type2_packet
61
+ expect(t2.encode64).to eq(type2_packet)
64
62
  end
65
63
 
66
64
  it 'should generate a type 3 response' do
@@ -72,17 +70,63 @@ describe Net::NTLM::Message::Type2 do
72
70
  type3_known.enable(:flag)
73
71
 
74
72
  t3 = t2.response({:user => 'vagrant', :password => 'vagrant', :domain => ''}, {:ntlmv2 => true, :workstation => 'kobe.local'})
75
- t3.domain.should == type3_known.domain
76
- t3.flag.should == type3_known.flag
77
- t3.sign.should == "NTLMSSP\0"
78
- t3.workstation.should == "k\0o\0b\0e\0.\0l\0o\0c\0a\0l\0"
79
- t3.user.should == "v\0a\0g\0r\0a\0n\0t\0"
80
- t3.session_key.should == ''
73
+ expect(t3.domain).to eq(type3_known.domain)
74
+ expect(t3.flag).to eq(type3_known.flag)
75
+ expect(t3.sign).to eq("NTLMSSP\0")
76
+ expect(t3.workstation).to eq("k\0o\0b\0e\0.\0l\0o\0c\0a\0l\0")
77
+ expect(t3.user).to eq("v\0a\0g\0r\0a\0n\0t\0")
78
+ expect(t3.session_key).to eq('')
81
79
  end
82
80
 
83
81
  it 'should upcase domain when provided' do
84
82
  t2 = Net::NTLM::Message.decode64(type2_packet)
85
83
  t3 = t2.response({:user => 'vagrant', :password => 'vagrant', :domain => 'domain'}, {:ntlmv2 => true, :workstation => 'kobe.local'})
86
- t3.domain.should == "D\0O\0M\0A\0I\0N\0"
84
+ expect(t3.domain).to eq("D\0O\0M\0A\0I\0N\0")
87
85
  end
88
- end
86
+
87
+ describe '.parse' do
88
+ subject(:message) { described_class.parse(data) }
89
+ # http://davenport.sourceforge.net/ntlm.html#appendixC7
90
+ context 'NTLM2 Session Response Authentication; NTLM2 Signing and Sealing Using the 128-bit NTLM2 Session Response User Session Key With Key Exchange Negotiated' do
91
+ let(:data) do
92
+ [
93
+ '4e544c4d53535000020000000c000c0030000000358289e0677f1c557a5ee96c' \
94
+ '0000000000000000460046003c00000054004500530054004e00540002000c00' \
95
+ '54004500530054004e00540001000c004d0045004d0042004500520003001e00' \
96
+ '6d0065006d006200650072002e0074006500730074002e0063006f006d000000' \
97
+ '0000'
98
+ ].pack('H*')
99
+ end
100
+
101
+ it 'should set the magic' do
102
+ expect(message.sign).to eql(Net::NTLM::SSP_SIGN)
103
+ end
104
+ it 'should set the type' do
105
+ expect(message.type).to eq(2)
106
+ end
107
+ it 'should set the target name' do
108
+ # TESTNT
109
+ expect(message.target_name).to eq(["54004500530054004e005400"].pack('H*'))
110
+ end
111
+ it 'should set the flags' do
112
+ expect(message.flag).to eq(0xe0898235)
113
+ end
114
+ it 'should set the challenge' do
115
+ expect(message.challenge).to eq(0x6ce95e7a551c7f67)
116
+ end
117
+ it 'should set an empty context' do
118
+ expect(message.context).to be_zero
119
+ end
120
+ it 'should set target info' do
121
+ ti = [
122
+ '02000c0054004500530054004e00540001000c004d0045004d00420045005200' \
123
+ '03001e006d0065006d006200650072002e0074006500730074002e0063006f00' \
124
+ '6d0000000000'
125
+ ].pack('H*')
126
+ expect(message.target_info).to eq(ti)
127
+ end
128
+
129
+ end
130
+ end
131
+
132
+ end
@@ -5,16 +5,221 @@ describe Net::NTLM::Message::Type3 do
5
5
  fields = [
6
6
  { :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
7
7
  { :name => :type, :class => Net::NTLM::Int32LE, :value => 3, :active => true },
8
- { :name => :flag, :class => Net::NTLM::Int64LE, :value => 0, :active => false },
9
8
  { :name => :lm_response, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
10
9
  { :name => :ntlm_response, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
11
10
  { :name => :domain, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
12
11
  { :name => :user, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
13
12
  { :name => :workstation, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
14
13
  { :name => :session_key, :class => Net::NTLM::SecurityBuffer, :value => '', :active => false },
14
+ { :name => :flag, :class => Net::NTLM::Int32LE, :value => 0, :active => false },
15
15
  ]
16
16
  flags = []
17
17
  it_behaves_like 'a fieldset', fields
18
18
  it_behaves_like 'a message', flags
19
19
 
20
- end
20
+ describe '.parse' do
21
+ subject(:message) { described_class.parse(data) }
22
+
23
+ context 'with NTLMv2 data' do
24
+ let(:data) do
25
+ # Captured NTLMSSP blob from smbclient with username 'administrator'
26
+ # and a blank password, i.e.:
27
+ # smbclient -U 'administrator%' -L //192.168.100.140/
28
+ [
29
+ '4e544c4d53535000030000001800180040000000c400c4005800000012001200' \
30
+ '1c0100001a001a002e0100001a001a0048010000100010006201000015820860' \
31
+ 'ced203d860b80c7350050754b238202a8c1c63134f0ae0f086a3fb147e8b2f9f' \
32
+ 'de3ef1b1b43c83dc010100000000000080512dba020ed0011c5bc2c8339fd29a' \
33
+ '0000000002001e00570049004e002d00420035004a004e003300520048004700' \
34
+ '46003300310001001e00570049004e002d00420035004a004e00330052004800' \
35
+ '470046003300310004001e00570049004e002d00420035004a004e0033005200' \
36
+ '4800470046003300310003001e00570049004e002d00420035004a004e003300' \
37
+ '52004800470046003300310007000800a209e5ba020ed0010000000057004f00' \
38
+ '52004b00470052004f0055005000610064006d0069006e006900730074007200' \
39
+ '610074006f0072004100550053002d004c004500450054002d00310030003300' \
40
+ '31007036615cd6d9b19a685ded4312311cd7'
41
+ ].pack('H*')
42
+ end
43
+
44
+ let(:server_challenge) { ['f588469dc96fe809'].pack('H*') }
45
+
46
+ it 'should set the magic' do
47
+ expect(message.sign).to eql(Net::NTLM::SSP_SIGN)
48
+ end
49
+ it 'should set the type' do
50
+ expect(message.type).to eq(3)
51
+ end
52
+ it 'should set the LM response' do
53
+ lm_response = ['ced203d860b80c7350050754b238202a8c1c63134f0ae0f0'].pack('H*')
54
+ expect(message.lm_response).to eq(lm_response)
55
+ end
56
+ it 'should set the NTLM response' do
57
+ ntlm_response = [
58
+ '86a3fb147e8b2f9fde3ef1b1b43c83dc010100000000000080512dba020ed001' \
59
+ '1c5bc2c8339fd29a0000000002001e00570049004e002d00420035004a004e00' \
60
+ '330052004800470046003300310001001e00570049004e002d00420035004a00' \
61
+ '4e00330052004800470046003300310004001e00570049004e002d0042003500' \
62
+ '4a004e00330052004800470046003300310003001e00570049004e002d004200' \
63
+ '35004a004e00330052004800470046003300310007000800a209e5ba020ed001' \
64
+ '00000000'
65
+ ].pack('H*')
66
+ expect(message.ntlm_response).to eq(ntlm_response)
67
+ end
68
+ it 'should set the user' do
69
+ # administrator
70
+ user = ['610064006d0069006e006900730074007200610074006f007200'].pack('H*')
71
+ expect(message.user).to eq(user)
72
+ end
73
+ it 'should set the domain' do
74
+ # WORKGROUP
75
+ domain = ['57004f0052004b00470052004f0055005000'].pack('H*')
76
+ expect(message.domain).to eq(domain)
77
+ end
78
+ it 'should set the workstation' do
79
+ # AUS-LEET-1031
80
+ workstation = ['4100550053002d004c004500450054002d003100300033003100'].pack('H*')
81
+ expect(message.workstation).to eq(workstation)
82
+ end
83
+ it 'should set the session key' do
84
+ session_key = ['7036615cd6d9b19a685ded4312311cd7'].pack('H*')
85
+ expect(message.session_key).to eq(session_key)
86
+ end
87
+
88
+ it 'should set the flags' do
89
+ expect(message.flag).to eq(0x60088215)
90
+ end
91
+
92
+ it 'should NOT set the OS version structure' do
93
+ expect(message.os_version).to be_nil
94
+ end
95
+
96
+ describe '#blank_password?' do
97
+ it 'should be true' do
98
+ expect(message.blank_password?(server_challenge)).to be true
99
+ end
100
+ end
101
+
102
+ describe '#ntlm_version' do
103
+ let(:ver) { message.ntlm_version }
104
+ it 'should be :ntlmv2' do
105
+ expect(ver).to eq(:ntlmv2)
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ # http://davenport.sourceforge.net/ntlm.html#appendixC7
112
+ context 'NTLM2 Session Response Authentication; NTLM2 Signing and Sealing Using the 128-bit NTLM2 Session Response User Session Key With Key Exchange Negotiated' do
113
+
114
+ let(:data) do
115
+ [
116
+ '4e544c4d5353500003000000180018006000000018001800780000000c000c00' \
117
+ '40000000080008004c0000000c000c00540000001000100090000000358288e0' \
118
+ '54004500530054004e00540074006500730074004d0045004d00420045005200' \
119
+ '404d1b6f6915258000000000000000000000000000000000ea8cc49f24da157f' \
120
+ '13436637f77693d8b992d619e584c7ee727a5240822ec7af4e9100c43e6fee7f'
121
+ ].pack('H*')
122
+ end
123
+
124
+ it 'should set the LM response' do
125
+ lm_response = ['404d1b6f6915258000000000000000000000000000000000'].pack('H*')
126
+ expect(message.lm_response).to eq(lm_response)
127
+ end
128
+ it 'should set the NTLM response' do
129
+ ntlm_response = [ 'ea8cc49f24da157f13436637f77693d8b992d619e584c7ee' ].pack('H*')
130
+ expect(message.ntlm_response).to eq(ntlm_response)
131
+ end
132
+ it 'should set the domain' do
133
+ # TESTNT
134
+ domain = ['54004500530054004e005400'].pack('H*')
135
+ expect(message.domain).to eq(domain)
136
+ end
137
+ it 'should set the user' do
138
+ # test
139
+ user = ['7400650073007400'].pack('H*')
140
+ expect(message.user).to eq(user)
141
+ end
142
+ it 'should set the workstation' do
143
+ # MEMBER
144
+ workstation = ['4d0045004d00420045005200'].pack('H*')
145
+ expect(message.workstation).to eq(workstation)
146
+ end
147
+ it 'should set the session key' do
148
+ session_key = ['727a5240822ec7af4e9100c43e6fee7f'].pack('H*')
149
+ expect(message.session_key).to eq(session_key)
150
+ end
151
+
152
+ let(:server_challenge) { ['677f1c557a5ee96c'].pack('H*') }
153
+ describe '#password?' do
154
+ it 'should be true for "test1234"' do
155
+ expect(message.password?('test1234', server_challenge)).to be true
156
+ end
157
+ end
158
+ describe '#blank_password?' do
159
+ it 'should be false' do
160
+ expect(message.blank_password?(server_challenge)).to be false
161
+ end
162
+ end
163
+
164
+ describe '#ntlm_version' do
165
+ let(:ver) { message.ntlm_version }
166
+ it 'should be :ntlm2_session' do
167
+ expect(ver).to eq(:ntlm2_session)
168
+ end
169
+ end
170
+
171
+ end
172
+
173
+ # http://davenport.sourceforge.net/ntlm.html#appendixC9
174
+ context 'NTLMv2 Authentication; NTLM1 Signing and Sealing Using the 40-bit NTLMv2 User Session Key' do
175
+ let(:data) do
176
+ [
177
+ '4e544c4d5353500003000000180018006000000076007600780000000c000c00' \
178
+ '40000000080008004c0000000c000c005400000000000000ee00000035828000' \
179
+ '54004500530054004e00540074006500730074004d0045004d00420045005200' \
180
+ '5d55a02b60a40526ac9a1e4d15fa45a0f2e6329726c598e8f77c67dad00b9321' \
181
+ '6242b197fe6addfa0101000000000000502db638677bc301f2e6329726c598e8' \
182
+ '0000000002000c0054004500530054004e00540001000c004d0045004d004200' \
183
+ '4500520003001e006d0065006d006200650072002e0074006500730074002e00' \
184
+ '63006f006d000000000000000000'
185
+ ].pack 'H*'
186
+ end
187
+
188
+ it 'should set the NTLM response' do
189
+ ntlm_response = [
190
+ 'f77c67dad00b93216242b197fe6addfa0101000000000000502db638677bc301' \
191
+ 'f2e6329726c598e80000000002000c0054004500530054004e00540001000c00' \
192
+ '4d0045004d0042004500520003001e006d0065006d006200650072002e007400' \
193
+ '6500730074002e0063006f006d000000000000000000'
194
+ ].pack 'H*'
195
+ expect(message.ntlm_response).to eq(ntlm_response)
196
+ end
197
+
198
+ it 'should set the domain' do
199
+ # TESTNT
200
+ domain = ['54004500530054004e005400'].pack('H*')
201
+ expect(message.domain).to eq(domain)
202
+ end
203
+ it 'should set the user' do
204
+ # test
205
+ user = ['7400650073007400'].pack('H*')
206
+ expect(message.user).to eq(user)
207
+ end
208
+ it 'should set the workstation' do
209
+ # MEMBER
210
+ workstation = ['4d0045004d00420045005200'].pack('H*')
211
+ expect(message.workstation).to eq(workstation)
212
+ end
213
+
214
+ describe '#ntlm_version' do
215
+ let(:ver) { message.ntlm_version }
216
+ it 'should be :ntlmv2' do
217
+ expect(ver).to eq(:ntlmv2)
218
+ end
219
+ end
220
+
221
+ end
222
+
223
+ end
224
+
225
+ end