rubyntlm 0.6.5 → 0.6.6

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +40 -9
  3. data/.gitignore +6 -0
  4. data/.rspec +1 -0
  5. data/CHANGELOG.md +5 -0
  6. data/Gemfile +17 -0
  7. data/README.md +1 -1
  8. data/Rakefile +15 -3
  9. data/lib/net/ntlm/md4.rb +3 -2
  10. data/lib/net/ntlm/message/type3.rb +9 -21
  11. data/lib/net/ntlm/version.rb +1 -1
  12. data/rubyntlm.gemspec +4 -7
  13. data/spec/lib/net/ntlm/blob_spec.rb +1 -3
  14. data/spec/lib/net/ntlm/channel_binding_spec.rb +1 -3
  15. data/spec/lib/net/ntlm/client/session_spec.rb +1 -3
  16. data/spec/lib/net/ntlm/client_spec.rb +1 -3
  17. data/spec/lib/net/ntlm/encode_util_spec.rb +1 -3
  18. data/spec/lib/net/ntlm/field_set_spec.rb +1 -3
  19. data/spec/lib/net/ntlm/field_spec.rb +1 -3
  20. data/spec/lib/net/ntlm/int16_le_spec.rb +1 -3
  21. data/spec/lib/net/ntlm/int32_le_spec.rb +1 -3
  22. data/spec/lib/net/ntlm/int64_le_spec.rb +1 -3
  23. data/spec/lib/net/ntlm/md4_spec.rb +16 -0
  24. data/spec/lib/net/ntlm/message/type0_spec.rb +1 -3
  25. data/spec/lib/net/ntlm/message/type1_spec.rb +1 -3
  26. data/spec/lib/net/ntlm/message/type2_spec.rb +1 -2
  27. data/spec/lib/net/ntlm/message/type3_spec.rb +72 -3
  28. data/spec/lib/net/ntlm/message_spec.rb +1 -3
  29. data/spec/lib/net/ntlm/security_buffer_spec.rb +1 -3
  30. data/spec/lib/net/ntlm/string_spec.rb +1 -3
  31. data/spec/lib/net/ntlm/target_info_spec.rb +1 -3
  32. data/spec/lib/net/ntlm/version_spec.rb +1 -2
  33. data/spec/lib/net/ntlm_spec.rb +1 -3
  34. data/spec/spec_helper.rb +44 -15
  35. data/spec/support/shared/examples/net/ntlm/field_shared.rb +1 -1
  36. data/spec/support/shared/examples/net/ntlm/fieldset_shared.rb +1 -1
  37. data/spec/support/shared/examples/net/ntlm/int_shared.rb +1 -1
  38. data/spec/support/shared/examples/net/ntlm/message_shared.rb +1 -1
  39. metadata +12 -104
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 12b18439c86b30b978043850938e3ec611230d2e0783828d6db337dfe4ea97ad
4
- data.tar.gz: 872a21844c21c9f64815abd312156c3fcddb8ebedc5185ec128106b6714b8521
3
+ metadata.gz: f618c1c4edae0dd1fc9e9a20d690f3b56d7280ba4e07dc097bfe86e8720ab043
4
+ data.tar.gz: 8b1516a2ae5919c22fd2788fbdb1c3cb78492826a629536fcb597afa6d2ecd69
5
5
  SHA512:
6
- metadata.gz: 03df0639b70648b2db81684060ce732d46f21a392590f4995ddb4c97399036ffc8d9a47fd1460b64441a34bebdbabfbd1f3d625bf1246a9e178a0901770f0ee5
7
- data.tar.gz: e3ff9341eb1738c501fe90d9456a8203e5771af2c459bb53f0168e24cbdd549540a0369d9a83f2864dce4fac86595cca4c7207b88f11a1b843d9fdbf52b59b20
6
+ metadata.gz: 0c5a6e37d4945d1abef840ceaf4b78b9149aba4c3cfc05f9b3bbeaa8b0e488b87c551d9652e0e9bda69983b788430cde3e8b968978dae0046f5d5f1dbf99cee2
7
+ data.tar.gz: a8a0fa4b29d5fa6b9d39bbaf6c3e1a9c342eb2c16e6cd43d969be33dac159c4b19babab2210810b4d14e1a1a0a2c62308cc04b05d6d6b84fe70dc232f5410ade
@@ -7,18 +7,49 @@ name: build
7
7
  branches:
8
8
  - master
9
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
+
10
20
  jobs:
11
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 }}
12
28
  strategy:
13
29
  fail-fast: false
14
30
  matrix:
15
- os: [ubuntu-latest, windows-2019]
16
- ruby: ['2.6', '2.7', '3.0', '3.1', '3.2', '3.3']
17
- runs-on: ${{ matrix.os }}
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
18
46
  steps:
19
- - uses: actions/checkout@v4
20
- - uses: ruby/setup-ruby@v1
21
- with:
22
- ruby-version: ${{ matrix.ruby }}
23
- bundler-cache: true
24
- - run: bundle exec rake
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 CHANGED
@@ -3,3 +3,9 @@
3
3
  /doc
4
4
  Gemfile.lock
5
5
  pkg
6
+
7
+ # Generated by SimpleCov (`rake coverage`)
8
+ /coverage
9
+
10
+ # RSpec's example status cache, used by `rspec --only-failures`
11
+ /spec/examples.txt
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
+ --require spec_helper
1
2
  --format documentation
2
3
  --color
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.6.6 (2026-09-09)
4
+
5
+ * Security: fix NTLMv2 authentication bypass in `Type3#password?`, which verified NTLMv2 responses against an empty password instead of the supplied one
6
+ * Fix binary padding in the Ruby MD4 fallback so non-ASCII passwords hash correctly under OpenSSL 3
7
+
3
8
  ## 0.6.5 (2024-06-11)
4
9
 
5
10
  * Update available NegotiateFlags during authentication
data/Gemfile CHANGED
@@ -1,3 +1,20 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ruby/NTLM -- NTLM Authentication Library for Ruby
2
2
 
3
- [![CI status](https://github.com/WinRb/rubyntlm/actions/workflows/build.yml/badge.svg)](https://github.com/WinRb/rubyntlm/actions/workflows/build.yml)
3
+ [![build status](https://github.com/WinRb/rubyntlm/actions/workflows/build.yml/badge.svg?branch=master&event=push)](https://github.com/WinRb/rubyntlm/actions/workflows/build.yml?query=branch%3Amaster+event%3Apush)
4
4
 
5
5
  Ruby/NTLM provides message creator and parser for the NTLM authentication.
6
6
 
data/Rakefile CHANGED
@@ -1,5 +1,4 @@
1
1
  require "bundler/gem_tasks"
2
- require 'github_changelog_generator/task'
3
2
 
4
3
  require 'rspec/core/rake_task'
5
4
  RSpec::Core::RakeTask.new(:spec)
@@ -20,6 +19,19 @@ task :console do
20
19
  Pry.start
21
20
  end
22
21
 
23
- GitHubChangelogGenerator::RakeTask.new :changelog do |config|
24
- config.future_release = Net::NTLM::VERSION::STRING
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
25
37
  end
data/lib/net/ntlm/md4.rb CHANGED
@@ -23,8 +23,9 @@ module NTLM
23
23
  # initial hash
24
24
  a, b, c, d = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
25
25
 
26
- bit_len = string.size << 3
27
- string += "\x80"
26
+ string = string.b
27
+ bit_len = string.bytesize << 3
28
+ string += "\x80".b
28
29
  while (string.size % 64) != 56
29
30
  string += "\0"
30
31
  end
@@ -101,29 +101,17 @@ module Net
101
101
  end
102
102
 
103
103
  def ntlmv2_password?(password, server_challenge)
104
+ # user and domain are already UTF-16LE from the wire; encode the
105
+ # supplied password to match before deriving the verification key.
106
+ key = NTLM.ntlmv2_hash(user, EncodeUtil.encode_utf16le(password), domain, :unicode => true)
107
+ server_challenge = NTLM.pack_int64le(server_challenge) if server_challenge.is_a?(Integer)
104
108
 
105
- # The first 16 bytes of the ntlm_response are the HMAC of the blob
106
- # that follows it.
107
- blob = Blob.new
108
- blob.parse(ntlm_response[16..-1])
109
-
110
- empty_hash = NTLM.ntlmv2_response(
111
- {
112
- # user and domain came from the serialized data here, so
113
- # they're already unicode
114
- :ntlmv2_hash => NTLM.ntlmv2_hash(user, '', domain, :unicode => true),
115
- :challenge => server_challenge,
116
- :target_info => blob.target_info
117
- },
118
- {
119
- :client_challenge => blob.challenge,
120
- # The blob's timestamp is already in milliseconds since 1601,
121
- # so convert it back to epoch time first
122
- :timestamp => (blob.timestamp / 10_000_000) - NTLM::TIME_OFFSET,
123
- }
109
+ # Authenticate the exact blob bytes. Rebuilding the blob truncates
110
+ # sub-second timestamps and rejects otherwise valid responses.
111
+ expected_proof = OpenSSL::HMAC.digest(
112
+ OpenSSL::Digest::MD5.new, key, server_challenge + ntlm_response[16..-1]
124
113
  )
125
-
126
- empty_hash == ntlm_response
114
+ expected_proof == ntlm_response[0,16]
127
115
  end
128
116
  end
129
117
  end
@@ -4,7 +4,7 @@ module Net
4
4
  module VERSION
5
5
  MAJOR = 0
6
6
  MINOR = 6
7
- TINY = 5
7
+ TINY = 6
8
8
  STRING = [MAJOR, MINOR, TINY].join('.')
9
9
  end
10
10
  end
data/rubyntlm.gemspec CHANGED
@@ -13,19 +13,16 @@ Gem::Specification.new do |s|
13
13
 
14
14
 
15
15
  s.files = `git ls-files`.split($/)
16
- s.test_files = s.files.grep(%r{^(test|spec|features)/})
17
16
  s.require_paths = ["lib"]
18
17
 
19
- s.required_ruby_version = '>= 2.6.0'
18
+ s.required_ruby_version = '>= 3.0.0'
20
19
 
21
20
  s.license = 'MIT'
22
21
 
23
- s.add_development_dependency 'github_changelog_generator', '1.14.3'
24
- s.add_development_dependency "pry"
25
- s.add_development_dependency "rake"
26
- s.add_development_dependency "rspec", ">= 2.11"
27
- s.add_development_dependency "simplecov"
28
22
  s.add_dependency "base64"
29
23
 
30
24
  s.metadata["rubygems_mfa_required"] = "true"
25
+ s.metadata["source_code_uri"] = s.homepage
26
+ s.metadata["changelog_uri"] = "#{s.homepage}/blob/master/CHANGELOG.md"
27
+ s.metadata["bug_tracker_uri"] = "#{s.homepage}/issues"
31
28
  end
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::Blob do
1
+ RSpec.describe Net::NTLM::Blob do
4
2
 
5
3
  fields = [
6
4
  { :name => :blob_signature, :class => Net::NTLM::Int32LE, :value => 257, :active => true },
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::ChannelBinding do
1
+ RSpec.describe Net::NTLM::ChannelBinding do
4
2
  let(:certificates_path) { 'spec/support/certificates' }
5
3
  let(:sha_256_path) { File.join(certificates_path, 'sha_256_hash.pem') }
6
4
  let(:sha_256_cert) { OpenSSL::X509::Certificate.new(File.read(sha_256_path)) }
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::Client::Session do
1
+ RSpec.describe Net::NTLM::Client::Session do
4
2
  let(:t2_challenge) { Net::NTLM::Message.decode64 "TlRMTVNTUAACAAAADAAMADgAAAA1goriAAyk1DmJUnUAAAAAAAAAAFAAUABEAAAABgLwIwAAAA9TAEUAUgBWAEUAUgACAAwAUwBFAFIAVgBFAFIAAQAMAFMARQBSAFYARQBSAAQADABzAGUAcgB2AGUAcgADAAwAcwBlAHIAdgBlAHIABwAIADd7mrNaB9ABAAAAAA==" }
5
3
  let(:inst) { Net::NTLM::Client::Session.new(nil, t2_challenge) }
6
4
  let(:user_session_key) {["3c4918ff0b33e2603e5d7ceaf34bb7d5"].pack("H*")}
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::Client do
1
+ RSpec.describe Net::NTLM::Client do
4
2
  let(:inst) { Net::NTLM::Client.new("test", "test01", :workstation => "testhost") }
5
3
  let(:user_session_key) {["3c4918ff0b33e2603e5d7ceaf34bb7d5"].pack("H*")}
6
4
 
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::EncodeUtil do
1
+ RSpec.describe Net::NTLM::EncodeUtil do
4
2
 
5
3
  context '#encode_utf16le' do
6
4
  it 'should convert an ASCII string to UTF' do
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::FieldSet do
1
+ RSpec.describe Net::NTLM::FieldSet do
4
2
 
5
3
  fields = []
6
4
 
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::Field do
1
+ RSpec.describe Net::NTLM::Field do
4
2
 
5
3
  it_behaves_like 'a field', 'Foo', false
6
4
 
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::Int16LE do
1
+ RSpec.describe Net::NTLM::Int16LE do
4
2
 
5
3
  int_values = {
6
4
  :default => 15,
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::Int32LE do
1
+ RSpec.describe Net::NTLM::Int32LE do
4
2
 
5
3
  int_values = {
6
4
  :default => 252716124,
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::Int64LE do
1
+ RSpec.describe Net::NTLM::Int64LE do
4
2
 
5
3
  int_values = {
6
4
  :default => 5294967295,
@@ -0,0 +1,16 @@
1
+ RSpec.describe Net::NTLM::Md4 do
2
+ describe '.digest' do
3
+ it 'hashes binary input containing high bytes' do
4
+ # Independently calculated with OpenSSL's legacy MD4 provider.
5
+ expect(described_class.digest("\xff".b).unpack('H*').first).
6
+ to eq('82c167af8e345bd055487af8d2b540c9')
7
+ end
8
+
9
+ it 'preserves the caller input and encoding' do
10
+ input = "\xff".b.freeze
11
+ described_class.digest(input)
12
+ expect(input).to eq("\xff".b)
13
+ expect(input.encoding).to eq(Encoding::ASCII_8BIT)
14
+ end
15
+ end
16
+ end
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::Message::Type0 do
1
+ RSpec.describe Net::NTLM::Message::Type0 do
4
2
 
5
3
  fields = [
6
4
  { :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::Message::Type1 do
1
+ RSpec.describe Net::NTLM::Message::Type1 do
4
2
  fields = [
5
3
  { :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
6
4
  { :name => :type, :class => Net::NTLM::Int32LE, :value => 1, :active => true },
@@ -1,7 +1,6 @@
1
1
  # encoding: UTF-8
2
- require 'spec_helper'
3
2
 
4
- describe Net::NTLM::Message::Type2 do
3
+ RSpec.describe Net::NTLM::Message::Type2 do
5
4
 
6
5
  fields = [
7
6
  { :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::Message::Type3 do
1
+ RSpec.describe Net::NTLM::Message::Type3 do
4
2
 
5
3
  fields = [
6
4
  { :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
@@ -99,6 +97,10 @@ describe Net::NTLM::Message::Type3 do
99
97
  end
100
98
  end
101
99
 
100
+ it 'rejects a non-empty password for an empty-password response' do
101
+ expect(message.password?('test1234', server_challenge)).to be false
102
+ end
103
+
102
104
  describe '#ntlm_version' do
103
105
  let(:ver) { message.ntlm_version }
104
106
  it 'should be :ntlmv2' do
@@ -172,6 +174,22 @@ describe Net::NTLM::Message::Type3 do
172
174
 
173
175
  # http://davenport.sourceforge.net/ntlm.html#appendixC9
174
176
  context 'NTLMv2 Authentication; NTLM1 Signing and Sealing Using the 40-bit NTLMv2 User Session Key' do
177
+ let(:server_challenge) { ['0033b02d17275b77'].pack('H*') }
178
+
179
+ describe '#password?' do
180
+ it 'accepts the known fixture password' do
181
+ expect(message.password?('test1234', server_challenge)).to be true
182
+ end
183
+
184
+ it 'rejects an incorrect password' do
185
+ expect(message.password?('wrong', server_challenge)).to be false
186
+ end
187
+
188
+ it 'rejects an empty password' do
189
+ expect(message.blank_password?(server_challenge)).to be false
190
+ end
191
+ end
192
+
175
193
  let(:data) do
176
194
  [
177
195
  '4e544c4d5353500003000000180018006000000076007600780000000c000c00' \
@@ -222,6 +240,57 @@ describe Net::NTLM::Message::Type3 do
222
240
 
223
241
  end
224
242
 
243
+ describe '#password? with serialized NTLMv2 responses' do
244
+ let(:type2) do
245
+ Net::NTLM::Message::Type2.new.tap do |message|
246
+ message.challenge = 0x0123456789abcdef
247
+ end
248
+ end
249
+ let(:server_challenge) { Net::NTLM.pack_int64le(type2.challenge) }
250
+ subject(:message) do
251
+ described_class.parse(type2.response(
252
+ { :user => 'victim', :domain => 'CORP', :password => password },
253
+ { :ntlmv2 => true, :client_challenge => 0x1122334455667788, :timestamp => 0 }
254
+ ).serialize)
255
+ end
256
+
257
+ ['secret', 'odd', "p\u00e4ss\u5bc6\u7801\u{1f512}", ''].each do |password|
258
+ context "with password #{password.inspect}" do
259
+ let(:password) { password }
260
+
261
+ it 'accepts the password used to generate the response' do
262
+ expect(message.password?(password, server_challenge)).to be true
263
+ end
264
+
265
+ it 'rejects a different non-empty password' do
266
+ expect(message.password?('incorrect', server_challenge)).to be false
267
+ end
268
+
269
+ it 'recognizes only an empty password as blank' do
270
+ expect(message.blank_password?(server_challenge)).to eq(password.empty?)
271
+ end
272
+
273
+ it 'rejects a different server challenge' do
274
+ expect(message.password?(password, "\x00" * 8)).to be false
275
+ end
276
+
277
+ it 'accepts an integer server challenge' do
278
+ expect(message.password?(password, type2.challenge)).to be true
279
+ end
280
+
281
+ it 'rejects a modified proof' do
282
+ message.ntlm_response.setbyte(0, message.ntlm_response.getbyte(0) ^ 1)
283
+ expect(message.password?(password, server_challenge)).to be false
284
+ end
285
+
286
+ it 'rejects a modified blob' do
287
+ message.ntlm_response.setbyte(24, message.ntlm_response.getbyte(24) ^ 1)
288
+ expect(message.password?(password, server_challenge)).to be false
289
+ end
290
+ end
291
+ end
292
+ end
293
+
225
294
  describe '#serialize' do
226
295
  context 'when the username contains non-ASCI characters' do
227
296
  let(:t3) {
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::Message do
1
+ RSpec.describe Net::NTLM::Message do
4
2
 
5
3
  fields = []
6
4
  flags = [
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::SecurityBuffer do
1
+ RSpec.describe Net::NTLM::SecurityBuffer do
4
2
 
5
3
  fields = [
6
4
  { :name => :length, :class => Net::NTLM::Int16LE, :value => 0, :active => true },
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::String do
1
+ RSpec.describe Net::NTLM::String do
4
2
 
5
3
  it_behaves_like 'a field', 'Foo', false
6
4
 
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::TargetInfo do
1
+ RSpec.describe Net::NTLM::TargetInfo do
4
2
  let(:key1) { Net::NTLM::TargetInfo::MSV_AV_NB_COMPUTER_NAME }
5
3
  let(:value1) { 'some data' }
6
4
  let(:key2) { Net::NTLM::TargetInfo::MSV_AV_NB_DOMAIN_NAME }
@@ -1,7 +1,6 @@
1
- require 'spec_helper'
2
1
  require File.expand_path("#{File.dirname(__FILE__)}/../../../../lib/net/ntlm/version")
3
2
 
4
- describe Net::NTLM::VERSION do
3
+ RSpec.describe Net::NTLM::VERSION do
5
4
 
6
5
  it 'should contain an integer value for Major Version' do
7
6
  expect(Net::NTLM::VERSION::MAJOR).to be_an Integer
@@ -1,6 +1,4 @@
1
- require "spec_helper"
2
-
3
- describe Net::NTLM do
1
+ RSpec.describe Net::NTLM do
4
2
  let(:passwd) {"SecREt01"}
5
3
  let(:user) {"user"}
6
4
  let(:domain) {"DOMAIN"}
data/spec/spec_helper.rb CHANGED
@@ -1,22 +1,51 @@
1
- require 'simplecov'
2
- require 'pathname'
1
+ # Coverage must be started before the library under test is loaded, otherwise
2
+ # methods defined at require time are not tracked.
3
+ if ENV['COVERAGE']
4
+ require 'simplecov'
3
5
 
4
- SimpleCov.start do
5
- add_filter '/spec/'
6
- add_filter '/config/'
7
- add_filter '/vendor/'
8
- end if ENV["COVERAGE"]
6
+ SimpleCov.start do
7
+ add_filter '/spec/'
8
+ add_filter '/vendor/'
9
+ enable_coverage :branch if respond_to?(:enable_coverage)
10
+ end
11
+ end
9
12
 
10
13
  require 'rspec'
11
14
  require 'net/ntlm'
12
15
 
13
- # add project lib directory to load path
14
- spec_pathname = Pathname.new(__FILE__).dirname
15
- root_pathname = spec_pathname.join('..').expand_path
16
- # Requires supporting ruby files with custom matchers and macros, etc,
17
- # in spec/support/ and its subdirectories.
18
- support_glob = root_pathname.join('spec', 'support', '**', '*.rb')
16
+ # Custom matchers, shared examples and other support code.
17
+ Dir[File.expand_path('support/**/*.rb', __dir__)].sort.each { |path| require path }
18
+
19
+ RSpec.configure do |config|
20
+ # Require `RSpec.describe` rather than a top-level `describe`, so the gem's
21
+ # specs do not depend on RSpec monkey-patching Object.
22
+ config.disable_monkey_patching!
23
+
24
+ config.expect_with :rspec do |expectations|
25
+ expectations.syntax = :expect
26
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
27
+ end
28
+
29
+ config.mock_with :rspec do |mocks|
30
+ mocks.syntax = :expect
31
+ # Fail fast when a partial double stubs a method the real object does not
32
+ # have, so refactors in lib/ cannot leave specs passing against a fiction.
33
+ mocks.verify_partial_doubles = true
34
+ end
35
+
36
+ # Shared example groups get their own metadata rather than leaking it into
37
+ # the host group. This is the RSpec 4 default.
38
+ config.shared_context_metadata_behavior = :apply_to_host_groups
39
+
40
+ # `rspec --only-failures` and `--next-failure`.
41
+ config.example_status_persistence_file_path = 'spec/examples.txt'
42
+
43
+ # Tagging an example `:focus` runs just that example, without needing to pass
44
+ # a line number. No effect when nothing is tagged.
45
+ config.filter_run_when_matching :focus
19
46
 
20
- Dir.glob(support_glob) do |path|
21
- require path
47
+ # Randomise ordering to surface accidental dependencies between examples, and
48
+ # print the seed so a failure can be reproduced with `--seed`.
49
+ config.order = :random
50
+ Kernel.srand config.seed
22
51
  end
@@ -1,4 +1,4 @@
1
- shared_examples_for 'a field' do | value, active|
1
+ RSpec.shared_examples_for 'a field' do | value, active|
2
2
 
3
3
  subject do
4
4
  described_class.new({
@@ -1,4 +1,4 @@
1
- shared_examples_for 'a fieldset' do |fields|
1
+ RSpec.shared_examples_for 'a fieldset' do |fields|
2
2
 
3
3
  subject(:fieldset_class) do
4
4
  Class.new(described_class)
@@ -1,4 +1,4 @@
1
- shared_examples_for 'an integer field' do |values|
1
+ RSpec.shared_examples_for 'an integer field' do |values|
2
2
 
3
3
  subject do
4
4
  described_class.new({
@@ -1,4 +1,4 @@
1
- shared_examples_for 'a message' do |flags|
1
+ RSpec.shared_examples_for 'a message' do |flags|
2
2
 
3
3
  subject(:test_message) do
4
4
  unless described_class.names.include?(:flag)
metadata CHANGED
@@ -1,86 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyntlm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.6.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kohei Kajimoto
8
8
  - Paul Morton
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-06-12 00:00:00.000000000 Z
12
+ date: 2026-09-09 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: github_changelog_generator
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - '='
19
- - !ruby/object:Gem::Version
20
- version: 1.14.3
21
- type: :development
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - '='
26
- - !ruby/object:Gem::Version
27
- version: 1.14.3
28
- - !ruby/object:Gem::Dependency
29
- name: pry
30
- requirement: !ruby/object:Gem::Requirement
31
- requirements:
32
- - - ">="
33
- - !ruby/object:Gem::Version
34
- version: '0'
35
- type: :development
36
- prerelease: false
37
- version_requirements: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- version: '0'
42
- - !ruby/object:Gem::Dependency
43
- name: rake
44
- requirement: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: '0'
49
- type: :development
50
- prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: '0'
56
- - !ruby/object:Gem::Dependency
57
- name: rspec
58
- requirement: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: '2.11'
63
- type: :development
64
- prerelease: false
65
- version_requirements: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- version: '2.11'
70
- - !ruby/object:Gem::Dependency
71
- name: simplecov
72
- requirement: !ruby/object:Gem::Requirement
73
- requirements:
74
- - - ">="
75
- - !ruby/object:Gem::Version
76
- version: '0'
77
- type: :development
78
- prerelease: false
79
- version_requirements: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- version: '0'
84
14
  - !ruby/object:Gem::Dependency
85
15
  name: base64
86
16
  requirement: !ruby/object:Gem::Requirement
@@ -151,6 +81,7 @@ files:
151
81
  - spec/lib/net/ntlm/int16_le_spec.rb
152
82
  - spec/lib/net/ntlm/int32_le_spec.rb
153
83
  - spec/lib/net/ntlm/int64_le_spec.rb
84
+ - spec/lib/net/ntlm/md4_spec.rb
154
85
  - spec/lib/net/ntlm/message/type0_spec.rb
155
86
  - spec/lib/net/ntlm/message/type1_spec.rb
156
87
  - spec/lib/net/ntlm/message/type2_spec.rb
@@ -172,7 +103,10 @@ licenses:
172
103
  - MIT
173
104
  metadata:
174
105
  rubygems_mfa_required: 'true'
175
- post_install_message:
106
+ source_code_uri: https://github.com/winrb/rubyntlm
107
+ changelog_uri: https://github.com/winrb/rubyntlm/blob/master/CHANGELOG.md
108
+ bug_tracker_uri: https://github.com/winrb/rubyntlm/issues
109
+ post_install_message:
176
110
  rdoc_options: []
177
111
  require_paths:
178
112
  - lib
@@ -180,41 +114,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
180
114
  requirements:
181
115
  - - ">="
182
116
  - !ruby/object:Gem::Version
183
- version: 2.6.0
117
+ version: 3.0.0
184
118
  required_rubygems_version: !ruby/object:Gem::Requirement
185
119
  requirements:
186
120
  - - ">="
187
121
  - !ruby/object:Gem::Version
188
122
  version: '0'
189
123
  requirements: []
190
- rubygems_version: 3.5.3
191
- signing_key:
124
+ rubygems_version: 3.4.19
125
+ signing_key:
192
126
  specification_version: 4
193
127
  summary: Ruby/NTLM library.
194
- test_files:
195
- - spec/lib/net/ntlm/blob_spec.rb
196
- - spec/lib/net/ntlm/channel_binding_spec.rb
197
- - spec/lib/net/ntlm/client/session_spec.rb
198
- - spec/lib/net/ntlm/client_spec.rb
199
- - spec/lib/net/ntlm/encode_util_spec.rb
200
- - spec/lib/net/ntlm/field_set_spec.rb
201
- - spec/lib/net/ntlm/field_spec.rb
202
- - spec/lib/net/ntlm/int16_le_spec.rb
203
- - spec/lib/net/ntlm/int32_le_spec.rb
204
- - spec/lib/net/ntlm/int64_le_spec.rb
205
- - spec/lib/net/ntlm/message/type0_spec.rb
206
- - spec/lib/net/ntlm/message/type1_spec.rb
207
- - spec/lib/net/ntlm/message/type2_spec.rb
208
- - spec/lib/net/ntlm/message/type3_spec.rb
209
- - spec/lib/net/ntlm/message_spec.rb
210
- - spec/lib/net/ntlm/security_buffer_spec.rb
211
- - spec/lib/net/ntlm/string_spec.rb
212
- - spec/lib/net/ntlm/target_info_spec.rb
213
- - spec/lib/net/ntlm/version_spec.rb
214
- - spec/lib/net/ntlm_spec.rb
215
- - spec/spec_helper.rb
216
- - spec/support/certificates/sha_256_hash.pem
217
- - spec/support/shared/examples/net/ntlm/field_shared.rb
218
- - spec/support/shared/examples/net/ntlm/fieldset_shared.rb
219
- - spec/support/shared/examples/net/ntlm/int_shared.rb
220
- - spec/support/shared/examples/net/ntlm/message_shared.rb
128
+ test_files: []