rubyntlm 0.6.1 → 0.6.2

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 +4 -3
  3. data/.rspec +2 -2
  4. data/.travis.yml +13 -12
  5. data/CHANGELOG.md +118 -6
  6. data/Gemfile +3 -3
  7. data/LICENSE +19 -19
  8. data/Rakefile +25 -22
  9. data/lib/net/ntlm.rb +266 -266
  10. data/lib/net/ntlm/blob.rb +28 -28
  11. data/lib/net/ntlm/channel_binding.rb +65 -65
  12. data/lib/net/ntlm/client.rb +65 -65
  13. data/lib/net/ntlm/client/session.rb +237 -237
  14. data/lib/net/ntlm/encode_util.rb +48 -48
  15. data/lib/net/ntlm/exceptions.rb +14 -14
  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 -89
  29. data/lib/net/ntlm/version.rb +11 -11
  30. data/rubyntlm.gemspec +29 -28
  31. data/spec/lib/net/ntlm/blob_spec.rb +16 -16
  32. data/spec/lib/net/ntlm/channel_binding_spec.rb +17 -17
  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 -76
  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 -19
  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 +17 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f4f6956cb7312016f0dd160d795fc7835e9d9dd9
4
- data.tar.gz: e81b31dd74c218f3765619086f03846dab005f0f
3
+ metadata.gz: 1faff36beeb295ca5d6326a6140686242c3c2447
4
+ data.tar.gz: 23a28cbdddae6dc194754d2a069c6b0cdfbeee05
5
5
  SHA512:
6
- metadata.gz: ae8d487fdeef742a2bc53a821fc491e26a5c34a5d7a1ae8b24d03c42dd0c842c7ec1591cf7a46028747d7411b3cf4b20ad5d396d812a7da0c601b1559d8aa625
7
- data.tar.gz: b33ee3d2081189aae2b2567aef95f89e2e2bacbc03966b51da178d014b78bbc29b0c37a3488f1b86b2aeb23488b08dac71e1ea0142d324c5a09d8bca2f3a9067
6
+ metadata.gz: 33144b0784c9d24f9be05709cef524ed451a45c7c9a54afcafe26aa1a8a9a7bdbfffe6d4252508bc8c924c96c2812c84d2f833204f7ee1a50de234c38b36bb10
7
+ data.tar.gz: 661166a477bf794791376cd7f52aa881f78c0ce6f8bef732ba85f09a703df055a6869305f13e432803e9f5736c3a44d67588240b5f606d7797e4a73d925bee6a
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
- .yardoc
2
- /doc
3
- Gemfile.lock
1
+ .yardoc
2
+ /doc
3
+ Gemfile.lock
4
+ pkg
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
- --format documentation
2
- --color
1
+ --format documentation
2
+ --color
@@ -1,12 +1,13 @@
1
- language: ruby
2
- rvm:
3
- - 2.1.9
4
- - 2.2.0
5
- - 2.3.1
6
- before_install:
7
- - gem update bundler
8
-
9
- # This prevents testing branches that are created just for PRs
10
- branches:
11
- only:
12
- - master
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.9
4
+ - 2.2.0
5
+ - 2.3.1
6
+ - 2.4.0
7
+ before_install:
8
+ - gem update bundler
9
+
10
+ # This prevents testing branches that are created just for PRs
11
+ branches:
12
+ only:
13
+ - master
@@ -1,6 +1,118 @@
1
- 0.2.0 - Major changes to behavior!!!!
2
- - Bug - Type 1 packets do not include a domain and workstation by defauly. Packet capture software will see this type of packet as malformed. All packets now include this information
3
- - Bug - Type 3 packets do not include the calling workstation. This should be setup by default.
4
-
5
- 0.1.2
6
- - Feature user can specify the target domain
1
+ # Change Log
2
+
3
+ ## [0.6.2](https://github.com/WinRb/rubyntlm/tree/0.6.2) (2017-04-06)
4
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/v0.6.1...0.6.2)
5
+
6
+ **Merged pull requests:**
7
+
8
+ - Support Ruby 2.4 [\#34](https://github.com/WinRb/rubyntlm/pull/34) ([fwininger](https://github.com/fwininger))
9
+ - ignore pkg directory in git [\#33](https://github.com/WinRb/rubyntlm/pull/33) ([mwrock](https://github.com/mwrock))
10
+
11
+ ## [v0.6.1](https://github.com/WinRb/rubyntlm/tree/v0.6.1) (2016-09-15)
12
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/v0.6.0...v0.6.1)
13
+
14
+ **Merged pull requests:**
15
+
16
+ - Release 0.6.1 [\#32](https://github.com/WinRb/rubyntlm/pull/32) ([mwrock](https://github.com/mwrock))
17
+ - only test supported rubies and do not test twice [\#31](https://github.com/WinRb/rubyntlm/pull/31) ([mwrock](https://github.com/mwrock))
18
+ - Protect against mutating frozen strings [\#30](https://github.com/WinRb/rubyntlm/pull/30) ([mwrock](https://github.com/mwrock))
19
+
20
+ ## [v0.6.0](https://github.com/WinRb/rubyntlm/tree/v0.6.0) (2016-02-16)
21
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/0.5.3...v0.6.0)
22
+
23
+ **Closed issues:**
24
+
25
+ - support Extended Protection for Authentication \(Channel Binding Tokens\) [\#27](https://github.com/WinRb/rubyntlm/issues/27)
26
+ - RubyNTLM is not documented [\#20](https://github.com/WinRb/rubyntlm/issues/20)
27
+
28
+ **Merged pull requests:**
29
+
30
+ - Support Extended Protection for Authentication \(Channel binding\) [\#28](https://github.com/WinRb/rubyntlm/pull/28) ([mwrock](https://github.com/mwrock))
31
+
32
+ ## [0.5.3](https://github.com/WinRb/rubyntlm/tree/0.5.3) (2016-01-22)
33
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/v0.5.3...0.5.3)
34
+
35
+ ## [v0.5.3](https://github.com/WinRb/rubyntlm/tree/v0.5.3) (2016-01-22)
36
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/0.5.2...v0.5.3)
37
+
38
+ **Merged pull requests:**
39
+
40
+ - fix session.workstation when passing only domain [\#26](https://github.com/WinRb/rubyntlm/pull/26) ([mwrock](https://github.com/mwrock))
41
+
42
+ ## [0.5.2](https://github.com/WinRb/rubyntlm/tree/0.5.2) (2015-07-20)
43
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/0.5.1...0.5.2)
44
+
45
+ **Merged pull requests:**
46
+
47
+ - Add Pass the Hash capability to the NTLM client [\#24](https://github.com/WinRb/rubyntlm/pull/24) ([dmaloney-r7](https://github.com/dmaloney-r7))
48
+
49
+ ## [0.5.1](https://github.com/WinRb/rubyntlm/tree/0.5.1) (2015-06-23)
50
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/0.5.0...0.5.1)
51
+
52
+ **Merged pull requests:**
53
+
54
+ - fix NTLM1 auth - NTLM::lm\_response\(pwd, chal\) and NTLM::ntlm\_response… [\#23](https://github.com/WinRb/rubyntlm/pull/23) ([marek-veber](https://github.com/marek-veber))
55
+ - Make the session key available to clients [\#21](https://github.com/WinRb/rubyntlm/pull/21) ([jlee-r7](https://github.com/jlee-r7))
56
+
57
+ ## [0.5.0](https://github.com/WinRb/rubyntlm/tree/0.5.0) (2015-02-22)
58
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/v0.4.0...0.5.0)
59
+
60
+ **Closed issues:**
61
+
62
+ - require 'net/ntlm/version' in spec/lib/net/ntlm/version\_spec.rb [\#12](https://github.com/WinRb/rubyntlm/issues/12)
63
+ - License missing from gemspec [\#5](https://github.com/WinRb/rubyntlm/issues/5)
64
+
65
+ **Merged pull requests:**
66
+
67
+ - Encode client and domain in oem/unicode in `Client\#authenticate!` [\#19](https://github.com/WinRb/rubyntlm/pull/19) ([jlee-r7](https://github.com/jlee-r7))
68
+ - require version to fix specs [\#17](https://github.com/WinRb/rubyntlm/pull/17) ([sneal](https://github.com/sneal))
69
+ - Initial go at an NTLM Client that will do session signing/sealing [\#16](https://github.com/WinRb/rubyntlm/pull/16) ([zenchild](https://github.com/zenchild))
70
+ - Verify passwords in Type3 messages [\#15](https://github.com/WinRb/rubyntlm/pull/15) ([jlee-r7](https://github.com/jlee-r7))
71
+ - RSpect should =\> expect modernization [\#14](https://github.com/WinRb/rubyntlm/pull/14) ([zenchild](https://github.com/zenchild))
72
+ - update http example with EncodeUtil class [\#11](https://github.com/WinRb/rubyntlm/pull/11) ([stensonb](https://github.com/stensonb))
73
+ - update readme with how to use and the correct namespacing for using the gem [\#10](https://github.com/WinRb/rubyntlm/pull/10) ([stensonb](https://github.com/stensonb))
74
+
75
+ ## [v0.4.0](https://github.com/WinRb/rubyntlm/tree/v0.4.0) (2013-09-12)
76
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/v0.3.4...v0.4.0)
77
+
78
+ **Closed issues:**
79
+
80
+ - The domain should always be capitalized otherwise domain authentication fails [\#7](https://github.com/WinRb/rubyntlm/issues/7)
81
+
82
+ **Merged pull requests:**
83
+
84
+ - Add licensing information and clean up attributions to provide licensing... [\#9](https://github.com/WinRb/rubyntlm/pull/9) ([pmorton](https://github.com/pmorton))
85
+ - Upcase the domain [\#8](https://github.com/WinRb/rubyntlm/pull/8) ([pmorton](https://github.com/pmorton))
86
+ - Refactor/refactor classes [\#6](https://github.com/WinRb/rubyntlm/pull/6) ([dmaloney-r7](https://github.com/dmaloney-r7))
87
+
88
+ ## [v0.3.4](https://github.com/WinRb/rubyntlm/tree/v0.3.4) (2013-08-08)
89
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/v0.3.3...v0.3.4)
90
+
91
+ ## [v0.3.3](https://github.com/WinRb/rubyntlm/tree/v0.3.3) (2013-07-23)
92
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/v0.3.2...v0.3.3)
93
+
94
+ **Merged pull requests:**
95
+
96
+ - Typo in NTLM namespace calls [\#4](https://github.com/WinRb/rubyntlm/pull/4) ([dmaloney-r7](https://github.com/dmaloney-r7))
97
+
98
+ ## [v0.3.2](https://github.com/WinRb/rubyntlm/tree/v0.3.2) (2013-06-24)
99
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/v0.3.1...v0.3.2)
100
+
101
+ **Closed issues:**
102
+
103
+ - Gem is locked at 1.9.2 [\#1](https://github.com/WinRb/rubyntlm/issues/1)
104
+
105
+ ## [v0.3.1](https://github.com/WinRb/rubyntlm/tree/v0.3.1) (2013-03-29)
106
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/v0.3.0...v0.3.1)
107
+
108
+ **Merged pull requests:**
109
+
110
+ - Fix gemspec for the proper ruby version and bump the version [\#2](https://github.com/WinRb/rubyntlm/pull/2) ([pmorton](https://github.com/pmorton))
111
+
112
+ ## [v0.3.0](https://github.com/WinRb/rubyntlm/tree/v0.3.0) (2013-03-25)
113
+ [Full Changelog](https://github.com/WinRb/rubyntlm/compare/v0.2.0...v0.3.0)
114
+
115
+ ## [v0.2.0](https://github.com/WinRb/rubyntlm/tree/v0.2.0) (2013-03-22)
116
+
117
+
118
+ \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE CHANGED
@@ -1,20 +1,20 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2013 Paul Morton, Matt Zukowski, Kohei Kajimoto
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy of
6
- this software and associated documentation files (the "Software"), to deal in
7
- the Software without restriction, including without limitation the rights to
8
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
- the Software, and to permit persons to whom the Software is furnished to do so,
10
- subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Paul Morton, Matt Zukowski, Kohei Kajimoto
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
20
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,22 +1,25 @@
1
- require "bundler/gem_tasks"
2
-
3
-
4
- require 'rspec/core/rake_task'
5
- RSpec::Core::RakeTask.new(:spec)
6
-
7
- task :default => :spec
8
-
9
- desc "Generate code coverage"
10
- task :coverage do
11
- ENV['COVERAGE'] = 'true'
12
- Rake::Task["spec"].execute
13
- end
14
-
15
- desc "Open a Pry console for this library"
16
- task :console do
17
- require 'pry'
18
- require 'net/ntlm'
19
- ARGV.clear
20
- Pry.start
21
- end
22
-
1
+ require "bundler/gem_tasks"
2
+ require 'github_changelog_generator/task'
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
8
+
9
+ desc "Generate code coverage"
10
+ task :coverage do
11
+ ENV['COVERAGE'] = 'true'
12
+ Rake::Task["spec"].execute
13
+ end
14
+
15
+ desc "Open a Pry console for this library"
16
+ task :console do
17
+ require 'pry'
18
+ require 'net/ntlm'
19
+ ARGV.clear
20
+ Pry.start
21
+ end
22
+
23
+ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
24
+ config.future_release = Net::NTLM::VERSION::STRING
25
+ end
@@ -1,266 +1,266 @@
1
- # encoding: UTF-8
2
- #
3
- # = net/ntlm.rb
4
- #
5
- # An NTLM Authentication Library for Ruby
6
- #
7
- # This code is a derivative of "dbf2.rb" written by yrock
8
- # and Minero Aoki. You can find original code here:
9
- # http://jp.rubyist.net/magazine/?0013-CodeReview
10
- # -------------------------------------------------------------
11
- # Copyright (c) 2005,2006 yrock
12
- #
13
- #
14
- # 2006-02-11 refactored by Minero Aoki
15
- # -------------------------------------------------------------
16
- #
17
- # All protocol information used to write this code stems from
18
- # "The NTLM Authentication Protocol" by Eric Glass. The author
19
- # would thank to him for this tremendous work and making it
20
- # available on the net.
21
- # http://davenport.sourceforge.net/ntlm.html
22
- # -------------------------------------------------------------
23
- # Copyright (c) 2003 Eric Glass
24
- #
25
- # -------------------------------------------------------------
26
- #
27
- # The author also looked Mozilla-Firefox-1.0.7 source code,
28
- # namely, security/manager/ssl/src/nsNTLMAuthModule.cpp and
29
- # Jonathan Bastien-Filiatrault's libntlm-ruby.
30
- # "http://x2a.org/websvn/filedetails.php?
31
- # repname=libntlm-ruby&path=%2Ftrunk%2Fntlm.rb&sc=1"
32
- # The latter has a minor bug in its separate_keys function.
33
- # The third key has to begin from the 14th character of the
34
- # input string instead of 13th:)
35
- #--
36
- # $Id: ntlm.rb,v 1.1 2006/10/05 01:36:52 koheik Exp $
37
- #++
38
-
39
- require 'base64'
40
- require 'openssl'
41
- require 'openssl/digest'
42
- require 'socket'
43
-
44
- # Load Order is important here
45
- require 'net/ntlm/exceptions'
46
- require 'net/ntlm/field'
47
- require 'net/ntlm/int16_le'
48
- require 'net/ntlm/int32_le'
49
- require 'net/ntlm/int64_le'
50
- require 'net/ntlm/string'
51
-
52
- require 'net/ntlm/field_set'
53
- require 'net/ntlm/blob'
54
- require 'net/ntlm/security_buffer'
55
- require 'net/ntlm/message'
56
- require 'net/ntlm/message/type0'
57
- require 'net/ntlm/message/type1'
58
- require 'net/ntlm/message/type2'
59
- require 'net/ntlm/message/type3'
60
-
61
- require 'net/ntlm/encode_util'
62
-
63
- require 'net/ntlm/client'
64
- require 'net/ntlm/channel_binding'
65
- require 'net/ntlm/target_info'
66
-
67
- module Net
68
- module NTLM
69
-
70
- LM_MAGIC = "KGS!@\#$%"
71
- TIME_OFFSET = 11644473600
72
- MAX64 = 0xffffffffffffffff
73
-
74
-
75
- class << self
76
-
77
- # Valid format for LAN Manager hex digest portion: 32 hexadecimal characters.
78
- LAN_MANAGER_HEX_DIGEST_REGEXP = /[0-9a-f]{32}/i
79
- # Valid format for NT LAN Manager hex digest portion: 32 hexadecimal characters.
80
- NT_LAN_MANAGER_HEX_DIGEST_REGEXP = /[0-9a-f]{32}/i
81
- # Valid format for an NTLM hash composed of `'<LAN Manager hex digest>:<NT LAN Manager hex digest>'`.
82
- DATA_REGEXP = /\A#{LAN_MANAGER_HEX_DIGEST_REGEXP}:#{NT_LAN_MANAGER_HEX_DIGEST_REGEXP}\z/
83
-
84
- # Takes a string and determines whether it is a valid NTLM Hash
85
- # @param [String] the string to validate
86
- # @return [Boolean] whether or not the string is a valid NTLM hash
87
- def is_ntlm_hash?(data)
88
- decoded_data = data.dup
89
- decoded_data = EncodeUtil.decode_utf16le(decoded_data)
90
- if DATA_REGEXP.match(decoded_data)
91
- true
92
- else
93
- false
94
- end
95
- end
96
-
97
- # Conver the value to a 64-Bit Little Endian Int
98
- # @param [String] val The string to convert
99
- def pack_int64le(val)
100
- [val & 0x00000000ffffffff, val >> 32].pack("V2")
101
- end
102
-
103
- # Builds an array of strings that are 7 characters long
104
- # @param [String] str The string to split
105
- # @api private
106
- def split7(str)
107
- s = str.dup
108
- until s.empty?
109
- (ret ||= []).push s.slice!(0, 7)
110
- end
111
- ret
112
- end
113
-
114
- # Not sure what this is doing
115
- # @param [String] str String to generate keys for
116
- # @api private
117
- def gen_keys(str)
118
- split7(str).map{ |str7|
119
- bits = split7(str7.unpack("B*")[0]).inject('')\
120
- {|ret, tkn| ret += tkn + (tkn.gsub('1', '').size % 2).to_s }
121
- [bits].pack("B*")
122
- }
123
- end
124
-
125
- def apply_des(plain, keys)
126
- dec = OpenSSL::Cipher::Cipher.new("des-cbc")
127
- dec.padding = 0
128
- keys.map {|k|
129
- dec.key = k
130
- dec.encrypt.update(plain) + dec.final
131
- }
132
- end
133
-
134
- # Generates a Lan Manager Hash
135
- # @param [String] password The password to base the hash on
136
- def lm_hash(password)
137
- keys = gen_keys password.upcase.ljust(14, "\0")
138
- apply_des(LM_MAGIC, keys).join
139
- end
140
-
141
- # Generate a NTLM Hash
142
- # @param [String] password The password to base the hash on
143
- # @option opt :unicode (false) Unicode encode the password
144
- def ntlm_hash(password, opt = {})
145
- pwd = password.dup
146
- unless opt[:unicode]
147
- pwd = EncodeUtil.encode_utf16le(pwd)
148
- end
149
- OpenSSL::Digest::MD4.digest pwd
150
- end
151
-
152
- # Generate a NTLMv2 Hash
153
- # @param [String] user The username
154
- # @param [String] password The password
155
- # @param [String] target The domain or workstation to authenticate to
156
- # @option opt :unicode (false) Unicode encode the domain
157
- def ntlmv2_hash(user, password, target, opt={})
158
- if is_ntlm_hash? password
159
- decoded_password = EncodeUtil.decode_utf16le(password)
160
- ntlmhash = [decoded_password.upcase[33,65]].pack('H32')
161
- else
162
- ntlmhash = ntlm_hash(password, opt)
163
- end
164
- userdomain = user.upcase + target
165
- unless opt[:unicode]
166
- userdomain = EncodeUtil.encode_utf16le(userdomain)
167
- end
168
- OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, ntlmhash, userdomain)
169
- end
170
-
171
- def lm_response(arg)
172
- begin
173
- hash = arg[:lm_hash]
174
- chal = arg[:challenge]
175
- rescue
176
- raise ArgumentError
177
- end
178
- chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
179
- keys = gen_keys hash.ljust(21, "\0")
180
- apply_des(chal, keys).join
181
- end
182
-
183
- def ntlm_response(arg)
184
- hash = arg[:ntlm_hash]
185
- chal = arg[:challenge]
186
- chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
187
- keys = gen_keys hash.ljust(21, "\0")
188
- apply_des(chal, keys).join
189
- end
190
-
191
- def ntlmv2_response(arg, opt = {})
192
- begin
193
- key = arg[:ntlmv2_hash]
194
- chal = arg[:challenge]
195
- ti = arg[:target_info]
196
- rescue
197
- raise ArgumentError
198
- end
199
- chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
200
-
201
- if opt[:client_challenge]
202
- cc = opt[:client_challenge]
203
- else
204
- cc = rand(MAX64)
205
- end
206
- cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
207
-
208
- if opt[:timestamp]
209
- ts = opt[:timestamp]
210
- else
211
- ts = Time.now.to_i
212
- end
213
- # epoch -> milsec from Jan 1, 1601
214
- ts = 10_000_000 * (ts + TIME_OFFSET)
215
-
216
- blob = Blob.new
217
- blob.timestamp = ts
218
- blob.challenge = cc
219
- blob.target_info = ti
220
-
221
- bb = blob.serialize
222
-
223
- OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + bb) + bb
224
- end
225
-
226
- def lmv2_response(arg, opt = {})
227
- key = arg[:ntlmv2_hash]
228
- chal = arg[:challenge]
229
-
230
- chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
231
-
232
- if opt[:client_challenge]
233
- cc = opt[:client_challenge]
234
- else
235
- cc = rand(MAX64)
236
- end
237
- cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
238
-
239
- OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + cc) + cc
240
- end
241
-
242
- def ntlm2_session(arg, opt = {})
243
- begin
244
- passwd_hash = arg[:ntlm_hash]
245
- chal = arg[:challenge]
246
- rescue
247
- raise ArgumentError
248
- end
249
- chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
250
-
251
- if opt[:client_challenge]
252
- cc = opt[:client_challenge]
253
- else
254
- cc = rand(MAX64)
255
- end
256
- cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
257
-
258
- keys = gen_keys(passwd_hash.ljust(21, "\0"))
259
- session_hash = OpenSSL::Digest::MD5.digest(chal + cc).slice(0, 8)
260
- response = apply_des(session_hash, keys).join
261
- [cc.ljust(24, "\0"), response]
262
- end
263
- end
264
-
265
- end
266
- end
1
+ # encoding: UTF-8
2
+ #
3
+ # = net/ntlm.rb
4
+ #
5
+ # An NTLM Authentication Library for Ruby
6
+ #
7
+ # This code is a derivative of "dbf2.rb" written by yrock
8
+ # and Minero Aoki. You can find original code here:
9
+ # http://jp.rubyist.net/magazine/?0013-CodeReview
10
+ # -------------------------------------------------------------
11
+ # Copyright (c) 2005,2006 yrock
12
+ #
13
+ #
14
+ # 2006-02-11 refactored by Minero Aoki
15
+ # -------------------------------------------------------------
16
+ #
17
+ # All protocol information used to write this code stems from
18
+ # "The NTLM Authentication Protocol" by Eric Glass. The author
19
+ # would thank to him for this tremendous work and making it
20
+ # available on the net.
21
+ # http://davenport.sourceforge.net/ntlm.html
22
+ # -------------------------------------------------------------
23
+ # Copyright (c) 2003 Eric Glass
24
+ #
25
+ # -------------------------------------------------------------
26
+ #
27
+ # The author also looked Mozilla-Firefox-1.0.7 source code,
28
+ # namely, security/manager/ssl/src/nsNTLMAuthModule.cpp and
29
+ # Jonathan Bastien-Filiatrault's libntlm-ruby.
30
+ # "http://x2a.org/websvn/filedetails.php?
31
+ # repname=libntlm-ruby&path=%2Ftrunk%2Fntlm.rb&sc=1"
32
+ # The latter has a minor bug in its separate_keys function.
33
+ # The third key has to begin from the 14th character of the
34
+ # input string instead of 13th:)
35
+ #--
36
+ # $Id: ntlm.rb,v 1.1 2006/10/05 01:36:52 koheik Exp $
37
+ #++
38
+
39
+ require 'base64'
40
+ require 'openssl'
41
+ require 'openssl/digest'
42
+ require 'socket'
43
+
44
+ # Load Order is important here
45
+ require 'net/ntlm/exceptions'
46
+ require 'net/ntlm/field'
47
+ require 'net/ntlm/int16_le'
48
+ require 'net/ntlm/int32_le'
49
+ require 'net/ntlm/int64_le'
50
+ require 'net/ntlm/string'
51
+
52
+ require 'net/ntlm/field_set'
53
+ require 'net/ntlm/blob'
54
+ require 'net/ntlm/security_buffer'
55
+ require 'net/ntlm/message'
56
+ require 'net/ntlm/message/type0'
57
+ require 'net/ntlm/message/type1'
58
+ require 'net/ntlm/message/type2'
59
+ require 'net/ntlm/message/type3'
60
+
61
+ require 'net/ntlm/encode_util'
62
+
63
+ require 'net/ntlm/client'
64
+ require 'net/ntlm/channel_binding'
65
+ require 'net/ntlm/target_info'
66
+
67
+ module Net
68
+ module NTLM
69
+
70
+ LM_MAGIC = "KGS!@\#$%"
71
+ TIME_OFFSET = 11644473600
72
+ MAX64 = 0xffffffffffffffff
73
+
74
+
75
+ class << self
76
+
77
+ # Valid format for LAN Manager hex digest portion: 32 hexadecimal characters.
78
+ LAN_MANAGER_HEX_DIGEST_REGEXP = /[0-9a-f]{32}/i
79
+ # Valid format for NT LAN Manager hex digest portion: 32 hexadecimal characters.
80
+ NT_LAN_MANAGER_HEX_DIGEST_REGEXP = /[0-9a-f]{32}/i
81
+ # Valid format for an NTLM hash composed of `'<LAN Manager hex digest>:<NT LAN Manager hex digest>'`.
82
+ DATA_REGEXP = /\A#{LAN_MANAGER_HEX_DIGEST_REGEXP}:#{NT_LAN_MANAGER_HEX_DIGEST_REGEXP}\z/
83
+
84
+ # Takes a string and determines whether it is a valid NTLM Hash
85
+ # @param [String] the string to validate
86
+ # @return [Boolean] whether or not the string is a valid NTLM hash
87
+ def is_ntlm_hash?(data)
88
+ decoded_data = data.dup
89
+ decoded_data = EncodeUtil.decode_utf16le(decoded_data)
90
+ if DATA_REGEXP.match(decoded_data)
91
+ true
92
+ else
93
+ false
94
+ end
95
+ end
96
+
97
+ # Conver the value to a 64-Bit Little Endian Int
98
+ # @param [String] val The string to convert
99
+ def pack_int64le(val)
100
+ [val & 0x00000000ffffffff, val >> 32].pack("V2")
101
+ end
102
+
103
+ # Builds an array of strings that are 7 characters long
104
+ # @param [String] str The string to split
105
+ # @api private
106
+ def split7(str)
107
+ s = str.dup
108
+ until s.empty?
109
+ (ret ||= []).push s.slice!(0, 7)
110
+ end
111
+ ret
112
+ end
113
+
114
+ # Not sure what this is doing
115
+ # @param [String] str String to generate keys for
116
+ # @api private
117
+ def gen_keys(str)
118
+ split7(str).map{ |str7|
119
+ bits = split7(str7.unpack("B*")[0]).inject('')\
120
+ {|ret, tkn| ret += tkn + (tkn.gsub('1', '').size % 2).to_s }
121
+ [bits].pack("B*")
122
+ }
123
+ end
124
+
125
+ def apply_des(plain, keys)
126
+ dec = OpenSSL::Cipher.new("des-cbc")
127
+ dec.padding = 0
128
+ keys.map {|k|
129
+ dec.key = k
130
+ dec.encrypt.update(plain) + dec.final
131
+ }
132
+ end
133
+
134
+ # Generates a Lan Manager Hash
135
+ # @param [String] password The password to base the hash on
136
+ def lm_hash(password)
137
+ keys = gen_keys password.upcase.ljust(14, "\0")
138
+ apply_des(LM_MAGIC, keys).join
139
+ end
140
+
141
+ # Generate a NTLM Hash
142
+ # @param [String] password The password to base the hash on
143
+ # @option opt :unicode (false) Unicode encode the password
144
+ def ntlm_hash(password, opt = {})
145
+ pwd = password.dup
146
+ unless opt[:unicode]
147
+ pwd = EncodeUtil.encode_utf16le(pwd)
148
+ end
149
+ OpenSSL::Digest::MD4.digest pwd
150
+ end
151
+
152
+ # Generate a NTLMv2 Hash
153
+ # @param [String] user The username
154
+ # @param [String] password The password
155
+ # @param [String] target The domain or workstation to authenticate to
156
+ # @option opt :unicode (false) Unicode encode the domain
157
+ def ntlmv2_hash(user, password, target, opt={})
158
+ if is_ntlm_hash? password
159
+ decoded_password = EncodeUtil.decode_utf16le(password)
160
+ ntlmhash = [decoded_password.upcase[33,65]].pack('H32')
161
+ else
162
+ ntlmhash = ntlm_hash(password, opt)
163
+ end
164
+ userdomain = user.upcase + target
165
+ unless opt[:unicode]
166
+ userdomain = EncodeUtil.encode_utf16le(userdomain)
167
+ end
168
+ OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, ntlmhash, userdomain)
169
+ end
170
+
171
+ def lm_response(arg)
172
+ begin
173
+ hash = arg[:lm_hash]
174
+ chal = arg[:challenge]
175
+ rescue
176
+ raise ArgumentError
177
+ end
178
+ chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
179
+ keys = gen_keys hash.ljust(21, "\0")
180
+ apply_des(chal, keys).join
181
+ end
182
+
183
+ def ntlm_response(arg)
184
+ hash = arg[:ntlm_hash]
185
+ chal = arg[:challenge]
186
+ chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
187
+ keys = gen_keys hash.ljust(21, "\0")
188
+ apply_des(chal, keys).join
189
+ end
190
+
191
+ def ntlmv2_response(arg, opt = {})
192
+ begin
193
+ key = arg[:ntlmv2_hash]
194
+ chal = arg[:challenge]
195
+ ti = arg[:target_info]
196
+ rescue
197
+ raise ArgumentError
198
+ end
199
+ chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
200
+
201
+ if opt[:client_challenge]
202
+ cc = opt[:client_challenge]
203
+ else
204
+ cc = rand(MAX64)
205
+ end
206
+ cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
207
+
208
+ if opt[:timestamp]
209
+ ts = opt[:timestamp]
210
+ else
211
+ ts = Time.now.to_i
212
+ end
213
+ # epoch -> milsec from Jan 1, 1601
214
+ ts = 10_000_000 * (ts + TIME_OFFSET)
215
+
216
+ blob = Blob.new
217
+ blob.timestamp = ts
218
+ blob.challenge = cc
219
+ blob.target_info = ti
220
+
221
+ bb = blob.serialize
222
+
223
+ OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + bb) + bb
224
+ end
225
+
226
+ def lmv2_response(arg, opt = {})
227
+ key = arg[:ntlmv2_hash]
228
+ chal = arg[:challenge]
229
+
230
+ chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
231
+
232
+ if opt[:client_challenge]
233
+ cc = opt[:client_challenge]
234
+ else
235
+ cc = rand(MAX64)
236
+ end
237
+ cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
238
+
239
+ OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + cc) + cc
240
+ end
241
+
242
+ def ntlm2_session(arg, opt = {})
243
+ begin
244
+ passwd_hash = arg[:ntlm_hash]
245
+ chal = arg[:challenge]
246
+ rescue
247
+ raise ArgumentError
248
+ end
249
+ chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
250
+
251
+ if opt[:client_challenge]
252
+ cc = opt[:client_challenge]
253
+ else
254
+ cc = rand(MAX64)
255
+ end
256
+ cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
257
+
258
+ keys = gen_keys(passwd_hash.ljust(21, "\0"))
259
+ session_hash = OpenSSL::Digest::MD5.digest(chal + cc).slice(0, 8)
260
+ response = apply_des(session_hash, keys).join
261
+ [cc.ljust(24, "\0"), response]
262
+ end
263
+ end
264
+
265
+ end
266
+ end