rubyntlm 0.3.4 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.rspec +3 -0
- data/.travis.yml +0 -1
- data/LICENSE +20 -0
- data/Rakefile +8 -15
- data/lib/net/ntlm.rb +22 -654
- data/lib/net/ntlm/blob.rb +17 -0
- data/lib/net/ntlm/encode_util.rb +49 -0
- data/lib/net/ntlm/field.rb +35 -0
- data/lib/net/ntlm/field_set.rb +125 -0
- data/lib/net/ntlm/int16_le.rb +26 -0
- data/lib/net/ntlm/int32_le.rb +25 -0
- data/lib/net/ntlm/int64_le.rb +26 -0
- data/lib/net/ntlm/message.rb +115 -0
- data/lib/net/ntlm/message/type0.rb +16 -0
- data/lib/net/ntlm/message/type1.rb +43 -0
- data/lib/net/ntlm/message/type2.rb +126 -0
- data/lib/net/ntlm/message/type3.rb +68 -0
- data/lib/net/ntlm/security_buffer.rb +48 -0
- data/lib/net/ntlm/string.rb +35 -0
- data/lib/net/ntlm/version.rb +11 -0
- data/rubyntlm.gemspec +4 -1
- data/spec/lib/net/ntlm/blob_spec.rb +16 -0
- data/spec/lib/net/ntlm/encode_util_spec.rb +16 -0
- data/spec/lib/net/ntlm/field_set_spec.rb +33 -0
- data/spec/lib/net/ntlm/field_spec.rb +34 -0
- data/spec/lib/net/ntlm/int16_le_spec.rb +18 -0
- data/spec/lib/net/ntlm/int32_le_spec.rb +19 -0
- data/spec/lib/net/ntlm/int64_le_spec.rb +19 -0
- data/spec/lib/net/ntlm/message/type0_spec.rb +21 -0
- data/spec/lib/net/ntlm/message/type1_spec.rb +42 -0
- data/spec/lib/net/ntlm/message/type2_spec.rb +88 -0
- data/spec/lib/net/ntlm/message/type3_spec.rb +20 -0
- data/spec/lib/net/ntlm/message_spec.rb +17 -0
- data/spec/lib/net/ntlm/security_buffer_spec.rb +64 -0
- data/spec/lib/net/ntlm/string_spec.rb +72 -0
- data/spec/lib/net/ntlm/version_spec.rb +26 -0
- data/spec/lib/net/ntlm_spec.rb +121 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/shared/examples/net/ntlm/field_shared.rb +25 -0
- data/spec/support/shared/examples/net/ntlm/fieldset_shared.rb +239 -0
- data/spec/support/shared/examples/net/ntlm/int_shared.rb +43 -0
- data/spec/support/shared/examples/net/ntlm/message_shared.rb +35 -0
- metadata +77 -5
- data/spec/unit/ntlm_spec.rb +0 -183
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Net::NTLM::Int64LE do
|
4
|
+
|
5
|
+
int_values = {
|
6
|
+
:default => 5294967295,
|
7
|
+
:default_hex => [5294967295 & 0x00000000ffffffff, 5294967295 >> 32].pack("V2"),
|
8
|
+
:alt => 5294967294,
|
9
|
+
:alt_hex => [5294967294 & 0x00000000ffffffff, 5294967294 >> 32].pack("V2"),
|
10
|
+
:small => "\x5C\x24\x10\x0f",
|
11
|
+
:size => 8,
|
12
|
+
:bits => 64
|
13
|
+
}
|
14
|
+
|
15
|
+
|
16
|
+
it_behaves_like 'a field', 252716124, false
|
17
|
+
it_behaves_like 'an integer field', int_values
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Net::NTLM::Message::Type0 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 => 0, :active => true },
|
8
|
+
]
|
9
|
+
flags = [
|
10
|
+
:UNICODE,
|
11
|
+
:OEM,
|
12
|
+
:REQUEST_TARGET,
|
13
|
+
:NTLM,
|
14
|
+
:ALWAYS_SIGN,
|
15
|
+
:NTLM2_KEY
|
16
|
+
]
|
17
|
+
it_behaves_like 'a fieldset', fields
|
18
|
+
it_behaves_like 'a message', flags
|
19
|
+
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Net::NTLM::Message::Type1 do
|
4
|
+
fields = [
|
5
|
+
{ :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
|
6
|
+
{ :name => :type, :class => Net::NTLM::Int32LE, :value => 1, :active => true },
|
7
|
+
{ :name => :flag, :class => Net::NTLM::Int32LE, :value => Net::NTLM::DEFAULT_FLAGS[:TYPE1], :active => true },
|
8
|
+
{ :name => :domain, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
|
9
|
+
{ :name => :workstation, :class => Net::NTLM::SecurityBuffer, :value => Socket.gethostname, :active => true },
|
10
|
+
{ :name => :padding, :class => Net::NTLM::String, :value => '', :active => false },
|
11
|
+
]
|
12
|
+
flags = [
|
13
|
+
:UNICODE,
|
14
|
+
:OEM,
|
15
|
+
:REQUEST_TARGET,
|
16
|
+
:NTLM,
|
17
|
+
:ALWAYS_SIGN,
|
18
|
+
:NTLM2_KEY
|
19
|
+
]
|
20
|
+
it_behaves_like 'a fieldset', fields
|
21
|
+
it_behaves_like 'a message', flags
|
22
|
+
|
23
|
+
let(:type1_packet) {"TlRMTVNTUAABAAAAB4IIAAAAAAAgAAAAAAAAACAAAAA="}
|
24
|
+
|
25
|
+
it 'should deserialize' do
|
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 == ''
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should serialize' do
|
37
|
+
t1 = Net::NTLM::Message::Type1.new
|
38
|
+
t1.workstation = ''
|
39
|
+
t1.encode64.should == type1_packet
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Net::NTLM::Message::Type2 do
|
5
|
+
|
6
|
+
fields = [
|
7
|
+
{ :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
|
8
|
+
{ :name => :type, :class => Net::NTLM::Int32LE, :value => 2, :active => true },
|
9
|
+
{ :name => :challenge, :class => Net::NTLM::Int64LE, :value => 0, :active => true },
|
10
|
+
{ :name => :context, :class => Net::NTLM::Int64LE, :value => 0, :active => false },
|
11
|
+
{ :name => :flag, :class => Net::NTLM::Int32LE, :value => Net::NTLM::DEFAULT_FLAGS[:TYPE2], :active => true },
|
12
|
+
{ :name => :target_name, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
|
13
|
+
{ :name => :target_info, :class => Net::NTLM::SecurityBuffer, :value => '', :active => false },
|
14
|
+
{ :name => :padding, :class => Net::NTLM::String, :value => '', :active => false },
|
15
|
+
]
|
16
|
+
flags = [
|
17
|
+
:UNICODE
|
18
|
+
]
|
19
|
+
it_behaves_like 'a fieldset', fields
|
20
|
+
it_behaves_like 'a message', flags
|
21
|
+
|
22
|
+
let(:type2_packet) {"TlRMTVNTUAACAAAAHAAcADgAAAAFgooCJ+UA1//+ZM4AAAAAAAAAAJAAkABUAAAABgGxHQAAAA9WAEEARwBSAEEATgBUAC0AMgAwADAAOABSADIAAgAcAFYAQQBHAFIAQQBOAFQALQAyADAAMAA4AFIAMgABABwAVgBBAEcAUgBBAE4AVAAtADIAMAAwADgAUgAyAAQAHAB2AGEAZwByAGEAbgB0AC0AMgAwADAAOABSADIAAwAcAHYAYQBnAHIAYQBuAHQALQAyADAAMAA4AFIAMgAHAAgAZBMdFHQnzgEAAAAA"}
|
23
|
+
let(:type3_packet) {"TlRMTVNTUAADAAAAGAAYAEQAAADAAMAAXAAAAAAAAAAcAQAADgAOABwBAAAUABQAKgEAAAAAAAA+AQAABYKKAgAAAADVS27TfQGmWxSSbXmolTUQyxJmD8ISQuBKKHFKC8GksUZISYc8Ps9RAQEAAAAAAAAANasTdCfOAcsSZg/CEkLgAAAAAAIAHABWAEEARwBSAEEATgBUAC0AMgAwADAAOABSADIAAQAcAFYAQQBHAFIAQQBOAFQALQAyADAAMAA4AFIAMgAEABwAdgBhAGcAcgBhAG4AdAAtADIAMAAwADgAUgAyAAMAHAB2AGEAZwByAGEAbgB0AC0AMgAwADAAOABSADIABwAIAGQTHRR0J84BAAAAAAAAAAB2AGEAZwByAGEAbgB0AGsAbwBiAGUALgBsAG8AYwBhAGwA"}
|
24
|
+
|
25
|
+
it 'should deserialize' do
|
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"
|
35
|
+
|
36
|
+
t2_target_info = Net::NTLM::EncodeUtil.decode_utf16le(t2.target_info)
|
37
|
+
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"
|
39
|
+
else
|
40
|
+
t2_target_info.should == "\u0002\u001CVAGRANT-2008R2\u0001\u001CVAGRANT-2008R2\u0004\u001Cvagrant-2008R2\u0003\u001Cvagrant-2008R2\a\b፤ᐝ❴ǎ\0\0"
|
41
|
+
end
|
42
|
+
|
43
|
+
Net::NTLM::EncodeUtil.decode_utf16le(t2.target_name).should == "VAGRANT-2008R2"
|
44
|
+
t2.type.should == 2
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should serialize' do
|
48
|
+
source = Net::NTLM::Message.decode64(type2_packet)
|
49
|
+
|
50
|
+
t2 = Net::NTLM::Message::Type2.new
|
51
|
+
t2.challenge = source.challenge
|
52
|
+
t2.context = source.context
|
53
|
+
t2.flag = source.flag
|
54
|
+
t2.padding = source.padding
|
55
|
+
t2.sign = source.sign
|
56
|
+
t2.target_info = source.target_info
|
57
|
+
t2.target_name = source.target_name
|
58
|
+
t2.type = source.type
|
59
|
+
t2.enable(:context)
|
60
|
+
t2.enable(:target_info)
|
61
|
+
t2.enable(:padding)
|
62
|
+
|
63
|
+
t2.encode64.should == type2_packet
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should generate a type 3 response' do
|
67
|
+
t2 = Net::NTLM::Message.decode64(type2_packet)
|
68
|
+
|
69
|
+
type3_known = Net::NTLM::Message.decode64(type3_packet)
|
70
|
+
type3_known.flag = 0x028a8205
|
71
|
+
type3_known.enable(:session_key)
|
72
|
+
type3_known.enable(:flag)
|
73
|
+
|
74
|
+
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 == ''
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should upcase domain when provided' do
|
84
|
+
t2 = Net::NTLM::Message.decode64(type2_packet)
|
85
|
+
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"
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Net::NTLM::Message::Type3 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 => 3, :active => true },
|
8
|
+
{ :name => :flag, :class => Net::NTLM::Int64LE, :value => 0, :active => false },
|
9
|
+
{ :name => :lm_response, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
|
10
|
+
{ :name => :ntlm_response, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
|
11
|
+
{ :name => :domain, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
|
12
|
+
{ :name => :user, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
|
13
|
+
{ :name => :workstation, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
|
14
|
+
{ :name => :session_key, :class => Net::NTLM::SecurityBuffer, :value => '', :active => false },
|
15
|
+
]
|
16
|
+
flags = []
|
17
|
+
it_behaves_like 'a fieldset', fields
|
18
|
+
it_behaves_like 'a message', flags
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Net::NTLM::Message do
|
4
|
+
|
5
|
+
fields = []
|
6
|
+
flags = [
|
7
|
+
:UNICODE,
|
8
|
+
:OEM,
|
9
|
+
:REQUEST_TARGET,
|
10
|
+
:NTLM,
|
11
|
+
:ALWAYS_SIGN,
|
12
|
+
:NTLM2_KEY
|
13
|
+
]
|
14
|
+
it_behaves_like 'a fieldset', fields
|
15
|
+
it_behaves_like 'a message', flags
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Net::NTLM::SecurityBuffer do
|
4
|
+
|
5
|
+
fields = [
|
6
|
+
{ :name => :length, :class => Net::NTLM::Int16LE, :value => 0, :active => true },
|
7
|
+
{ :name => :allocated, :class => Net::NTLM::Int16LE, :value => 0, :active => true },
|
8
|
+
{ :name => :offset, :class => Net::NTLM::Int32LE, :value => 0, :active => true },
|
9
|
+
]
|
10
|
+
|
11
|
+
it_behaves_like 'a fieldset', fields
|
12
|
+
it_behaves_like 'a field', 'WORKSTATION', true
|
13
|
+
|
14
|
+
|
15
|
+
subject(:domain_security_buffer) do
|
16
|
+
Net::NTLM::SecurityBuffer.new({
|
17
|
+
:value => 'WORKSTATION',
|
18
|
+
:active => true
|
19
|
+
})
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when setting the value directly' do
|
23
|
+
before(:each) do
|
24
|
+
domain_security_buffer.value = 'DOMAIN1'
|
25
|
+
end
|
26
|
+
it 'should change the value' do
|
27
|
+
domain_security_buffer.value.should == 'DOMAIN1'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should adjust the length field to the size of the new value' do
|
31
|
+
domain_security_buffer.length.should == 7
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should adjust the allocated field to the size of the new value' do
|
35
|
+
domain_security_buffer.allocated.should == 7
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context '#data_size' do
|
40
|
+
it 'should return the size of the value if active' do
|
41
|
+
domain_security_buffer.data_size.should == 11
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should return 0 if inactive' do
|
45
|
+
domain_security_buffer.active = false
|
46
|
+
domain_security_buffer.data_size.should == 0
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context '#parse' do
|
51
|
+
it 'should read in a properly formatted string' do
|
52
|
+
# Length of the string is 8
|
53
|
+
length = "\x08\x00"
|
54
|
+
# Space allocated is 8
|
55
|
+
allocated = "\x08\x00"
|
56
|
+
# The offset that the actual value begins at is also 8
|
57
|
+
offset = "\x08\x00\x00\x00"
|
58
|
+
string_to_parse = "#{length}#{allocated}#{offset}FooBarBaz"
|
59
|
+
domain_security_buffer.parse(string_to_parse).should == 8
|
60
|
+
domain_security_buffer.value.should == 'FooBarBa'
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Net::NTLM::String do
|
4
|
+
|
5
|
+
it_behaves_like 'a field', 'Foo', false
|
6
|
+
|
7
|
+
let(:active) {
|
8
|
+
Net::NTLM::String.new({
|
9
|
+
:value => 'Test',
|
10
|
+
:active => true,
|
11
|
+
:size => 4
|
12
|
+
})
|
13
|
+
}
|
14
|
+
|
15
|
+
let(:inactive) {
|
16
|
+
Net::NTLM::String.new({
|
17
|
+
:value => 'Test',
|
18
|
+
:active => false,
|
19
|
+
:size => 4
|
20
|
+
})
|
21
|
+
}
|
22
|
+
|
23
|
+
context '#serialize' do
|
24
|
+
it 'should return the value when active' do
|
25
|
+
active.serialize.should == 'Test'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should return an empty string when inactive' do
|
29
|
+
inactive.serialize.should == ''
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should coerce non-string values into strings' do
|
33
|
+
active.value = 15
|
34
|
+
active.serialize.should == '15'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should return empty string on a nil' do
|
38
|
+
active.value = nil
|
39
|
+
active.serialize.should == ''
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context '#value=' do
|
44
|
+
it 'should set active to false if it empty' do
|
45
|
+
active.value = ''
|
46
|
+
active.active.should == false
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should adjust the size based on the value set' do
|
50
|
+
active.size.should == 4
|
51
|
+
active.value = 'Foobar'
|
52
|
+
active.size.should == 6
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context '#parse' do
|
57
|
+
it 'should read in a string of the proper size' do
|
58
|
+
active.parse('tseT').should == 4
|
59
|
+
active.value.should == 'tseT'
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should not read in a string that is too small' do
|
63
|
+
active.parse('B').should == 0
|
64
|
+
active.value.should == 'Test'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should be able to read from an offset and only for the given size' do
|
68
|
+
active.parse('FooBarBaz',3).should == 4
|
69
|
+
active.value.should == 'BarB'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Net::NTLM::VERSION do
|
4
|
+
|
5
|
+
it 'should contain an integer value for Major Version' do
|
6
|
+
Net::NTLM::VERSION::MAJOR.should be_an Integer
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should contain an integer value for Minor Version' do
|
10
|
+
Net::NTLM::VERSION::MINOR.should be_an Integer
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should contain an integer value for Patch Version' do
|
14
|
+
Net::NTLM::VERSION::TINY.should be_an Integer
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should contain an aggregate version string' do
|
18
|
+
string = [
|
19
|
+
Net::NTLM::VERSION::MAJOR,
|
20
|
+
Net::NTLM::VERSION::MINOR,
|
21
|
+
Net::NTLM::VERSION::TINY
|
22
|
+
].join('.')
|
23
|
+
Net::NTLM::VERSION::STRING.should be_a String
|
24
|
+
Net::NTLM::VERSION::STRING.should == string
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
|
2
|
+
require 'rspec'
|
3
|
+
require 'net/ntlm'
|
4
|
+
|
5
|
+
describe Net::NTLM do
|
6
|
+
let(:passwd) {"SecREt01"}
|
7
|
+
let(:user) {"user"}
|
8
|
+
let(:domain) {"domain"}
|
9
|
+
let(:challenge) {["0123456789abcdef"].pack("H*")}
|
10
|
+
let(:client_ch) {["ffffff0011223344"].pack("H*")}
|
11
|
+
let(:timestamp) {1055844000}
|
12
|
+
let(:trgt_info) {[
|
13
|
+
"02000c0044004f004d00410049004e00" +
|
14
|
+
"01000c00530045005200560045005200" +
|
15
|
+
"0400140064006f006d00610069006e00" +
|
16
|
+
"2e0063006f006d000300220073006500" +
|
17
|
+
"72007600650072002e0064006f006d00" +
|
18
|
+
"610069006e002e0063006f006d000000" +
|
19
|
+
"0000"
|
20
|
+
].pack("H*")}
|
21
|
+
let(:padded_pwd) { passwd.upcase.ljust(14, "\0")}
|
22
|
+
let(:keys) { Net::NTLM.gen_keys(padded_pwd)}
|
23
|
+
|
24
|
+
it 'should convert a value to 64-bit LE Integer' do
|
25
|
+
Net::NTLM.pack_int64le(42).should == "\x2A\x00\x00\x00\x00\x00\x00\x00"
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should split a string into an array of slices, 7 chars or less' do
|
29
|
+
Net::NTLM.split7("HelloWorld!").should == [ 'HelloWo', 'rld!']
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should generate DES keys from the supplied string' do
|
33
|
+
first_key = ["52a2516b252a5161"].pack('H*')
|
34
|
+
second_key = ["3180010101010101"].pack('H*')
|
35
|
+
Net::NTLM.gen_keys(padded_pwd).should == [first_key, second_key]
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should encrypt the string with DES for each key supplied' do
|
39
|
+
first_crypt = ["ff3750bcc2b22412"].pack('H*')
|
40
|
+
second_crypt = ["c2265b23734e0dac"].pack('H*')
|
41
|
+
Net::NTLM::apply_des(Net::NTLM::LM_MAGIC, keys).should == [first_crypt, second_crypt]
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should generate an lm_hash' do
|
45
|
+
Net::NTLM::lm_hash(passwd).should == ["ff3750bcc2b22412c2265b23734e0dac"].pack("H*")
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should generate an ntlm_hash' do
|
49
|
+
Net::NTLM::ntlm_hash(passwd).should == ["cd06ca7c7e10c99b1d33b7485a2ed808"].pack("H*")
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should generate an ntlmv2_hash' do
|
53
|
+
Net::NTLM::ntlmv2_hash(user, passwd, domain).should == ["04b8e0ba74289cc540826bab1dee63ae"].pack("H*")
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should generate an lm_response' do
|
57
|
+
Net::NTLM::lm_response(
|
58
|
+
{
|
59
|
+
:lm_hash => Net::NTLM::lm_hash(passwd),
|
60
|
+
:challenge => challenge
|
61
|
+
}
|
62
|
+
).should == ["c337cd5cbd44fc9782a667af6d427c6de67c20c2d3e77c56"].pack("H*")
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should generate an ntlm_response' do
|
66
|
+
ntlm_hash = Net::NTLM::ntlm_hash(passwd)
|
67
|
+
Net::NTLM::ntlm_response(
|
68
|
+
{
|
69
|
+
:ntlm_hash => ntlm_hash,
|
70
|
+
:challenge => challenge
|
71
|
+
}
|
72
|
+
).should == ["25a98c1c31e81847466b29b2df4680f39958fb8c213a9cc6"].pack("H*")
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should generate a lvm2_response' do
|
76
|
+
Net::NTLM::lmv2_response(
|
77
|
+
{
|
78
|
+
:ntlmv2_hash => Net::NTLM::ntlmv2_hash(user, passwd, domain),
|
79
|
+
:challenge => challenge
|
80
|
+
},
|
81
|
+
{ :client_challenge => client_ch }
|
82
|
+
).should == ["d6e6152ea25d03b7c6ba6629c2d6aaf0ffffff0011223344"].pack("H*")
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should generate a ntlmv2_response' do
|
86
|
+
Net::NTLM::ntlmv2_response(
|
87
|
+
{
|
88
|
+
:ntlmv2_hash => Net::NTLM::ntlmv2_hash(user, passwd, domain),
|
89
|
+
:challenge => challenge,
|
90
|
+
:target_info => trgt_info
|
91
|
+
},
|
92
|
+
{
|
93
|
+
:timestamp => timestamp,
|
94
|
+
:client_challenge => client_ch
|
95
|
+
}
|
96
|
+
).should == [
|
97
|
+
"cbabbca713eb795d04c97abc01ee4983" +
|
98
|
+
"01010000000000000090d336b734c301" +
|
99
|
+
"ffffff00112233440000000002000c00" +
|
100
|
+
"44004f004d00410049004e0001000c00" +
|
101
|
+
"53004500520056004500520004001400" +
|
102
|
+
"64006f006d00610069006e002e006300" +
|
103
|
+
"6f006d00030022007300650072007600" +
|
104
|
+
"650072002e0064006f006d0061006900" +
|
105
|
+
"6e002e0063006f006d00000000000000" +
|
106
|
+
"0000"
|
107
|
+
].pack("H*")
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should generate a ntlm2_session' do
|
111
|
+
session = Net::NTLM::ntlm2_session(
|
112
|
+
{
|
113
|
+
:ntlm_hash => Net::NTLM::ntlm_hash(passwd),
|
114
|
+
:challenge => challenge
|
115
|
+
},
|
116
|
+
{ :client_challenge => client_ch }
|
117
|
+
)
|
118
|
+
session[0].should == ["ffffff001122334400000000000000000000000000000000"].pack("H*")
|
119
|
+
session[1].should == ["10d550832d12b2ccb79d5ad1f4eed3df82aca4c3681dd455"].pack("H*")
|
120
|
+
end
|
121
|
+
end
|