rkerberos 0.2.1 → 0.2.3

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.
data/spec/kadm5_spec.rb CHANGED
@@ -1,12 +1,14 @@
1
1
  # spec/kadm5_spec.rb
2
2
  # RSpec tests for Kerberos::Kadm5
3
3
 
4
- require 'rkerberos'
4
+ require 'spec_helper'
5
5
  require 'socket'
6
6
 
7
- RSpec.describe Kerberos::Kadm5 do
7
+ RSpec.describe 'Kerberos::Kadm5', :kadm5 do
8
+ let(:server){ Kerberos::Kadm5::Config.new.admin_server }
9
+ subject(:klass){ Kerberos::Kadm5 }
10
+
8
11
  before(:all) do
9
- @server = Kerberos::Kadm5::Config.new.admin_server
10
12
  @host = Socket.gethostname
11
13
  @user = ENV['KRB5_ADMIN_PRINCIPAL']
12
14
  @pass = ENV['KRB5_ADMIN_PASSWORD']
@@ -23,40 +25,79 @@ RSpec.describe Kerberos::Kadm5 do
23
25
 
24
26
  describe 'constructor' do
25
27
  it 'responds to .new' do
26
- expect(described_class).to respond_to(:new)
28
+ expect(subject).to respond_to(:new)
27
29
  end
28
30
  it 'works with valid user and password' do
29
- expect { described_class.new(principal: user, password: pass) }.not_to raise_error
31
+ expect { subject.new(principal: user, password: pass) }.not_to raise_error
30
32
  end
31
33
  it 'works with valid service' do
32
34
  expect {
33
- described_class.new(principal: user, password: pass, service: 'kadmin/admin')
35
+ subject.new(principal: user, password: pass, service: 'kadmin/admin')
34
36
  }.not_to raise_error
35
37
  end
36
38
  it 'only accepts a hash argument' do
37
- expect { described_class.new(user) }.to raise_error(TypeError)
38
- expect { described_class.new(1) }.to raise_error(TypeError)
39
+ expect { subject.new(user) }.to raise_error(TypeError)
40
+ expect { subject.new(1) }.to raise_error(TypeError)
39
41
  end
40
42
  it 'accepts a block and yields itself' do
41
- expect { described_class.new(principal: user, password: pass) {} }.not_to raise_error
42
- described_class.new(principal: user, password: pass) { |kadm5| expect(kadm5).to be_a(described_class) }
43
+ expect { subject.new(principal: user, password: pass) {} }.not_to raise_error
44
+ subject.new(principal: user, password: pass) { |kadm5| expect(kadm5).to be_a(subject) }
43
45
  end
44
46
  it 'requires principal to be specified' do
45
- expect { described_class.new({}) }.to raise_error(ArgumentError)
47
+ expect { subject.new({}) }.to raise_error(ArgumentError)
46
48
  end
47
49
  it 'requires principal to be a string' do
48
- expect { described_class.new(principal: 1) }.to raise_error(TypeError)
50
+ expect { subject.new(principal: 1) }.to raise_error(TypeError)
49
51
  end
50
52
  it 'requires password to be a string' do
51
- expect { described_class.new(principal: user, password: 1) }.to raise_error(TypeError)
53
+ expect { subject.new(principal: user, password: 1) }.to raise_error(TypeError)
52
54
  end
53
55
  it 'requires keytab to be a string or boolean' do
54
- expect { described_class.new(principal: user, keytab: 1) }.to raise_error(TypeError)
56
+ expect { subject.new(principal: user, keytab: 1) }.to raise_error(TypeError)
55
57
  end
56
58
  it 'requires service to be a string' do
57
- expect { described_class.new(principal: user, password: pass, service: 1) }.to raise_error(TypeError)
59
+ expect { subject.new(principal: user, password: pass, service: 1) }.to raise_error(TypeError)
58
60
  end
59
61
  end
60
62
 
61
- # ... (Due to length, only a representative subset of tests is shown. The rest should be ported similarly.)
63
+ describe '#get_privileges' do
64
+ before(:each) do
65
+ @kadm5 = subject.new(principal: user, password: pass)
66
+ end
67
+
68
+ after(:each) do
69
+ @kadm5.close
70
+ end
71
+
72
+ it 'returns an integer bitmask by default' do
73
+ result = @kadm5.get_privileges
74
+ expect(result).to be_a(Integer)
75
+ expect(result).not_to eq(0)
76
+ end
77
+
78
+ it 'returns an array of strings when passed a truthy argument' do
79
+ result = @kadm5.get_privileges(true)
80
+ expect(result).to be_a(Array)
81
+ expect(result).not_to be_empty
82
+ expect(result).to all(be_a(String))
83
+ end
84
+
85
+ it 'only contains valid privilege names' do
86
+ result = @kadm5.get_privileges(true)
87
+ valid = %w[GET ADD MODIFY DELETE]
88
+ result.each do |priv|
89
+ expect(valid).to include(priv)
90
+ end
91
+ end
92
+
93
+ it 'does not contain UNKNOWN entries' do
94
+ result = @kadm5.get_privileges(true)
95
+ expect(result).not_to include('UNKNOWN')
96
+ end
97
+
98
+ it 'includes GET for an admin principal' do
99
+ result = @kadm5.get_privileges(true)
100
+ expect(result).to include('GET')
101
+ end
102
+ end
62
103
  end
@@ -4,12 +4,13 @@
4
4
  require 'rkerberos'
5
5
  require 'tmpdir'
6
6
  require 'fileutils'
7
- require 'pty'
8
- require 'expect'
9
-
10
7
 
8
+ unless File::ALT_SEPARATOR
9
+ require 'pty'
10
+ require 'expect'
11
+ end
11
12
 
12
- RSpec.describe Kerberos::Krb5::Keytab do
13
+ RSpec.describe Kerberos::Krb5::Keytab, :kadm5 do
13
14
  before(:all) do
14
15
  @realm = Kerberos::Kadm5::Config.new.realm
15
16
  @keytab_file = File.join(Dir.tmpdir, 'test.keytab')
@@ -29,6 +30,10 @@ RSpec.describe Kerberos::Krb5::Keytab do
29
30
  end
30
31
  end
31
32
 
33
+ after(:all) do
34
+ FileUtils.rm_f(@keytab_file)
35
+ end
36
+
32
37
  subject(:keytab) { described_class.new }
33
38
 
34
39
  describe 'constructor' do
@@ -43,4 +48,195 @@ RSpec.describe Kerberos::Krb5::Keytab do
43
48
  }.to raise_error(Kerberos::Krb5::Keytab::Exception)
44
49
  end
45
50
  end
51
+
52
+ describe '#keytab_name and #keytab_type' do
53
+ it 'returns the underlying name and type strings' do
54
+ kt = described_class.new(@keytab_name)
55
+ expect(kt).to respond_to(:keytab_name)
56
+ expect(kt).to respond_to(:keytab_type)
57
+
58
+ expect(kt.keytab_name).to be_a(String)
59
+ expect(kt.keytab_type).to be_a(String)
60
+
61
+ # name should include the residual portion we supplied
62
+ expect(kt.keytab_name).to include(File.basename(@keytab_file))
63
+ # type should match the scheme
64
+ expect(kt.keytab_type.downcase).to eq("file")
65
+ end
66
+ end
67
+
68
+ describe '#close' do
69
+ it 'returns true' do
70
+ kt = described_class.new(@keytab_name)
71
+ expect(kt.close).to eq(true)
72
+ end
73
+
74
+ it 'can be called multiple times without error' do
75
+ kt = described_class.new(@keytab_name)
76
+ kt.close
77
+ expect { kt.close }.not_to raise_error
78
+ end
79
+
80
+ it 'raises an error when calling keytab_name after close' do
81
+ kt = described_class.new(@keytab_name)
82
+ kt.close
83
+ expect { kt.keytab_name }.to raise_error(Kerberos::Krb5::Exception)
84
+ end
85
+
86
+ it 'raises an error when calling keytab_type after close' do
87
+ kt = described_class.new(@keytab_name)
88
+ kt.close
89
+ expect { kt.keytab_type }.to raise_error(Kerberos::Krb5::Exception)
90
+ end
91
+
92
+ it 'does not segfault when garbage collected after close' do
93
+ kt = described_class.new(@keytab_name)
94
+ kt.close
95
+ kt = nil
96
+ GC.start
97
+ end
98
+ end
99
+
100
+ describe '.foreach' do
101
+ it 'yields keytab entries for a valid keytab' do
102
+ entries = []
103
+ described_class.foreach(@keytab_name) { |entry| entries << entry }
104
+ expect(entries.length).to eq(2)
105
+ entries.each do |entry|
106
+ expect(entry).to be_a(Kerberos::Krb5::Keytab::Entry)
107
+ expect(entry.principal).to be_a(String)
108
+ expect(entry.principal).to match(/@#{Regexp.quote(@realm)}$/)
109
+ expect(entry.vno).to be_a(Integer)
110
+ expect(entry.timestamp).to be_a(Time)
111
+ expect(entry.key).to be_a(Integer)
112
+ end
113
+ end
114
+
115
+ it 'uses the default keytab when no name is provided' do
116
+ # The default keytab may not exist in the test container, so we
117
+ # just verify it attempts to use it (raises keytab-related error
118
+ # rather than ArgumentError or similar).
119
+ begin
120
+ described_class.foreach { |_| }
121
+ rescue Kerberos::Krb5::Exception
122
+ # Expected when default keytab is absent
123
+ end
124
+ end
125
+
126
+ it 'raises an error for a non-existent keytab file' do
127
+ expect {
128
+ described_class.foreach("FILE:/no/such/keytab") { |_| }
129
+ }.to raise_error(Kerberos::Krb5::Exception)
130
+ end
131
+
132
+ it 'raises an error for an invalid keytab type' do
133
+ expect {
134
+ described_class.foreach("BOGUS:/tmp/keytab") { |_| }
135
+ }.to raise_error(Kerberos::Krb5::Exception)
136
+ end
137
+
138
+ it 'does not leak resources when the block raises' do
139
+ expect {
140
+ described_class.foreach(@keytab_name) { |_| raise "boom" }
141
+ }.to raise_error(RuntimeError, "boom")
142
+ end
143
+
144
+ it 'does not leak resources when the block breaks' do
145
+ result = catch(:done) do
146
+ described_class.foreach(@keytab_name) { |_| throw :done, :escaped }
147
+ :completed
148
+ end
149
+ expect(result).to eq(:escaped)
150
+ end
151
+ end
152
+
153
+ describe '#each' do
154
+ it 'yields keytab entries for a valid keytab' do
155
+ kt = described_class.new(@keytab_name)
156
+ entries = []
157
+ kt.each { |entry| entries << entry }
158
+ expect(entries.length).to eq(2)
159
+ entries.each do |entry|
160
+ expect(entry).to be_a(Kerberos::Krb5::Keytab::Entry)
161
+ expect(entry.principal).to be_a(String)
162
+ expect(entry.vno).to be_a(Integer)
163
+ expect(entry.timestamp).to be_a(Time)
164
+ expect(entry.key).to be_a(Integer)
165
+ end
166
+ end
167
+
168
+ it 'does not leak resources when the block raises' do
169
+ kt = described_class.new(@keytab_name)
170
+ expect {
171
+ kt.each { |_| raise "boom" }
172
+ }.to raise_error(RuntimeError, "boom")
173
+ end
174
+
175
+ it 'does not leak resources when the block breaks' do
176
+ kt = described_class.new(@keytab_name)
177
+ result = catch(:done) do
178
+ kt.each { |_| throw :done, :escaped }
179
+ :completed
180
+ end
181
+ expect(result).to eq(:escaped)
182
+ end
183
+ end
184
+
185
+ describe '#get_entry' do
186
+ it 'finds an entry by principal name' do
187
+ kt = described_class.new(@keytab_name)
188
+ entry = kt.get_entry("testuser1@#{@realm}")
189
+ expect(entry).to be_a(Kerberos::Krb5::Keytab::Entry)
190
+ expect(entry.principal).to eq("testuser1@#{@realm}")
191
+ expect(entry.vno).to eq(1)
192
+ expect(entry.timestamp).to be_a(Time)
193
+ expect(entry.key).to be_a(Integer)
194
+ end
195
+
196
+ it 'finds an entry filtering by vno' do
197
+ kt = described_class.new(@keytab_name)
198
+ entry = kt.get_entry("testuser1@#{@realm}", 1)
199
+ expect(entry.principal).to eq("testuser1@#{@realm}")
200
+ expect(entry.vno).to eq(1)
201
+ end
202
+
203
+ it 'finds an entry filtering by vno and enctype' do
204
+ kt = described_class.new(@keytab_name)
205
+ # aes128-cts-hmac-sha1-96 is enctype 17
206
+ entry = kt.get_entry("testuser1@#{@realm}", 1, 17)
207
+ expect(entry.principal).to eq("testuser1@#{@realm}")
208
+ expect(entry.vno).to eq(1)
209
+ expect(entry.key).to eq(17)
210
+ end
211
+
212
+ it 'raises an error for a non-existent principal' do
213
+ kt = described_class.new(@keytab_name)
214
+ expect {
215
+ kt.get_entry("bogus@#{@realm}")
216
+ }.to raise_error(Kerberos::Krb5::Exception)
217
+ end
218
+
219
+ it 'is aliased as find' do
220
+ kt = described_class.new(@keytab_name)
221
+ expect(kt.method(:find)).to eq(kt.method(:get_entry))
222
+ end
223
+ end
224
+
225
+ describe '#dup' do
226
+ it 'creates an independent handle referring to same keytab' do
227
+ kt1 = described_class.new(@keytab_name)
228
+ kt2 = kt1.dup
229
+ expect(kt2).to be_a(described_class)
230
+ expect(kt2.keytab_name).to eq(kt1.keytab_name)
231
+
232
+ # closing one should not invalidate the other
233
+ kt1.close
234
+ expect { kt2.keytab_name }.not_to raise_error
235
+ end
236
+
237
+ it 'clone is an alias for dup' do
238
+ kt = described_class.new(@keytab_name)
239
+ expect(kt.method(:clone)).to eq(kt.method(:dup))
240
+ end
241
+ end
46
242
  end
data/spec/krb5_spec.rb CHANGED
@@ -1,18 +1,20 @@
1
1
  # spec/krb5_spec.rb
2
2
  # RSpec tests for Kerberos::Krb5
3
3
 
4
- require 'rkerberos'
4
+ require 'spec_helper'
5
5
  require 'open3'
6
- require 'pty'
7
- require 'expect'
6
+
7
+ unless File::ALT_SEPARATOR
8
+ require 'pty'
9
+ require 'expect'
10
+ end
8
11
 
9
12
  RSpec.describe Kerberos::Krb5 do
10
13
  before(:all) do
14
+ krb5_conf = RSpec.configuration.krb5_conf
11
15
  @cache_found = true
12
16
  Open3.popen3('klist') { |_, _, stderr| @cache_found = false unless stderr.gets.nil? }
13
- @krb5_conf = ENV['KRB5_CONFIG'] || '/etc/krb5.conf'
14
- @realm = IO.read(@krb5_conf).split("\n").grep(/default_realm/).first.split('=').last.lstrip.chomp
15
-
17
+ @realm = IO.read(krb5_conf).split("\n").grep(/default_realm/).first.split('=').last.lstrip.chomp
16
18
  end
17
19
 
18
20
  subject(:krb5) { described_class.new }
@@ -21,7 +23,7 @@ RSpec.describe Kerberos::Krb5 do
21
23
  let(:service) { 'kadmin/admin' }
22
24
 
23
25
  it 'has the correct version constant' do
24
- expect(Kerberos::Krb5::VERSION).to eq('0.2.1')
26
+ expect(Kerberos::Krb5::VERSION).to eq('0.2.3')
25
27
  end
26
28
 
27
29
  it 'accepts a block and yields itself' do
@@ -48,7 +50,7 @@ RSpec.describe Kerberos::Krb5 do
48
50
  end
49
51
  end
50
52
 
51
- describe '#verify_init_creds' do
53
+ describe '#verify_init_creds', :kadm5 do
52
54
  # Some KDC setups may not correctly set the initial password during
53
55
  # entrypoint startup; enforce it here via the admin API so the test is
54
56
  # deterministic.
@@ -116,7 +118,77 @@ RSpec.describe Kerberos::Krb5 do
116
118
  end
117
119
  end
118
120
 
119
- describe '#get_init_creds_keytab' do
121
+ describe '#change_password', :kadm5 do
122
+ before do
123
+ # Ensure testuser1 has a known password before each test.
124
+ Kerberos::Kadm5.new(
125
+ principal: ENV.fetch('KRB5_ADMIN_PRINCIPAL', 'admin/admin@EXAMPLE.COM'),
126
+ password: ENV.fetch('KRB5_ADMIN_PASSWORD', 'adminpassword')
127
+ ) do |kadmin|
128
+ kadmin.set_password(user, 'changeme')
129
+ end
130
+ end
131
+
132
+ after do
133
+ # Reset to known password so later tests are not affected.
134
+ Kerberos::Kadm5.new(
135
+ principal: ENV.fetch('KRB5_ADMIN_PRINCIPAL', 'admin/admin@EXAMPLE.COM'),
136
+ password: ENV.fetch('KRB5_ADMIN_PASSWORD', 'adminpassword')
137
+ ) do |kadmin|
138
+ kadmin.set_password(user, 'changeme')
139
+ end
140
+ end
141
+
142
+ it 'responds to change_password' do
143
+ expect(krb5).to respond_to(:change_password)
144
+ end
145
+
146
+ it 'requires exactly two arguments' do
147
+ expect { krb5.change_password }.to raise_error(ArgumentError)
148
+ expect { krb5.change_password('old') }.to raise_error(ArgumentError)
149
+ expect { krb5.change_password('old', 'new', 'extra') }.to raise_error(ArgumentError)
150
+ end
151
+
152
+ it 'raises if no principal has been established' do
153
+ expect { krb5.change_password('changeme', 'newpass1A!') }.to raise_error(Kerberos::Krb5::Exception, /no principal/)
154
+ end
155
+
156
+ it 'changes the password successfully' do
157
+ krb5.get_init_creds_password(user, 'changeme')
158
+ expect(krb5.change_password('changeme', 'Newpass99!')).to be true
159
+ # Verify we can authenticate with the new password
160
+ krb5_check = described_class.new
161
+ expect(krb5_check.get_init_creds_password(user, 'Newpass99!')).to be true
162
+ krb5_check.close
163
+ end
164
+
165
+ it 'raises with a meaningful message when the old password is wrong' do
166
+ krb5.get_init_creds_password(user, 'changeme')
167
+ expect {
168
+ krb5.change_password('wrongpass', 'Newpass99!')
169
+ }.to raise_error(Kerberos::Krb5::Exception, /krb5_(get_init_creds_password|change_password)/)
170
+ end
171
+
172
+ it 'requires string arguments' do
173
+ expect { krb5.change_password(1, 'new') }.to raise_error(TypeError)
174
+ expect { krb5.change_password('old', 1) }.to raise_error(TypeError)
175
+ end
176
+
177
+ context 'when the KDC rejects the new password due to policy' do
178
+ let(:policy_user) { "policyuser@#{@realm}" }
179
+ # Password must satisfy strict_policy (minlength=8, minclasses=3).
180
+ let(:compliant_pw) { 'Changeme1!' }
181
+
182
+ it 'raises an exception with the KDC rejection reason' do
183
+ krb5.get_init_creds_password(policy_user, compliant_pw)
184
+ expect {
185
+ krb5.change_password(compliant_pw, 'a')
186
+ }.to raise_error(Kerberos::Krb5::Exception, /krb5_change_password/)
187
+ end
188
+ end
189
+ end
190
+
191
+ describe '#get_init_creds_keytab', :unix do
120
192
  before(:each) do
121
193
  @kt_file = File.join(Dir.tmpdir, "test_get_init_creds_#{Process.pid}_#{rand(10000)}.keytab")
122
194
 
data/spec/policy_spec.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  # spec/policy_spec.rb
2
2
  # RSpec tests for Kerberos::Kadm5::Policy
3
3
 
4
- require 'rkerberos'
4
+ require 'spec_helper'
5
5
 
6
- RSpec.describe Kerberos::Kadm5::Policy do
7
- subject(:policy) { described_class.new(name: 'test', max_life: 10000) }
6
+ RSpec.describe 'Kerberos::Kadm5::Policy', :kadm5 do
7
+ subject(:klass){ Kerberos::Kadm5::Policy }
8
+ let(:policy) { klass.new(name: 'test', max_life: 10000) }
8
9
 
9
10
  describe 'name' do
10
11
  it 'responds to policy' do
@@ -15,10 +16,10 @@ RSpec.describe Kerberos::Kadm5::Policy do
15
16
  expect(policy.method(:name)).to eq(policy.method(:policy))
16
17
  end
17
18
  it 'must be a string' do
18
- expect { described_class.new(name: 1) }.to raise_error(TypeError)
19
+ expect { klass.new(name: 1) }.to raise_error(TypeError)
19
20
  end
20
21
  it 'must be present' do
21
- expect { described_class.new(max_life: 10000) }.to raise_error(ArgumentError)
22
+ expect { klass.new(max_life: 10000) }.to raise_error(ArgumentError)
22
23
  end
23
24
  end
24
25
 
@@ -28,7 +29,7 @@ RSpec.describe Kerberos::Kadm5::Policy do
28
29
  expect { policy.min_life }.not_to raise_error
29
30
  end
30
31
  it 'must be a number if not nil' do
31
- expect { described_class.new(name: 'test', min_life: 'test') }.to raise_error(TypeError)
32
+ expect { klass.new(name: 'test', min_life: 'test') }.to raise_error(TypeError)
32
33
  end
33
34
  end
34
35
 
@@ -38,7 +39,7 @@ RSpec.describe Kerberos::Kadm5::Policy do
38
39
  expect { policy.max_life }.not_to raise_error
39
40
  end
40
41
  it 'must be a number if not nil' do
41
- expect { described_class.new(name: 'test', max_life: 'test') }.to raise_error(TypeError)
42
+ expect { klass.new(name: 'test', max_life: 'test') }.to raise_error(TypeError)
42
43
  end
43
44
  end
44
45
 
@@ -12,6 +12,24 @@ RSpec.describe Kerberos::Krb5::Principal do
12
12
  expect { described_class.new(1) }.to raise_error(TypeError)
13
13
  expect { described_class.new(true) }.to raise_error(TypeError)
14
14
  end
15
+
16
+ it 'accepts an explicit nil argument' do
17
+ expect{ described_class.new(nil) }.not_to raise_error
18
+ end
19
+
20
+ it 'works as expected with a nil argument to the constructor' do
21
+ expect(described_class.new(nil).principal).to be_nil
22
+ end
23
+ end
24
+
25
+ describe '#realm' do
26
+ it 'returns the expected value' do
27
+ expect(subject.realm).to eq('EXAMPLE.COM')
28
+ end
29
+
30
+ it 'raises an error if the constructor argument was nil' do
31
+ expect{ described_class.new(nil).realm }.to raise_error(Kerberos::Krb5::Exception, /no principal/)
32
+ end
15
33
  end
16
34
 
17
35
  describe '#name' do
@@ -0,0 +1,34 @@
1
+ require 'rkerberos'
2
+ require 'rspec'
3
+ require 'etc'
4
+ require 'tmpdir'
5
+
6
+ RSpec.configure do |config|
7
+ config.filter_run_excluding :kadm5 => true unless defined?(Kerberos::Kadm5::Config)
8
+ config.filter_run_excluding :unix => true if File::ALT_SEPARATOR
9
+
10
+ krb5_conf = ENV['KRB5_CONFIG']
11
+ krb5_cc_name = ENV['KRB5CCNAME']
12
+ login = Etc.getlogin || ENV['USER'] || (Etc.getpwuid(Process.uid).name rescue nil)
13
+
14
+ if File::ALT_SEPARATOR
15
+ krb5_conf ||= 'C:\\ProgramData\\MIT\\Kerberos5\\krb5.ini'
16
+ krb5_cc_name ||= File.join(ENV['USERPROFILE'], 'krb5cache')
17
+ else
18
+ krb5_conf ||= '/etc/krb5.conf'
19
+ krb5_cc_name ||= File.join(Dir.tmpdir, "krb5cc_#{Etc.getpwnam(login).uid}")
20
+ end
21
+
22
+ config.add_setting :krb5_conf
23
+ config.krb5_conf = krb5_conf
24
+
25
+ config.add_setting :krb5_cc_name
26
+ config.krb5_cc_name = krb5_cc_name
27
+
28
+ config.add_setting :login
29
+ config.login = login
30
+
31
+ unless File.exist?(krb5_conf)
32
+ config.filter_run_excluding :krb5_config => true
33
+ end
34
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rkerberos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Berger
@@ -92,6 +92,7 @@ files:
92
92
  - spec/krb5_spec.rb
93
93
  - spec/policy_spec.rb
94
94
  - spec/principal_spec.rb
95
+ - spec/spec_helper.rb
95
96
  homepage: http://github.com/rkerberos/rkerberos
96
97
  licenses:
97
98
  - Artistic-2.0
@@ -119,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
120
  - !ruby/object:Gem::Version
120
121
  version: '0'
121
122
  requirements: []
122
- rubygems_version: 4.0.3
123
+ rubygems_version: 4.0.6
123
124
  specification_version: 4
124
125
  summary: A Ruby interface for the the Kerberos library
125
126
  test_files: