rubyntlm 0.6.6 → 0.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +48 -48
- data/lib/net/ntlm/blob.rb +11 -10
- data/lib/net/ntlm/channel_binding.rb +13 -9
- data/lib/net/ntlm/client/session.rb +34 -141
- data/lib/net/ntlm/client/session_crypto.rb +126 -0
- data/lib/net/ntlm/client.rb +8 -9
- data/lib/net/ntlm/encode_util.rb +39 -38
- data/lib/net/ntlm/exceptions.rb +3 -0
- data/lib/net/ntlm/field.rb +29 -31
- data/lib/net/ntlm/field_set.rb +39 -18
- data/lib/net/ntlm/int16_le.rb +8 -8
- data/lib/net/ntlm/int32_le.rb +8 -7
- data/lib/net/ntlm/int64_le.rb +8 -7
- data/lib/net/ntlm/md4.rb +102 -64
- data/lib/net/ntlm/message/type0.rb +4 -7
- data/lib/net/ntlm/message/type1.rb +8 -9
- data/lib/net/ntlm/message/type2.rb +87 -67
- data/lib/net/ntlm/message/type3.rb +43 -41
- data/lib/net/ntlm/message.rb +116 -111
- data/lib/net/ntlm/rc4.rb +51 -44
- data/lib/net/ntlm/response.rb +112 -0
- data/lib/net/ntlm/security_buffer.rb +13 -15
- data/lib/net/ntlm/string.rb +8 -7
- data/lib/net/ntlm/target_info.rb +52 -44
- data/lib/net/ntlm/version.rb +3 -1
- data/lib/net/ntlm.rb +37 -125
- data/lib/rubyntlm.rb +3 -1
- metadata +5 -44
- data/.devcontainer/devcontainer.json +0 -22
- data/.github/dependabot.yml +0 -10
- data/.github/workflows/build.yml +0 -55
- data/.gitignore +0 -11
- data/.rspec +0 -3
- data/Gemfile +0 -20
- data/Rakefile +0 -37
- data/examples/http.rb +0 -86
- data/examples/imap.rb +0 -73
- data/examples/smtp.rb +0 -94
- data/rubyntlm.gemspec +0 -28
- data/spec/lib/net/ntlm/blob_spec.rb +0 -14
- data/spec/lib/net/ntlm/channel_binding_spec.rb +0 -15
- data/spec/lib/net/ntlm/client/session_spec.rb +0 -85
- data/spec/lib/net/ntlm/client_spec.rb +0 -62
- data/spec/lib/net/ntlm/encode_util_spec.rb +0 -14
- data/spec/lib/net/ntlm/field_set_spec.rb +0 -31
- data/spec/lib/net/ntlm/field_spec.rb +0 -32
- data/spec/lib/net/ntlm/int16_le_spec.rb +0 -16
- data/spec/lib/net/ntlm/int32_le_spec.rb +0 -17
- data/spec/lib/net/ntlm/int64_le_spec.rb +0 -17
- data/spec/lib/net/ntlm/md4_spec.rb +0 -16
- data/spec/lib/net/ntlm/message/type0_spec.rb +0 -19
- data/spec/lib/net/ntlm/message/type1_spec.rb +0 -129
- data/spec/lib/net/ntlm/message/type2_spec.rb +0 -131
- data/spec/lib/net/ntlm/message/type3_spec.rb +0 -336
- data/spec/lib/net/ntlm/message_spec.rb +0 -15
- data/spec/lib/net/ntlm/security_buffer_spec.rb +0 -62
- data/spec/lib/net/ntlm/string_spec.rb +0 -70
- data/spec/lib/net/ntlm/target_info_spec.rb +0 -74
- data/spec/lib/net/ntlm/version_spec.rb +0 -26
- data/spec/lib/net/ntlm_spec.rb +0 -133
- data/spec/spec_helper.rb +0 -51
- data/spec/support/certificates/sha_256_hash.pem +0 -19
- data/spec/support/shared/examples/net/ntlm/field_shared.rb +0 -25
- data/spec/support/shared/examples/net/ntlm/fieldset_shared.rb +0 -239
- data/spec/support/shared/examples/net/ntlm/int_shared.rb +0 -43
- data/spec/support/shared/examples/net/ntlm/message_shared.rb +0 -35
data/lib/net/ntlm.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
#
|
|
3
4
|
# = net/ntlm.rb
|
|
4
5
|
#
|
|
@@ -61,21 +62,20 @@ require 'net/ntlm/message/type3'
|
|
|
61
62
|
require 'net/ntlm/encode_util'
|
|
62
63
|
require 'net/ntlm/md4'
|
|
63
64
|
require 'net/ntlm/rc4'
|
|
65
|
+
require 'net/ntlm/response'
|
|
64
66
|
|
|
65
67
|
require 'net/ntlm/client'
|
|
66
68
|
require 'net/ntlm/channel_binding'
|
|
67
69
|
require 'net/ntlm/target_info'
|
|
68
70
|
|
|
69
71
|
module Net
|
|
72
|
+
# Ruby/NTLM library: message creator and parser for NTLM authentication.
|
|
70
73
|
module NTLM
|
|
71
|
-
|
|
72
74
|
LM_MAGIC = "KGS!@\#$%"
|
|
73
|
-
TIME_OFFSET =
|
|
75
|
+
TIME_OFFSET = 11_644_473_600
|
|
74
76
|
MAX64 = 0xffffffffffffffff
|
|
75
77
|
|
|
76
|
-
|
|
77
78
|
class << self
|
|
78
|
-
|
|
79
79
|
# Valid format for LAN Manager hex digest portion: 32 hexadecimal characters.
|
|
80
80
|
LAN_MANAGER_HEX_DIGEST_REGEXP = /[0-9a-f]{32}/i
|
|
81
81
|
# Valid format for NT LAN Manager hex digest portion: 32 hexadecimal characters.
|
|
@@ -86,7 +86,7 @@ module Net
|
|
|
86
86
|
# Takes a string and determines whether it is a valid NTLM Hash
|
|
87
87
|
# @param [String] the string to validate
|
|
88
88
|
# @return [Boolean] whether or not the string is a valid NTLM hash
|
|
89
|
-
def
|
|
89
|
+
def ntlm_hash?(data)
|
|
90
90
|
decoded_data = data.dup
|
|
91
91
|
decoded_data = EncodeUtil.decode_utf16le(decoded_data)
|
|
92
92
|
if DATA_REGEXP.match(decoded_data)
|
|
@@ -96,10 +96,12 @@ module Net
|
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
+
alias is_ntlm_hash? ntlm_hash?
|
|
100
|
+
|
|
99
101
|
# Convert the value to a 64-bit little-endian integer
|
|
100
102
|
# @param [String] val The string to convert
|
|
101
103
|
def pack_int64le(val)
|
|
102
|
-
[val & 0x00000000ffffffff, val >> 32].pack(
|
|
104
|
+
[val & 0x00000000ffffffff, val >> 32].pack('V2')
|
|
103
105
|
end
|
|
104
106
|
|
|
105
107
|
# Builds an array of strings that are 7 characters long
|
|
@@ -107,9 +109,7 @@ module Net
|
|
|
107
109
|
# @api private
|
|
108
110
|
def split7(str)
|
|
109
111
|
s = str.dup
|
|
110
|
-
until s.empty?
|
|
111
|
-
(ret ||= []).push s.slice!(0, 7)
|
|
112
|
-
end
|
|
112
|
+
(ret ||= []).push s.slice!(0, 7) until s.empty?
|
|
113
113
|
ret
|
|
114
114
|
end
|
|
115
115
|
|
|
@@ -118,18 +118,18 @@ module Net
|
|
|
118
118
|
# @param [String] str String to generate keys for
|
|
119
119
|
# @api private
|
|
120
120
|
def gen_keys(str)
|
|
121
|
-
split7(str).map{ |str7|
|
|
122
|
-
bits = split7(str7.
|
|
123
|
-
{|ret, tkn| ret
|
|
124
|
-
[bits].pack(
|
|
121
|
+
split7(str).map { |str7|
|
|
122
|
+
bits = split7(str7.unpack1('B*')).inject('')\
|
|
123
|
+
{ |ret, tkn| ret + tkn + (tkn.gsub('1', '').size % 2).to_s }
|
|
124
|
+
[bits].pack('B*')
|
|
125
125
|
}
|
|
126
126
|
end
|
|
127
127
|
|
|
128
128
|
def apply_des(plain, keys)
|
|
129
|
-
keys.map {|k|
|
|
129
|
+
keys.map { |k|
|
|
130
130
|
# Spec requires des-cbc, but openssl 3 does not support single des
|
|
131
131
|
# by default, so just do triple DES (EDE) with the same key
|
|
132
|
-
dec = OpenSSL::Cipher.new(
|
|
132
|
+
dec = OpenSSL::Cipher.new('des-ede-cbc').encrypt
|
|
133
133
|
dec.padding = 0
|
|
134
134
|
dec.key = k + k
|
|
135
135
|
dec.update(plain) + dec.final
|
|
@@ -148,9 +148,7 @@ module Net
|
|
|
148
148
|
# @option opt :unicode (false) Unicode encode the password
|
|
149
149
|
def ntlm_hash(password, opt = {})
|
|
150
150
|
pwd = password.dup
|
|
151
|
-
unless opt[:unicode]
|
|
152
|
-
pwd = EncodeUtil.encode_utf16le(pwd)
|
|
153
|
-
end
|
|
151
|
+
pwd = EncodeUtil.encode_utf16le(pwd) unless opt[:unicode]
|
|
154
152
|
Net::NTLM::Md4.digest pwd
|
|
155
153
|
end
|
|
156
154
|
|
|
@@ -159,124 +157,38 @@ module Net
|
|
|
159
157
|
# @param [String] password The password
|
|
160
158
|
# @param [String] target The domain or workstation to authenticate to
|
|
161
159
|
# @option [Boolean] opt :unicode (false) Unicode encode the domain.
|
|
162
|
-
def ntlmv2_hash(user, password, target, opt={})
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
else
|
|
167
|
-
ntlmhash = ntlm_hash(password, opt)
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
if opt[:unicode]
|
|
171
|
-
# Uppercase operation on username containing non-ASCI characters
|
|
172
|
-
# after behing unicode encoded with `EncodeUtil.encode_utf16le`
|
|
173
|
-
# doesn't play well. Upcase should be done before encoding.
|
|
174
|
-
user_upcase = EncodeUtil.decode_utf16le(user).upcase
|
|
175
|
-
user_upcase = EncodeUtil.encode_utf16le(user_upcase)
|
|
176
|
-
else
|
|
177
|
-
user_upcase = user.upcase
|
|
178
|
-
end
|
|
179
|
-
userdomain = user_upcase + target
|
|
180
|
-
|
|
181
|
-
unless opt[:unicode]
|
|
182
|
-
userdomain = EncodeUtil.encode_utf16le(userdomain)
|
|
183
|
-
end
|
|
184
|
-
OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, ntlmhash, userdomain)
|
|
160
|
+
def ntlmv2_hash(user, password, target, opt = {})
|
|
161
|
+
ntlmhash = ntlmv2_key(password, opt)
|
|
162
|
+
userdomain = ntlmv2_userdomain(user, target, opt)
|
|
163
|
+
OpenSSL::HMAC.digest(OpenSSL::Digest.new('MD5'), ntlmhash, userdomain)
|
|
185
164
|
end
|
|
186
165
|
|
|
187
|
-
|
|
188
|
-
begin
|
|
189
|
-
hash = arg[:lm_hash]
|
|
190
|
-
chal = arg[:challenge]
|
|
191
|
-
rescue
|
|
192
|
-
raise ArgumentError
|
|
193
|
-
end
|
|
194
|
-
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
|
195
|
-
keys = gen_keys hash.ljust(21, "\0")
|
|
196
|
-
apply_des(chal, keys).join
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
def ntlm_response(arg)
|
|
200
|
-
hash = arg[:ntlm_hash]
|
|
201
|
-
chal = arg[:challenge]
|
|
202
|
-
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
|
203
|
-
keys = gen_keys hash.ljust(21, "\0")
|
|
204
|
-
apply_des(chal, keys).join
|
|
205
|
-
end
|
|
166
|
+
private
|
|
206
167
|
|
|
207
|
-
def
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
ti = arg[:target_info]
|
|
212
|
-
rescue
|
|
213
|
-
raise ArgumentError
|
|
214
|
-
end
|
|
215
|
-
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
|
216
|
-
|
|
217
|
-
if opt[:client_challenge]
|
|
218
|
-
cc = opt[:client_challenge]
|
|
219
|
-
else
|
|
220
|
-
cc = rand(MAX64)
|
|
221
|
-
end
|
|
222
|
-
cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
|
|
223
|
-
|
|
224
|
-
if opt[:timestamp]
|
|
225
|
-
ts = opt[:timestamp]
|
|
168
|
+
def ntlmv2_key(password, opt)
|
|
169
|
+
if ntlm_hash? password
|
|
170
|
+
decoded = EncodeUtil.decode_utf16le(password)
|
|
171
|
+
[decoded.upcase[33, 65]].pack('H32')
|
|
226
172
|
else
|
|
227
|
-
|
|
173
|
+
ntlm_hash(password, opt)
|
|
228
174
|
end
|
|
229
|
-
# epoch -> milsec from Jan 1, 1601
|
|
230
|
-
ts = 10_000_000 * (ts + TIME_OFFSET)
|
|
231
|
-
|
|
232
|
-
blob = Blob.new
|
|
233
|
-
blob.timestamp = ts
|
|
234
|
-
blob.challenge = cc
|
|
235
|
-
blob.target_info = ti
|
|
236
|
-
|
|
237
|
-
bb = blob.serialize
|
|
238
|
-
|
|
239
|
-
OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + bb) + bb
|
|
240
175
|
end
|
|
241
176
|
|
|
242
|
-
def
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
|
247
|
-
|
|
248
|
-
if opt[:client_challenge]
|
|
249
|
-
cc = opt[:client_challenge]
|
|
250
|
-
else
|
|
251
|
-
cc = rand(MAX64)
|
|
252
|
-
end
|
|
253
|
-
cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
|
|
254
|
-
|
|
255
|
-
OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + cc) + cc
|
|
177
|
+
def ntlmv2_userdomain(user, target, opt)
|
|
178
|
+
userdomain = ntlmv2_upcase_user(user, opt) + target
|
|
179
|
+
opt[:unicode] ? userdomain : EncodeUtil.encode_utf16le(userdomain)
|
|
256
180
|
end
|
|
257
181
|
|
|
258
|
-
def
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
end
|
|
265
|
-
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
|
266
|
-
|
|
267
|
-
if opt[:client_challenge]
|
|
268
|
-
cc = opt[:client_challenge]
|
|
182
|
+
def ntlmv2_upcase_user(user, opt)
|
|
183
|
+
if opt[:unicode]
|
|
184
|
+
# Uppercase operation on username containing non-ASCI characters
|
|
185
|
+
# after behing unicode encoded with `EncodeUtil.encode_utf16le`
|
|
186
|
+
# doesn't play well. Upcase should be done before encoding.
|
|
187
|
+
EncodeUtil.encode_utf16le(EncodeUtil.decode_utf16le(user).upcase)
|
|
269
188
|
else
|
|
270
|
-
|
|
189
|
+
user.upcase
|
|
271
190
|
end
|
|
272
|
-
cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
|
|
273
|
-
|
|
274
|
-
keys = gen_keys(passwd_hash.ljust(21, "\0"))
|
|
275
|
-
session_hash = OpenSSL::Digest::MD5.digest(chal + cc).slice(0, 8)
|
|
276
|
-
response = apply_des(session_hash, keys).join
|
|
277
|
-
[cc.ljust(24, "\0"), response]
|
|
278
191
|
end
|
|
279
192
|
end
|
|
280
|
-
|
|
281
193
|
end
|
|
282
194
|
end
|
data/lib/rubyntlm.rb
CHANGED
metadata
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubyntlm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kohei Kajimoto
|
|
8
8
|
- Paul Morton
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: base64
|
|
@@ -33,24 +32,15 @@ executables: []
|
|
|
33
32
|
extensions: []
|
|
34
33
|
extra_rdoc_files: []
|
|
35
34
|
files:
|
|
36
|
-
- ".devcontainer/devcontainer.json"
|
|
37
|
-
- ".github/dependabot.yml"
|
|
38
|
-
- ".github/workflows/build.yml"
|
|
39
|
-
- ".gitignore"
|
|
40
|
-
- ".rspec"
|
|
41
35
|
- CHANGELOG.md
|
|
42
|
-
- Gemfile
|
|
43
36
|
- LICENSE
|
|
44
37
|
- README.md
|
|
45
|
-
- Rakefile
|
|
46
|
-
- examples/http.rb
|
|
47
|
-
- examples/imap.rb
|
|
48
|
-
- examples/smtp.rb
|
|
49
38
|
- lib/net/ntlm.rb
|
|
50
39
|
- lib/net/ntlm/blob.rb
|
|
51
40
|
- lib/net/ntlm/channel_binding.rb
|
|
52
41
|
- lib/net/ntlm/client.rb
|
|
53
42
|
- lib/net/ntlm/client/session.rb
|
|
43
|
+
- lib/net/ntlm/client/session_crypto.rb
|
|
54
44
|
- lib/net/ntlm/encode_util.rb
|
|
55
45
|
- lib/net/ntlm/exceptions.rb
|
|
56
46
|
- lib/net/ntlm/field.rb
|
|
@@ -65,39 +55,12 @@ files:
|
|
|
65
55
|
- lib/net/ntlm/message/type2.rb
|
|
66
56
|
- lib/net/ntlm/message/type3.rb
|
|
67
57
|
- lib/net/ntlm/rc4.rb
|
|
58
|
+
- lib/net/ntlm/response.rb
|
|
68
59
|
- lib/net/ntlm/security_buffer.rb
|
|
69
60
|
- lib/net/ntlm/string.rb
|
|
70
61
|
- lib/net/ntlm/target_info.rb
|
|
71
62
|
- lib/net/ntlm/version.rb
|
|
72
63
|
- lib/rubyntlm.rb
|
|
73
|
-
- rubyntlm.gemspec
|
|
74
|
-
- spec/lib/net/ntlm/blob_spec.rb
|
|
75
|
-
- spec/lib/net/ntlm/channel_binding_spec.rb
|
|
76
|
-
- spec/lib/net/ntlm/client/session_spec.rb
|
|
77
|
-
- spec/lib/net/ntlm/client_spec.rb
|
|
78
|
-
- spec/lib/net/ntlm/encode_util_spec.rb
|
|
79
|
-
- spec/lib/net/ntlm/field_set_spec.rb
|
|
80
|
-
- spec/lib/net/ntlm/field_spec.rb
|
|
81
|
-
- spec/lib/net/ntlm/int16_le_spec.rb
|
|
82
|
-
- spec/lib/net/ntlm/int32_le_spec.rb
|
|
83
|
-
- spec/lib/net/ntlm/int64_le_spec.rb
|
|
84
|
-
- spec/lib/net/ntlm/md4_spec.rb
|
|
85
|
-
- spec/lib/net/ntlm/message/type0_spec.rb
|
|
86
|
-
- spec/lib/net/ntlm/message/type1_spec.rb
|
|
87
|
-
- spec/lib/net/ntlm/message/type2_spec.rb
|
|
88
|
-
- spec/lib/net/ntlm/message/type3_spec.rb
|
|
89
|
-
- spec/lib/net/ntlm/message_spec.rb
|
|
90
|
-
- spec/lib/net/ntlm/security_buffer_spec.rb
|
|
91
|
-
- spec/lib/net/ntlm/string_spec.rb
|
|
92
|
-
- spec/lib/net/ntlm/target_info_spec.rb
|
|
93
|
-
- spec/lib/net/ntlm/version_spec.rb
|
|
94
|
-
- spec/lib/net/ntlm_spec.rb
|
|
95
|
-
- spec/spec_helper.rb
|
|
96
|
-
- spec/support/certificates/sha_256_hash.pem
|
|
97
|
-
- spec/support/shared/examples/net/ntlm/field_shared.rb
|
|
98
|
-
- spec/support/shared/examples/net/ntlm/fieldset_shared.rb
|
|
99
|
-
- spec/support/shared/examples/net/ntlm/int_shared.rb
|
|
100
|
-
- spec/support/shared/examples/net/ntlm/message_shared.rb
|
|
101
64
|
homepage: https://github.com/winrb/rubyntlm
|
|
102
65
|
licenses:
|
|
103
66
|
- MIT
|
|
@@ -106,7 +69,6 @@ metadata:
|
|
|
106
69
|
source_code_uri: https://github.com/winrb/rubyntlm
|
|
107
70
|
changelog_uri: https://github.com/winrb/rubyntlm/blob/master/CHANGELOG.md
|
|
108
71
|
bug_tracker_uri: https://github.com/winrb/rubyntlm/issues
|
|
109
|
-
post_install_message:
|
|
110
72
|
rdoc_options: []
|
|
111
73
|
require_paths:
|
|
112
74
|
- lib
|
|
@@ -121,8 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
121
83
|
- !ruby/object:Gem::Version
|
|
122
84
|
version: '0'
|
|
123
85
|
requirements: []
|
|
124
|
-
rubygems_version: 3.
|
|
125
|
-
signing_key:
|
|
86
|
+
rubygems_version: 3.6.9
|
|
126
87
|
specification_version: 4
|
|
127
88
|
summary: Ruby/NTLM library.
|
|
128
89
|
test_files: []
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
|
2
|
-
// README at: https://github.com/devcontainers/templates/tree/main/src/ruby
|
|
3
|
-
{
|
|
4
|
-
"name": "Ruby",
|
|
5
|
-
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
|
6
|
-
"image": "mcr.microsoft.com/devcontainers/ruby:1-3.3-bullseye"
|
|
7
|
-
|
|
8
|
-
// Features to add to the dev container. More info: https://containers.dev/features.
|
|
9
|
-
// "features": {},
|
|
10
|
-
|
|
11
|
-
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
|
12
|
-
// "forwardPorts": [],
|
|
13
|
-
|
|
14
|
-
// Use 'postCreateCommand' to run commands after the container is created.
|
|
15
|
-
// "postCreateCommand": "ruby --version",
|
|
16
|
-
|
|
17
|
-
// Configure tool-specific properties.
|
|
18
|
-
// "customizations": {},
|
|
19
|
-
|
|
20
|
-
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
|
21
|
-
// "remoteUser": "root"
|
|
22
|
-
}
|
data/.github/dependabot.yml
DELETED
data/.github/workflows/build.yml
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: build
|
|
3
|
-
|
|
4
|
-
"on":
|
|
5
|
-
pull_request:
|
|
6
|
-
push:
|
|
7
|
-
branches:
|
|
8
|
-
- master
|
|
9
|
-
|
|
10
|
-
# The job only ever reads the checkout; deny everything else by default.
|
|
11
|
-
permissions:
|
|
12
|
-
contents: read
|
|
13
|
-
|
|
14
|
-
# A new push to a PR makes the in-flight run redundant. Never cancel master,
|
|
15
|
-
# because those runs are what the README badge reports.
|
|
16
|
-
concurrency:
|
|
17
|
-
group: ${{ github.workflow }}-${{ github.ref }}
|
|
18
|
-
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
19
|
-
|
|
20
|
-
jobs:
|
|
21
|
-
unit:
|
|
22
|
-
name: ${{ matrix.os }} / ruby ${{ matrix.ruby }}
|
|
23
|
-
runs-on: ${{ matrix.os }}
|
|
24
|
-
timeout-minutes: 15
|
|
25
|
-
# Nightly builds break for reasons that are not this gem's fault, so they
|
|
26
|
-
# report without failing the run.
|
|
27
|
-
continue-on-error: ${{ matrix.experimental || false }}
|
|
28
|
-
strategy:
|
|
29
|
-
fail-fast: false
|
|
30
|
-
matrix:
|
|
31
|
-
os: [ubuntu-latest, windows-latest]
|
|
32
|
-
ruby: ['3.0', '3.1', '3.2', '3.3', '3.4', '4.0']
|
|
33
|
-
include:
|
|
34
|
-
- os: ubuntu-latest
|
|
35
|
-
ruby: 'head'
|
|
36
|
-
experimental: true
|
|
37
|
-
- os: windows-latest
|
|
38
|
-
ruby: 'head'
|
|
39
|
-
experimental: true
|
|
40
|
-
# truffleruby has no Windows build via setup-ruby.
|
|
41
|
-
- os: ubuntu-latest
|
|
42
|
-
ruby: 'truffleruby'
|
|
43
|
-
- os: ubuntu-latest
|
|
44
|
-
ruby: 'truffleruby-head'
|
|
45
|
-
experimental: true
|
|
46
|
-
steps:
|
|
47
|
-
- uses: actions/checkout@v4
|
|
48
|
-
|
|
49
|
-
- uses: ruby/setup-ruby@v1
|
|
50
|
-
with:
|
|
51
|
-
ruby-version: ${{ matrix.ruby }}
|
|
52
|
-
bundler-cache: true
|
|
53
|
-
|
|
54
|
-
- name: Run specs
|
|
55
|
-
run: bundle exec rake spec
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/Gemfile
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
source 'https://rubygems.org'
|
|
2
|
-
|
|
3
|
-
gemspec
|
|
4
|
-
|
|
5
|
-
# Development dependencies live here rather than in the gemspec so that they
|
|
6
|
-
# can be grouped, and so that consumers of the gem never resolve them.
|
|
7
|
-
group :development, :test do
|
|
8
|
-
gem 'pry'
|
|
9
|
-
gem 'rake'
|
|
10
|
-
gem 'rspec', '~> 3.13'
|
|
11
|
-
gem 'simplecov', require: false
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# Release tooling only. Marked optional so it is not installed by default:
|
|
15
|
-
# github_changelog_generator drags in a large, slow-moving dependency tree that
|
|
16
|
-
# does not resolve on every Ruby we test against. Opt in when cutting a release
|
|
17
|
-
# with `bundle install --with changelog`.
|
|
18
|
-
group :changelog, optional: true do
|
|
19
|
-
gem 'github_changelog_generator'
|
|
20
|
-
end
|
data/Rakefile
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
require "bundler/gem_tasks"
|
|
2
|
-
|
|
3
|
-
require 'rspec/core/rake_task'
|
|
4
|
-
RSpec::Core::RakeTask.new(:spec)
|
|
5
|
-
|
|
6
|
-
task :default => :spec
|
|
7
|
-
|
|
8
|
-
desc "Generate code coverage"
|
|
9
|
-
task :coverage do
|
|
10
|
-
ENV['COVERAGE'] = 'true'
|
|
11
|
-
Rake::Task["spec"].execute
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
desc "Open a Pry console for this library"
|
|
15
|
-
task :console do
|
|
16
|
-
require 'pry'
|
|
17
|
-
require 'net/ntlm'
|
|
18
|
-
ARGV.clear
|
|
19
|
-
Pry.start
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# Release tooling only, and deliberately optional: the :changelog bundle group
|
|
23
|
-
# is not installed by default, so this must never break `rake` or `rake spec`.
|
|
24
|
-
# Run `bundle install --with changelog` to enable it.
|
|
25
|
-
begin
|
|
26
|
-
require 'github_changelog_generator/task'
|
|
27
|
-
|
|
28
|
-
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
|
29
|
-
config.future_release = Net::NTLM::VERSION::STRING
|
|
30
|
-
end
|
|
31
|
-
rescue LoadError
|
|
32
|
-
desc "Generate CHANGELOG.md (requires: bundle install --with changelog)"
|
|
33
|
-
task :changelog do
|
|
34
|
-
abort "github_changelog_generator is not installed. " \
|
|
35
|
-
"Run `bundle install --with changelog` first."
|
|
36
|
-
end
|
|
37
|
-
end
|
data/examples/http.rb
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# $Id: http.rb,v 1.2 2006/10/05 01:36:52 koheik Exp $
|
|
2
|
-
require 'socket'
|
|
3
|
-
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
|
4
|
-
require 'net/ntlm'
|
|
5
|
-
|
|
6
|
-
$user = nil
|
|
7
|
-
$passwd = nil
|
|
8
|
-
|
|
9
|
-
$host = "www"
|
|
10
|
-
$port = 80
|
|
11
|
-
|
|
12
|
-
def header(f, host)
|
|
13
|
-
f.print "GET / HTTP/1.1\r\n"
|
|
14
|
-
f.print "Host: #{host}\r\n"
|
|
15
|
-
f.print "Keep-Alive: 300\r\n"
|
|
16
|
-
f.print "Connection: keep-alive\r\n"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def main
|
|
20
|
-
|
|
21
|
-
s = TCPSocket.new($host, $port)
|
|
22
|
-
|
|
23
|
-
# client -> server
|
|
24
|
-
t1 = Net::NTLM::Message::Type1.new()
|
|
25
|
-
header(s, $host)
|
|
26
|
-
s.print "Authorization: NTLM " + t1.encode64 + "\r\n"
|
|
27
|
-
s.print "\r\n"
|
|
28
|
-
|
|
29
|
-
# server -> client
|
|
30
|
-
length = 0
|
|
31
|
-
while(line = s.gets)
|
|
32
|
-
|
|
33
|
-
if /^WWW-Authenticate: (NTLM|Negotiate) (.+)\r\n/ =~ line
|
|
34
|
-
msg = $2
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
if /^Content-Length: (\d+)\r\n/ =~ line
|
|
38
|
-
length = $1.to_i
|
|
39
|
-
end
|
|
40
|
-
if /^\r\n/ =~ line
|
|
41
|
-
if length > 0
|
|
42
|
-
cont = s.read(length)
|
|
43
|
-
end
|
|
44
|
-
break
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
t2 = Net::NTLM::Message.decode64(msg)
|
|
48
|
-
|
|
49
|
-
unless $user and $passwd
|
|
50
|
-
target = t2.target_name
|
|
51
|
-
target = Net::NTLM::EncodeUtil.decode_utf16le(target) if t2.has_flag?(:UNICODE)
|
|
52
|
-
puts "Target: #{target}"
|
|
53
|
-
print "User name: "
|
|
54
|
-
($user = $stdin.readline).chomp!
|
|
55
|
-
print "Password: "
|
|
56
|
-
($passwd = $stdin.readline).chomp!
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# client -> server, again
|
|
60
|
-
t3 = t2.response({:user => $user, :password => $passwd}, {:ntlmv2 => true})
|
|
61
|
-
header(s, $host)
|
|
62
|
-
s.print "Authorization: NTLM " + t3.encode64 + "\r\n"
|
|
63
|
-
s.print "\r\n"
|
|
64
|
-
|
|
65
|
-
# server -> client
|
|
66
|
-
length = 0
|
|
67
|
-
while(line = s.gets)
|
|
68
|
-
|
|
69
|
-
if /^WWW-Authenticate: (NTLM|Negotiate) (.+)\r\n/ =~ line
|
|
70
|
-
msg = $2
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
if /^Content-Length: (\d+)\r\n/ =~ line
|
|
74
|
-
length = $1.to_i
|
|
75
|
-
end
|
|
76
|
-
if /^\r\n/ =~ line
|
|
77
|
-
if length > 0
|
|
78
|
-
p cont = s.read(length)
|
|
79
|
-
end
|
|
80
|
-
break
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
s.close
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
main
|
data/examples/imap.rb
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# $Id: imap.rb,v 1.1 2006/10/05 01:36:52 koheik Exp $
|
|
2
|
-
|
|
3
|
-
require "net/imap"
|
|
4
|
-
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
|
5
|
-
require "net/ntlm"
|
|
6
|
-
|
|
7
|
-
Net::IMAP::debug = true
|
|
8
|
-
|
|
9
|
-
$host = "localhost"
|
|
10
|
-
$port = 143
|
|
11
|
-
$ssl = false
|
|
12
|
-
$user = nil
|
|
13
|
-
$passwd = nil
|
|
14
|
-
|
|
15
|
-
module Net
|
|
16
|
-
class IMAP
|
|
17
|
-
class NtlmAuthenticator
|
|
18
|
-
def process(data)
|
|
19
|
-
case @state
|
|
20
|
-
when 1
|
|
21
|
-
@state = 2
|
|
22
|
-
t1 = Net::NTLM::Message::Type1.new()
|
|
23
|
-
return t1.serialize
|
|
24
|
-
when 2
|
|
25
|
-
@state = 3
|
|
26
|
-
t2 = Net::NTLM::Message.parse(data)
|
|
27
|
-
t3 = t2.response({:user => @user, :password => @password}, {:ntlmv2 => (@ntlm_type == "ntlmv2")})
|
|
28
|
-
return t3.serialize
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
private
|
|
33
|
-
|
|
34
|
-
def initialize(user, password, ntlm_type = "ntlmv2")
|
|
35
|
-
@user = user
|
|
36
|
-
@password = password
|
|
37
|
-
@ntlm_type = @ntlm_type
|
|
38
|
-
@state = 1
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
add_authenticator "NTLM", NtlmAuthenticator
|
|
42
|
-
|
|
43
|
-
class ResponseParser
|
|
44
|
-
def continue_req
|
|
45
|
-
match(T_PLUS)
|
|
46
|
-
if lookahead.symbol == T_CRLF # means empty message
|
|
47
|
-
return ContinuationRequest.new(ResponseText.new(nil, ""), @str)
|
|
48
|
-
end
|
|
49
|
-
match(T_SPACE)
|
|
50
|
-
return ContinuationRequest.new(resp_text, @str)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
unless $user and $passwd
|
|
57
|
-
print "User name: "
|
|
58
|
-
($user = $stdin.readline).chomp!
|
|
59
|
-
print "Password: "
|
|
60
|
-
($passwd = $stdin.readline).chomp!
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
imap = Net::IMAP.new($host, $port, $ssl)
|
|
64
|
-
imap.authenticate("NTLM", $user, $passwd)
|
|
65
|
-
imap.examine("Inbox")
|
|
66
|
-
# imap.search(["RECENT"]).each do |message_id|
|
|
67
|
-
# envelope = imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"]
|
|
68
|
-
# from = envelope.from.nil? ? "" : envelope.from[0].name
|
|
69
|
-
# subject = envelope.subject
|
|
70
|
-
# puts "#{message_id} #{from}: \t#{subject}"
|
|
71
|
-
# end
|
|
72
|
-
imap.logout
|
|
73
|
-
# imap.disconnect
|