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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +3 -0
  3. data/.travis.yml +0 -1
  4. data/LICENSE +20 -0
  5. data/Rakefile +8 -15
  6. data/lib/net/ntlm.rb +22 -654
  7. data/lib/net/ntlm/blob.rb +17 -0
  8. data/lib/net/ntlm/encode_util.rb +49 -0
  9. data/lib/net/ntlm/field.rb +35 -0
  10. data/lib/net/ntlm/field_set.rb +125 -0
  11. data/lib/net/ntlm/int16_le.rb +26 -0
  12. data/lib/net/ntlm/int32_le.rb +25 -0
  13. data/lib/net/ntlm/int64_le.rb +26 -0
  14. data/lib/net/ntlm/message.rb +115 -0
  15. data/lib/net/ntlm/message/type0.rb +16 -0
  16. data/lib/net/ntlm/message/type1.rb +43 -0
  17. data/lib/net/ntlm/message/type2.rb +126 -0
  18. data/lib/net/ntlm/message/type3.rb +68 -0
  19. data/lib/net/ntlm/security_buffer.rb +48 -0
  20. data/lib/net/ntlm/string.rb +35 -0
  21. data/lib/net/ntlm/version.rb +11 -0
  22. data/rubyntlm.gemspec +4 -1
  23. data/spec/lib/net/ntlm/blob_spec.rb +16 -0
  24. data/spec/lib/net/ntlm/encode_util_spec.rb +16 -0
  25. data/spec/lib/net/ntlm/field_set_spec.rb +33 -0
  26. data/spec/lib/net/ntlm/field_spec.rb +34 -0
  27. data/spec/lib/net/ntlm/int16_le_spec.rb +18 -0
  28. data/spec/lib/net/ntlm/int32_le_spec.rb +19 -0
  29. data/spec/lib/net/ntlm/int64_le_spec.rb +19 -0
  30. data/spec/lib/net/ntlm/message/type0_spec.rb +21 -0
  31. data/spec/lib/net/ntlm/message/type1_spec.rb +42 -0
  32. data/spec/lib/net/ntlm/message/type2_spec.rb +88 -0
  33. data/spec/lib/net/ntlm/message/type3_spec.rb +20 -0
  34. data/spec/lib/net/ntlm/message_spec.rb +17 -0
  35. data/spec/lib/net/ntlm/security_buffer_spec.rb +64 -0
  36. data/spec/lib/net/ntlm/string_spec.rb +72 -0
  37. data/spec/lib/net/ntlm/version_spec.rb +26 -0
  38. data/spec/lib/net/ntlm_spec.rb +121 -0
  39. data/spec/spec_helper.rb +21 -0
  40. data/spec/support/shared/examples/net/ntlm/field_shared.rb +25 -0
  41. data/spec/support/shared/examples/net/ntlm/fieldset_shared.rb +239 -0
  42. data/spec/support/shared/examples/net/ntlm/int_shared.rb +43 -0
  43. data/spec/support/shared/examples/net/ntlm/message_shared.rb +35 -0
  44. metadata +77 -5
  45. 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