rubyntlm 0.6.6 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/README.md +48 -48
  4. data/lib/net/ntlm/blob.rb +11 -10
  5. data/lib/net/ntlm/channel_binding.rb +13 -9
  6. data/lib/net/ntlm/client/session.rb +34 -141
  7. data/lib/net/ntlm/client/session_crypto.rb +126 -0
  8. data/lib/net/ntlm/client.rb +8 -9
  9. data/lib/net/ntlm/encode_util.rb +39 -38
  10. data/lib/net/ntlm/exceptions.rb +3 -0
  11. data/lib/net/ntlm/field.rb +29 -31
  12. data/lib/net/ntlm/field_set.rb +39 -18
  13. data/lib/net/ntlm/int16_le.rb +8 -8
  14. data/lib/net/ntlm/int32_le.rb +8 -7
  15. data/lib/net/ntlm/int64_le.rb +8 -7
  16. data/lib/net/ntlm/md4.rb +102 -64
  17. data/lib/net/ntlm/message/type0.rb +4 -7
  18. data/lib/net/ntlm/message/type1.rb +8 -9
  19. data/lib/net/ntlm/message/type2.rb +87 -67
  20. data/lib/net/ntlm/message/type3.rb +43 -41
  21. data/lib/net/ntlm/message.rb +116 -111
  22. data/lib/net/ntlm/rc4.rb +51 -44
  23. data/lib/net/ntlm/response.rb +112 -0
  24. data/lib/net/ntlm/security_buffer.rb +13 -15
  25. data/lib/net/ntlm/string.rb +8 -7
  26. data/lib/net/ntlm/target_info.rb +52 -44
  27. data/lib/net/ntlm/version.rb +3 -1
  28. data/lib/net/ntlm.rb +37 -125
  29. data/lib/rubyntlm.rb +3 -1
  30. metadata +5 -44
  31. data/.devcontainer/devcontainer.json +0 -22
  32. data/.github/dependabot.yml +0 -10
  33. data/.github/workflows/build.yml +0 -55
  34. data/.gitignore +0 -11
  35. data/.rspec +0 -3
  36. data/Gemfile +0 -20
  37. data/Rakefile +0 -37
  38. data/examples/http.rb +0 -86
  39. data/examples/imap.rb +0 -73
  40. data/examples/smtp.rb +0 -94
  41. data/rubyntlm.gemspec +0 -28
  42. data/spec/lib/net/ntlm/blob_spec.rb +0 -14
  43. data/spec/lib/net/ntlm/channel_binding_spec.rb +0 -15
  44. data/spec/lib/net/ntlm/client/session_spec.rb +0 -85
  45. data/spec/lib/net/ntlm/client_spec.rb +0 -62
  46. data/spec/lib/net/ntlm/encode_util_spec.rb +0 -14
  47. data/spec/lib/net/ntlm/field_set_spec.rb +0 -31
  48. data/spec/lib/net/ntlm/field_spec.rb +0 -32
  49. data/spec/lib/net/ntlm/int16_le_spec.rb +0 -16
  50. data/spec/lib/net/ntlm/int32_le_spec.rb +0 -17
  51. data/spec/lib/net/ntlm/int64_le_spec.rb +0 -17
  52. data/spec/lib/net/ntlm/md4_spec.rb +0 -16
  53. data/spec/lib/net/ntlm/message/type0_spec.rb +0 -19
  54. data/spec/lib/net/ntlm/message/type1_spec.rb +0 -129
  55. data/spec/lib/net/ntlm/message/type2_spec.rb +0 -131
  56. data/spec/lib/net/ntlm/message/type3_spec.rb +0 -336
  57. data/spec/lib/net/ntlm/message_spec.rb +0 -15
  58. data/spec/lib/net/ntlm/security_buffer_spec.rb +0 -62
  59. data/spec/lib/net/ntlm/string_spec.rb +0 -70
  60. data/spec/lib/net/ntlm/target_info_spec.rb +0 -74
  61. data/spec/lib/net/ntlm/version_spec.rb +0 -26
  62. data/spec/lib/net/ntlm_spec.rb +0 -133
  63. data/spec/spec_helper.rb +0 -51
  64. data/spec/support/certificates/sha_256_hash.pem +0 -19
  65. data/spec/support/shared/examples/net/ntlm/field_shared.rb +0 -25
  66. data/spec/support/shared/examples/net/ntlm/fieldset_shared.rb +0 -239
  67. data/spec/support/shared/examples/net/ntlm/int_shared.rb +0 -43
  68. data/spec/support/shared/examples/net/ntlm/message_shared.rb +0 -35
@@ -1,131 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- RSpec.describe Net::NTLM::Message::Type2 do
4
-
5
- fields = [
6
- { :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
7
- { :name => :type, :class => Net::NTLM::Int32LE, :value => 2, :active => true },
8
- { :name => :challenge, :class => Net::NTLM::Int64LE, :value => 0, :active => true },
9
- { :name => :context, :class => Net::NTLM::Int64LE, :value => 0, :active => false },
10
- { :name => :flag, :class => Net::NTLM::Int32LE, :value => Net::NTLM::DEFAULT_FLAGS[:TYPE2], :active => true },
11
- { :name => :target_name, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
12
- { :name => :target_info, :class => Net::NTLM::SecurityBuffer, :value => '', :active => false },
13
- { :name => :os_version, :class => Net::NTLM::String, :value => '', :active => false },
14
- ]
15
- flags = [
16
- :UNICODE
17
- ]
18
- it_behaves_like 'a fieldset', fields
19
- it_behaves_like 'a message', flags
20
-
21
- let(:type2_packet) {"TlRMTVNTUAACAAAAHAAcADgAAAAFgooCJ+UA1//+ZM4AAAAAAAAAAJAAkABUAAAABgGxHQAAAA9WAEEARwBSAEEATgBUAC0AMgAwADAAOABSADIAAgAcAFYAQQBHAFIAQQBOAFQALQAyADAAMAA4AFIAMgABABwAVgBBAEcAUgBBAE4AVAAtADIAMAAwADgAUgAyAAQAHAB2AGEAZwByAGEAbgB0AC0AMgAwADAAOABSADIAAwAcAHYAYQBnAHIAYQBuAHQALQAyADAAMAA4AFIAMgAHAAgAZBMdFHQnzgEAAAAA"}
22
- let(:type3_packet) {"TlRMTVNTUAADAAAAGAAYAEQAAADAAMAAXAAAAAAAAAAcAQAADgAOABwBAAAUABQAKgEAAAAAAAA+AQAABYKKAgAAAADVS27TfQGmWxSSbXmolTUQyxJmD8ISQuBKKHFKC8GksUZISYc8Ps9RAQEAAAAAAAAANasTdCfOAcsSZg/CEkLgAAAAAAIAHABWAEEARwBSAEEATgBUAC0AMgAwADAAOABSADIAAQAcAFYAQQBHAFIAQQBOAFQALQAyADAAMAA4AFIAMgAEABwAdgBhAGcAcgBhAG4AdAAtADIAMAAwADgAUgAyAAMAHAB2AGEAZwByAGEAbgB0AC0AMgAwADAAOABSADIABwAIAGQTHRR0J84BAAAAAAAAAAB2AGEAZwByAGEAbgB0AGsAbwBiAGUALgBsAG8AYwBhAGwA"}
23
-
24
- it 'should deserialize' do
25
- t2 = Net::NTLM::Message.decode64(type2_packet)
26
- expect(t2.class).to eq(Net::NTLM::Message::Type2)
27
- expect(t2.challenge).to eq(14872292244261496103)
28
- expect(t2.context).to eq(0)
29
- expect(t2.flag).to eq(42631685)
30
- expect(t2.os_version).to eq(['0601b11d0000000f'].pack('H*'))
31
- expect(t2.sign).to eq("NTLMSSP\0")
32
-
33
- t2_target_info = Net::NTLM::EncodeUtil.decode_utf16le(t2.target_info)
34
- if RUBY_VERSION == "1.8.7"
35
- 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")
36
- else
37
- expect(t2_target_info).to eq("\u0002\u001CVAGRANT-2008R2\u0001\u001CVAGRANT-2008R2\u0004\u001Cvagrant-2008R2\u0003\u001Cvagrant-2008R2\a\b፤ᐝ❴ǎ\0\0")
38
- end
39
-
40
- expect(Net::NTLM::EncodeUtil.decode_utf16le(t2.target_name)).to eq("VAGRANT-2008R2")
41
- expect(t2.type).to eq(2)
42
- end
43
-
44
- it 'should serialize' do
45
- source = Net::NTLM::Message.decode64(type2_packet)
46
-
47
- t2 = Net::NTLM::Message::Type2.new
48
- t2.challenge = source.challenge
49
- t2.context = source.context
50
- t2.flag = source.flag
51
- t2.os_version = source.os_version
52
- t2.sign = source.sign
53
- t2.target_info = source.target_info
54
- t2.target_name = source.target_name
55
- t2.type = source.type
56
- t2.enable(:context)
57
- t2.enable(:target_info)
58
- t2.enable(:os_version)
59
-
60
- expect(t2.encode64).to eq(type2_packet)
61
- end
62
-
63
- it 'should generate a type 3 response' do
64
- t2 = Net::NTLM::Message.decode64(type2_packet)
65
-
66
- type3_known = Net::NTLM::Message.decode64(type3_packet)
67
- type3_known.flag = 0x028a8205
68
- type3_known.enable(:session_key)
69
- type3_known.enable(:flag)
70
-
71
- t3 = t2.response({:user => 'vagrant', :password => 'vagrant', :domain => ''}, {:ntlmv2 => true, :workstation => 'kobe.local'})
72
- expect(t3.domain).to eq(type3_known.domain)
73
- expect(t3.flag).to eq(type3_known.flag)
74
- expect(t3.sign).to eq("NTLMSSP\0")
75
- expect(t3.workstation).to eq("k\0o\0b\0e\0.\0l\0o\0c\0a\0l\0")
76
- expect(t3.user).to eq("v\0a\0g\0r\0a\0n\0t\0")
77
- expect(t3.session_key).to eq('')
78
- end
79
-
80
- it 'should upcase domain when provided' do
81
- t2 = Net::NTLM::Message.decode64(type2_packet)
82
- t3 = t2.response({:user => 'vagrant', :password => 'vagrant', :domain => 'domain'}, {:ntlmv2 => true, :workstation => 'kobe.local'})
83
- expect(t3.domain).to eq("D\0O\0M\0A\0I\0N\0")
84
- end
85
-
86
- describe '.parse' do
87
- subject(:message) { described_class.parse(data) }
88
- # http://davenport.sourceforge.net/ntlm.html#appendixC7
89
- context 'NTLM2 Session Response Authentication; NTLM2 Signing and Sealing Using the 128-bit NTLM2 Session Response User Session Key With Key Exchange Negotiated' do
90
- let(:data) do
91
- [
92
- '4e544c4d53535000020000000c000c0030000000358289e0677f1c557a5ee96c' \
93
- '0000000000000000460046003c00000054004500530054004e00540002000c00' \
94
- '54004500530054004e00540001000c004d0045004d0042004500520003001e00' \
95
- '6d0065006d006200650072002e0074006500730074002e0063006f006d000000' \
96
- '0000'
97
- ].pack('H*')
98
- end
99
-
100
- it 'should set the magic' do
101
- expect(message.sign).to eql(Net::NTLM::SSP_SIGN)
102
- end
103
- it 'should set the type' do
104
- expect(message.type).to eq(2)
105
- end
106
- it 'should set the target name' do
107
- # TESTNT
108
- expect(message.target_name).to eq(["54004500530054004e005400"].pack('H*'))
109
- end
110
- it 'should set the flags' do
111
- expect(message.flag).to eq(0xe0898235)
112
- end
113
- it 'should set the challenge' do
114
- expect(message.challenge).to eq(0x6ce95e7a551c7f67)
115
- end
116
- it 'should set an empty context' do
117
- expect(message.context).to be_zero
118
- end
119
- it 'should set target info' do
120
- ti = [
121
- '02000c0054004500530054004e00540001000c004d0045004d00420045005200' \
122
- '03001e006d0065006d006200650072002e0074006500730074002e0063006f00' \
123
- '6d0000000000'
124
- ].pack('H*')
125
- expect(message.target_info).to eq(ti)
126
- end
127
-
128
- end
129
- end
130
-
131
- end
@@ -1,336 +0,0 @@
1
- RSpec.describe Net::NTLM::Message::Type3 do
2
-
3
- fields = [
4
- { :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
5
- { :name => :type, :class => Net::NTLM::Int32LE, :value => 3, :active => true },
6
- { :name => :lm_response, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
7
- { :name => :ntlm_response, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
8
- { :name => :domain, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
9
- { :name => :user, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
10
- { :name => :workstation, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
11
- { :name => :session_key, :class => Net::NTLM::SecurityBuffer, :value => '', :active => false },
12
- { :name => :flag, :class => Net::NTLM::Int32LE, :value => 0, :active => false },
13
- ]
14
- flags = []
15
- it_behaves_like 'a fieldset', fields
16
- it_behaves_like 'a message', flags
17
-
18
- describe '.parse' do
19
- subject(:message) { described_class.parse(data) }
20
-
21
- context 'with NTLMv2 data' do
22
- let(:data) do
23
- # Captured NTLMSSP blob from smbclient with username 'administrator'
24
- # and a blank password, i.e.:
25
- # smbclient -U 'administrator%' -L //192.168.100.140/
26
- [
27
- '4e544c4d53535000030000001800180040000000c400c4005800000012001200' \
28
- '1c0100001a001a002e0100001a001a0048010000100010006201000015820860' \
29
- 'ced203d860b80c7350050754b238202a8c1c63134f0ae0f086a3fb147e8b2f9f' \
30
- 'de3ef1b1b43c83dc010100000000000080512dba020ed0011c5bc2c8339fd29a' \
31
- '0000000002001e00570049004e002d00420035004a004e003300520048004700' \
32
- '46003300310001001e00570049004e002d00420035004a004e00330052004800' \
33
- '470046003300310004001e00570049004e002d00420035004a004e0033005200' \
34
- '4800470046003300310003001e00570049004e002d00420035004a004e003300' \
35
- '52004800470046003300310007000800a209e5ba020ed0010000000057004f00' \
36
- '52004b00470052004f0055005000610064006d0069006e006900730074007200' \
37
- '610074006f0072004100550053002d004c004500450054002d00310030003300' \
38
- '31007036615cd6d9b19a685ded4312311cd7'
39
- ].pack('H*')
40
- end
41
-
42
- let(:server_challenge) { ['f588469dc96fe809'].pack('H*') }
43
-
44
- it 'should set the magic' do
45
- expect(message.sign).to eql(Net::NTLM::SSP_SIGN)
46
- end
47
- it 'should set the type' do
48
- expect(message.type).to eq(3)
49
- end
50
- it 'should set the LM response' do
51
- lm_response = ['ced203d860b80c7350050754b238202a8c1c63134f0ae0f0'].pack('H*')
52
- expect(message.lm_response).to eq(lm_response)
53
- end
54
- it 'should set the NTLM response' do
55
- ntlm_response = [
56
- '86a3fb147e8b2f9fde3ef1b1b43c83dc010100000000000080512dba020ed001' \
57
- '1c5bc2c8339fd29a0000000002001e00570049004e002d00420035004a004e00' \
58
- '330052004800470046003300310001001e00570049004e002d00420035004a00' \
59
- '4e00330052004800470046003300310004001e00570049004e002d0042003500' \
60
- '4a004e00330052004800470046003300310003001e00570049004e002d004200' \
61
- '35004a004e00330052004800470046003300310007000800a209e5ba020ed001' \
62
- '00000000'
63
- ].pack('H*')
64
- expect(message.ntlm_response).to eq(ntlm_response)
65
- end
66
- it 'should set the user' do
67
- # administrator
68
- user = ['610064006d0069006e006900730074007200610074006f007200'].pack('H*')
69
- expect(message.user).to eq(user)
70
- end
71
- it 'should set the domain' do
72
- # WORKGROUP
73
- domain = ['57004f0052004b00470052004f0055005000'].pack('H*')
74
- expect(message.domain).to eq(domain)
75
- end
76
- it 'should set the workstation' do
77
- # AUS-LEET-1031
78
- workstation = ['4100550053002d004c004500450054002d003100300033003100'].pack('H*')
79
- expect(message.workstation).to eq(workstation)
80
- end
81
- it 'should set the session key' do
82
- session_key = ['7036615cd6d9b19a685ded4312311cd7'].pack('H*')
83
- expect(message.session_key).to eq(session_key)
84
- end
85
-
86
- it 'should set the flags' do
87
- expect(message.flag).to eq(0x60088215)
88
- end
89
-
90
- it 'should NOT set the OS version structure' do
91
- expect(message.os_version).to be_nil
92
- end
93
-
94
- describe '#blank_password?' do
95
- it 'should be true' do
96
- expect(message.blank_password?(server_challenge)).to be true
97
- end
98
- end
99
-
100
- it 'rejects a non-empty password for an empty-password response' do
101
- expect(message.password?('test1234', server_challenge)).to be false
102
- end
103
-
104
- describe '#ntlm_version' do
105
- let(:ver) { message.ntlm_version }
106
- it 'should be :ntlmv2' do
107
- expect(ver).to eq(:ntlmv2)
108
- end
109
- end
110
-
111
- end
112
-
113
- # http://davenport.sourceforge.net/ntlm.html#appendixC7
114
- context 'NTLM2 Session Response Authentication; NTLM2 Signing and Sealing Using the 128-bit NTLM2 Session Response User Session Key With Key Exchange Negotiated' do
115
-
116
- let(:data) do
117
- [
118
- '4e544c4d5353500003000000180018006000000018001800780000000c000c00' \
119
- '40000000080008004c0000000c000c00540000001000100090000000358288e0' \
120
- '54004500530054004e00540074006500730074004d0045004d00420045005200' \
121
- '404d1b6f6915258000000000000000000000000000000000ea8cc49f24da157f' \
122
- '13436637f77693d8b992d619e584c7ee727a5240822ec7af4e9100c43e6fee7f'
123
- ].pack('H*')
124
- end
125
-
126
- it 'should set the LM response' do
127
- lm_response = ['404d1b6f6915258000000000000000000000000000000000'].pack('H*')
128
- expect(message.lm_response).to eq(lm_response)
129
- end
130
- it 'should set the NTLM response' do
131
- ntlm_response = [ 'ea8cc49f24da157f13436637f77693d8b992d619e584c7ee' ].pack('H*')
132
- expect(message.ntlm_response).to eq(ntlm_response)
133
- end
134
- it 'should set the domain' do
135
- # TESTNT
136
- domain = ['54004500530054004e005400'].pack('H*')
137
- expect(message.domain).to eq(domain)
138
- end
139
- it 'should set the user' do
140
- # test
141
- user = ['7400650073007400'].pack('H*')
142
- expect(message.user).to eq(user)
143
- end
144
- it 'should set the workstation' do
145
- # MEMBER
146
- workstation = ['4d0045004d00420045005200'].pack('H*')
147
- expect(message.workstation).to eq(workstation)
148
- end
149
- it 'should set the session key' do
150
- session_key = ['727a5240822ec7af4e9100c43e6fee7f'].pack('H*')
151
- expect(message.session_key).to eq(session_key)
152
- end
153
-
154
- let(:server_challenge) { ['677f1c557a5ee96c'].pack('H*') }
155
- describe '#password?' do
156
- it 'should be true for "test1234"' do
157
- expect(message.password?('test1234', server_challenge)).to be true
158
- end
159
- end
160
- describe '#blank_password?' do
161
- it 'should be false' do
162
- expect(message.blank_password?(server_challenge)).to be false
163
- end
164
- end
165
-
166
- describe '#ntlm_version' do
167
- let(:ver) { message.ntlm_version }
168
- it 'should be :ntlm2_session' do
169
- expect(ver).to eq(:ntlm2_session)
170
- end
171
- end
172
-
173
- end
174
-
175
- # http://davenport.sourceforge.net/ntlm.html#appendixC9
176
- context 'NTLMv2 Authentication; NTLM1 Signing and Sealing Using the 40-bit NTLMv2 User Session Key' do
177
- let(:server_challenge) { ['0033b02d17275b77'].pack('H*') }
178
-
179
- describe '#password?' do
180
- it 'accepts the known fixture password' do
181
- expect(message.password?('test1234', server_challenge)).to be true
182
- end
183
-
184
- it 'rejects an incorrect password' do
185
- expect(message.password?('wrong', server_challenge)).to be false
186
- end
187
-
188
- it 'rejects an empty password' do
189
- expect(message.blank_password?(server_challenge)).to be false
190
- end
191
- end
192
-
193
- let(:data) do
194
- [
195
- '4e544c4d5353500003000000180018006000000076007600780000000c000c00' \
196
- '40000000080008004c0000000c000c005400000000000000ee00000035828000' \
197
- '54004500530054004e00540074006500730074004d0045004d00420045005200' \
198
- '5d55a02b60a40526ac9a1e4d15fa45a0f2e6329726c598e8f77c67dad00b9321' \
199
- '6242b197fe6addfa0101000000000000502db638677bc301f2e6329726c598e8' \
200
- '0000000002000c0054004500530054004e00540001000c004d0045004d004200' \
201
- '4500520003001e006d0065006d006200650072002e0074006500730074002e00' \
202
- '63006f006d000000000000000000'
203
- ].pack 'H*'
204
- end
205
-
206
- it 'should set the NTLM response' do
207
- ntlm_response = [
208
- 'f77c67dad00b93216242b197fe6addfa0101000000000000502db638677bc301' \
209
- 'f2e6329726c598e80000000002000c0054004500530054004e00540001000c00' \
210
- '4d0045004d0042004500520003001e006d0065006d006200650072002e007400' \
211
- '6500730074002e0063006f006d000000000000000000'
212
- ].pack 'H*'
213
- expect(message.ntlm_response).to eq(ntlm_response)
214
- end
215
-
216
- it 'should set the domain' do
217
- # TESTNT
218
- domain = ['54004500530054004e005400'].pack('H*')
219
- expect(message.domain).to eq(domain)
220
- end
221
- it 'should set the user' do
222
- # test
223
- user = ['7400650073007400'].pack('H*')
224
- expect(message.user).to eq(user)
225
- end
226
- it 'should set the workstation' do
227
- # MEMBER
228
- workstation = ['4d0045004d00420045005200'].pack('H*')
229
- expect(message.workstation).to eq(workstation)
230
- end
231
-
232
- describe '#ntlm_version' do
233
- let(:ver) { message.ntlm_version }
234
- it 'should be :ntlmv2' do
235
- expect(ver).to eq(:ntlmv2)
236
- end
237
- end
238
-
239
- end
240
-
241
- end
242
-
243
- describe '#password? with serialized NTLMv2 responses' do
244
- let(:type2) do
245
- Net::NTLM::Message::Type2.new.tap do |message|
246
- message.challenge = 0x0123456789abcdef
247
- end
248
- end
249
- let(:server_challenge) { Net::NTLM.pack_int64le(type2.challenge) }
250
- subject(:message) do
251
- described_class.parse(type2.response(
252
- { :user => 'victim', :domain => 'CORP', :password => password },
253
- { :ntlmv2 => true, :client_challenge => 0x1122334455667788, :timestamp => 0 }
254
- ).serialize)
255
- end
256
-
257
- ['secret', 'odd', "p\u00e4ss\u5bc6\u7801\u{1f512}", ''].each do |password|
258
- context "with password #{password.inspect}" do
259
- let(:password) { password }
260
-
261
- it 'accepts the password used to generate the response' do
262
- expect(message.password?(password, server_challenge)).to be true
263
- end
264
-
265
- it 'rejects a different non-empty password' do
266
- expect(message.password?('incorrect', server_challenge)).to be false
267
- end
268
-
269
- it 'recognizes only an empty password as blank' do
270
- expect(message.blank_password?(server_challenge)).to eq(password.empty?)
271
- end
272
-
273
- it 'rejects a different server challenge' do
274
- expect(message.password?(password, "\x00" * 8)).to be false
275
- end
276
-
277
- it 'accepts an integer server challenge' do
278
- expect(message.password?(password, type2.challenge)).to be true
279
- end
280
-
281
- it 'rejects a modified proof' do
282
- message.ntlm_response.setbyte(0, message.ntlm_response.getbyte(0) ^ 1)
283
- expect(message.password?(password, server_challenge)).to be false
284
- end
285
-
286
- it 'rejects a modified blob' do
287
- message.ntlm_response.setbyte(24, message.ntlm_response.getbyte(24) ^ 1)
288
- expect(message.password?(password, server_challenge)).to be false
289
- end
290
- end
291
- end
292
- end
293
-
294
- describe '#serialize' do
295
- context 'when the username contains non-ASCI characters' do
296
- let(:t3) {
297
- t2 = Net::NTLM::Message::Type2.new
298
- t2.response(
299
- {
300
- :user => 'Hélène',
301
- :password => '123456',
302
- :domain => ''
303
- },
304
- {
305
- :ntlmv2 => true,
306
- :workstation => 'testlab.local'
307
- }
308
- )
309
- }
310
-
311
- it 'serializes without error' do
312
- expect { t3.serialize }.not_to raise_error
313
- end
314
- end
315
-
316
- subject(:message) { described_class.create(opts) }
317
- context 'with the UNICODE flag set' do
318
- let(:opts) { {lm_response: "\x00".b, ntlm_response: '', domain: '', workstation: '', user: '', flag: Net::NTLM::DEFAULT_FLAGS[:TYPE3] | Net::NTLM::FLAGS[:UNICODE] } }
319
-
320
- it 'should pad the domain field to a multiple of 2' do
321
- message.serialize
322
- expect(message[:domain][:offset].value % 2).to eq 0
323
- end
324
-
325
- it 'should pad the user field to a multiple of 2' do
326
- message.serialize
327
- expect(message[:user][:offset].value % 2).to eq 0
328
- end
329
-
330
- it 'should pad the workstation field to a multiple of 2' do
331
- message.serialize
332
- expect(message[:workstation][:offset].value % 2).to eq 0
333
- end
334
- end
335
- end
336
- end
@@ -1,15 +0,0 @@
1
- RSpec.describe Net::NTLM::Message do
2
-
3
- fields = []
4
- flags = [
5
- :UNICODE,
6
- :OEM,
7
- :REQUEST_TARGET,
8
- :NTLM,
9
- :ALWAYS_SIGN,
10
- :NTLM2_KEY
11
- ]
12
- it_behaves_like 'a fieldset', fields
13
- it_behaves_like 'a message', flags
14
-
15
- end
@@ -1,62 +0,0 @@
1
- RSpec.describe Net::NTLM::SecurityBuffer do
2
-
3
- fields = [
4
- { :name => :length, :class => Net::NTLM::Int16LE, :value => 0, :active => true },
5
- { :name => :allocated, :class => Net::NTLM::Int16LE, :value => 0, :active => true },
6
- { :name => :offset, :class => Net::NTLM::Int32LE, :value => 0, :active => true },
7
- ]
8
-
9
- it_behaves_like 'a fieldset', fields
10
- it_behaves_like 'a field', 'WORKSTATION', true
11
-
12
-
13
- subject(:domain_security_buffer) do
14
- Net::NTLM::SecurityBuffer.new({
15
- :value => 'WORKSTATION',
16
- :active => true
17
- })
18
- end
19
-
20
- context 'when setting the value directly' do
21
- before(:each) do
22
- domain_security_buffer.value = 'DOMAIN1'
23
- end
24
- it 'should change the value' do
25
- expect(domain_security_buffer.value).to eq('DOMAIN1')
26
- end
27
-
28
- it 'should adjust the length field to the size of the new value' do
29
- expect(domain_security_buffer.length).to eq(7)
30
- end
31
-
32
- it 'should adjust the allocated field to the size of the new value' do
33
- expect(domain_security_buffer.allocated).to eq(7)
34
- end
35
- end
36
-
37
- context '#data_size' do
38
- it 'should return the size of the value if active' do
39
- expect(domain_security_buffer.data_size).to eq(11)
40
- end
41
-
42
- it 'should return 0 if inactive' do
43
- domain_security_buffer.active = false
44
- expect(domain_security_buffer.data_size).to eq(0)
45
- end
46
- end
47
-
48
- context '#parse' do
49
- it 'should read in a properly formatted string' do
50
- # Length of the string is 8
51
- length = "\x08\x00"
52
- # Space allocated is 8
53
- allocated = "\x08\x00"
54
- # The offset that the actual value begins at is also 8
55
- offset = "\x08\x00\x00\x00"
56
- string_to_parse = "#{length}#{allocated}#{offset}FooBarBaz"
57
- expect(domain_security_buffer.parse(string_to_parse)).to eq(8)
58
- expect(domain_security_buffer.value).to eq('FooBarBa')
59
- end
60
-
61
- end
62
- end
@@ -1,70 +0,0 @@
1
- RSpec.describe Net::NTLM::String do
2
-
3
- it_behaves_like 'a field', 'Foo', false
4
-
5
- let(:active) {
6
- Net::NTLM::String.new({
7
- :value => 'Test',
8
- :active => true,
9
- :size => 4
10
- })
11
- }
12
-
13
- let(:inactive) {
14
- Net::NTLM::String.new({
15
- :value => 'Test',
16
- :active => false,
17
- :size => 4
18
- })
19
- }
20
-
21
- context '#serialize' do
22
- it 'should return the value when active' do
23
- expect(active.serialize).to eq('Test')
24
- end
25
-
26
- it 'should return an empty string when inactive' do
27
- expect(inactive.serialize).to eq('')
28
- end
29
-
30
- it 'should coerce non-string values into strings' do
31
- active.value = 15
32
- expect(active.serialize).to eq('15')
33
- end
34
-
35
- it 'should return empty string on a nil' do
36
- active.value = nil
37
- expect(active.serialize).to eq('')
38
- end
39
- end
40
-
41
- context '#value=' do
42
- it 'should set active to false if it empty' do
43
- active.value = ''
44
- expect(active.active).to eq(false)
45
- end
46
-
47
- it 'should adjust the size based on the value set' do
48
- expect(active.size).to eq(4)
49
- active.value = 'Foobar'
50
- expect(active.size).to eq(6)
51
- end
52
- end
53
-
54
- context '#parse' do
55
- it 'should read in a string of the proper size' do
56
- expect(active.parse('tseT')).to eq(4)
57
- expect(active.value).to eq('tseT')
58
- end
59
-
60
- it 'should not read in a string that is too small' do
61
- expect(active.parse('B')).to eq(0)
62
- expect(active.value).to eq('Test')
63
- end
64
-
65
- it 'should be able to read from an offset and only for the given size' do
66
- expect(active.parse('FooBarBaz',3)).to eq(4)
67
- expect(active.value).to eq('BarB')
68
- end
69
- end
70
- end
@@ -1,74 +0,0 @@
1
- RSpec.describe Net::NTLM::TargetInfo do
2
- let(:key1) { Net::NTLM::TargetInfo::MSV_AV_NB_COMPUTER_NAME }
3
- let(:value1) { 'some data' }
4
- let(:key2) { Net::NTLM::TargetInfo::MSV_AV_NB_DOMAIN_NAME }
5
- let(:value2) { 'some other data' }
6
- let(:data) do
7
- dt = key1.dup
8
- dt << [value1.length].pack('S')
9
- dt << value1
10
- dt << key2.dup
11
- dt << [value2.length].pack('S')
12
- dt << value2
13
- dt << Net::NTLM::TargetInfo::MSV_AV_EOL
14
- dt << [0].pack('S')
15
- dt.force_encoding(Encoding::ASCII_8BIT)
16
- end
17
-
18
- subject { Net::NTLM::TargetInfo.new(data) }
19
-
20
- describe 'invalid data' do
21
-
22
- context 'invalid pair id' do
23
- let(:data) { "\xFF\x00" }
24
-
25
- it 'returns an error' do
26
- expect{subject}.to raise_error Net::NTLM::InvalidTargetDataError
27
- end
28
- end
29
- end
30
-
31
- describe '#av_pairs' do
32
-
33
- it 'returns the pair values with the given keys' do
34
- expect(subject.av_pairs[key1]).to eq value1
35
- expect(subject.av_pairs[key2]).to eq value2
36
- end
37
-
38
- context "target data is nil" do
39
- subject { Net::NTLM::TargetInfo.new(nil) }
40
-
41
- it 'returns the pair values with the given keys' do
42
- expect(subject.av_pairs).to be_empty
43
- end
44
- end
45
- end
46
-
47
- describe '#to_s' do
48
- let(:data) do
49
- dt = key1.dup
50
- dt << [value1.length].pack('S')
51
- dt << value1
52
- dt << key2.dup
53
- dt << [value2.length].pack('S')
54
- dt << value2
55
- dt.force_encoding(Encoding::ASCII_8BIT)
56
- end
57
- let(:new_key) { Net::NTLM::TargetInfo::MSV_AV_CHANNEL_BINDINGS }
58
- let(:new_value) { 'bindings' }
59
- let(:new_data) do
60
- dt = data
61
- dt << new_key
62
- dt << [new_value.length].pack('S')
63
- dt << new_value
64
- dt << Net::NTLM::TargetInfo::MSV_AV_EOL
65
- dt << [0].pack('S')
66
- dt.force_encoding(Encoding::ASCII_8BIT)
67
- end
68
-
69
- it 'returns bytes with any new data added' do
70
- subject.av_pairs[new_key] = new_value
71
- expect(subject.to_s).to eq new_data
72
- end
73
- end
74
- end