rubyntlm 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -3
- data/.rspec +2 -2
- data/.travis.yml +13 -12
- data/CHANGELOG.md +118 -6
- data/Gemfile +3 -3
- data/LICENSE +19 -19
- data/Rakefile +25 -22
- data/lib/net/ntlm.rb +266 -266
- data/lib/net/ntlm/blob.rb +28 -28
- data/lib/net/ntlm/channel_binding.rb +65 -65
- data/lib/net/ntlm/client.rb +65 -65
- data/lib/net/ntlm/client/session.rb +237 -237
- data/lib/net/ntlm/encode_util.rb +48 -48
- data/lib/net/ntlm/exceptions.rb +14 -14
- data/lib/net/ntlm/field.rb +34 -34
- data/lib/net/ntlm/field_set.rb +129 -129
- data/lib/net/ntlm/int16_le.rb +25 -25
- data/lib/net/ntlm/int32_le.rb +24 -24
- data/lib/net/ntlm/int64_le.rb +25 -25
- data/lib/net/ntlm/message.rb +129 -129
- data/lib/net/ntlm/message/type0.rb +16 -16
- data/lib/net/ntlm/message/type1.rb +18 -18
- data/lib/net/ntlm/message/type2.rb +102 -102
- data/lib/net/ntlm/message/type3.rb +131 -131
- data/lib/net/ntlm/security_buffer.rb +47 -47
- data/lib/net/ntlm/string.rb +34 -34
- data/lib/net/ntlm/target_info.rb +89 -89
- data/lib/net/ntlm/version.rb +11 -11
- data/rubyntlm.gemspec +29 -28
- data/spec/lib/net/ntlm/blob_spec.rb +16 -16
- data/spec/lib/net/ntlm/channel_binding_spec.rb +17 -17
- data/spec/lib/net/ntlm/client/session_spec.rb +68 -68
- data/spec/lib/net/ntlm/client_spec.rb +64 -64
- data/spec/lib/net/ntlm/encode_util_spec.rb +16 -16
- data/spec/lib/net/ntlm/field_set_spec.rb +33 -33
- data/spec/lib/net/ntlm/field_spec.rb +34 -34
- data/spec/lib/net/ntlm/int16_le_spec.rb +17 -17
- data/spec/lib/net/ntlm/int32_le_spec.rb +18 -18
- data/spec/lib/net/ntlm/int64_le_spec.rb +18 -18
- data/spec/lib/net/ntlm/message/type0_spec.rb +20 -20
- data/spec/lib/net/ntlm/message/type1_spec.rb +131 -131
- data/spec/lib/net/ntlm/message/type2_spec.rb +132 -132
- data/spec/lib/net/ntlm/message/type3_spec.rb +225 -225
- data/spec/lib/net/ntlm/message_spec.rb +16 -16
- data/spec/lib/net/ntlm/security_buffer_spec.rb +64 -64
- data/spec/lib/net/ntlm/string_spec.rb +72 -72
- data/spec/lib/net/ntlm/target_info_spec.rb +76 -76
- data/spec/lib/net/ntlm/version_spec.rb +27 -27
- data/spec/lib/net/ntlm_spec.rb +127 -127
- data/spec/spec_helper.rb +22 -22
- data/spec/support/certificates/sha_256_hash.pem +19 -19
- data/spec/support/shared/examples/net/ntlm/field_shared.rb +25 -25
- data/spec/support/shared/examples/net/ntlm/fieldset_shared.rb +239 -239
- data/spec/support/shared/examples/net/ntlm/int_shared.rb +43 -43
- data/spec/support/shared/examples/net/ntlm/message_shared.rb +35 -35
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1faff36beeb295ca5d6326a6140686242c3c2447
|
4
|
+
data.tar.gz: 23a28cbdddae6dc194754d2a069c6b0cdfbeee05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/.travis.yml
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
language: ruby
|
2
|
-
rvm:
|
3
|
-
- 2.1.9
|
4
|
-
- 2.2.0
|
5
|
-
- 2.3.1
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
branches
|
11
|
-
|
12
|
-
|
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
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,118 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
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
|
data/lib/net/ntlm.rb
CHANGED
@@ -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
|
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
|