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.
- checksums.yaml +4 -4
- data/CHANGES.md +28 -8
- data/MANIFEST.md +24 -16
- data/Rakefile +4 -1
- data/ext/rkerberos/ccache.c +98 -1
- data/ext/rkerberos/config.c +10 -7
- data/ext/rkerberos/context.c +6 -0
- data/ext/rkerberos/extconf.rb +16 -3
- data/ext/rkerberos/kadm5.c +97 -45
- data/ext/rkerberos/keytab.c +247 -106
- data/ext/rkerberos/keytab_entry.c +2 -1
- data/ext/rkerberos/principal.c +28 -0
- data/ext/rkerberos/rkerberos.c +91 -13
- data/rkerberos.gemspec +1 -1
- data/spec/config_spec.rb +29 -7
- data/spec/context_spec.rb +6 -7
- data/spec/credentials_cache_spec.rb +79 -12
- data/spec/kadm5_spec.rb +57 -16
- data/spec/krb5_keytab_spec.rb +200 -4
- data/spec/krb5_spec.rb +81 -9
- data/spec/policy_spec.rb +8 -7
- data/spec/principal_spec.rb +18 -0
- data/spec/spec_helper.rb +34 -0
- metadata +3 -2
data/ext/rkerberos/rkerberos.c
CHANGED
|
@@ -100,7 +100,10 @@ static VALUE rkrb5_get_default_realm(VALUE self){
|
|
|
100
100
|
if(kerror)
|
|
101
101
|
rb_raise(cKrb5Exception, "krb5_get_default_realm: %s", error_message(kerror));
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
VALUE v_realm = rb_str_new2(realm);
|
|
104
|
+
krb5_free_default_realm(ptr->ctx, realm);
|
|
105
|
+
|
|
106
|
+
return v_realm;
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
/*
|
|
@@ -164,18 +167,41 @@ static VALUE rkrb5_get_init_creds_keytab(int argc, VALUE* argv, VALUE self){
|
|
|
164
167
|
if(!ptr->ctx)
|
|
165
168
|
rb_raise(cKrb5Exception, "no context has been established");
|
|
166
169
|
|
|
170
|
+
// Free resources from a previous call to avoid leaks on repeated use.
|
|
171
|
+
if(ptr->keytab){
|
|
172
|
+
krb5_kt_close(ptr->ctx, ptr->keytab);
|
|
173
|
+
ptr->keytab = NULL;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if(ptr->princ){
|
|
177
|
+
krb5_free_principal(ptr->ctx, ptr->princ);
|
|
178
|
+
ptr->princ = NULL;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
krb5_free_cred_contents(ptr->ctx, &ptr->creds);
|
|
182
|
+
memset(&ptr->creds, 0, sizeof(ptr->creds));
|
|
183
|
+
|
|
184
|
+
rb_scan_args(argc, argv, "04", &v_user, &v_keytab_name, &v_service, &v_ccache);
|
|
185
|
+
|
|
186
|
+
// Validate argument types before allocating opt, so type errors don't leak it.
|
|
187
|
+
if(!NIL_P(v_user))
|
|
188
|
+
Check_Type(v_user, T_STRING);
|
|
189
|
+
|
|
190
|
+
if(!NIL_P(v_keytab_name))
|
|
191
|
+
Check_Type(v_keytab_name, T_STRING);
|
|
192
|
+
|
|
193
|
+
if(!NIL_P(v_service))
|
|
194
|
+
Check_Type(v_service, T_STRING);
|
|
195
|
+
|
|
167
196
|
kerror = krb5_get_init_creds_opt_alloc(ptr->ctx, &opt);
|
|
168
197
|
if(kerror)
|
|
169
198
|
rb_raise(cKrb5Exception, "krb5_get_init_creds_opt_alloc: %s", error_message(kerror));
|
|
170
199
|
|
|
171
|
-
rb_scan_args(argc, argv, "04", &v_user, &v_keytab_name, &v_service, &v_ccache);
|
|
172
|
-
|
|
173
200
|
// We need the service information for later.
|
|
174
201
|
if(NIL_P(v_service)){
|
|
175
202
|
service = NULL;
|
|
176
203
|
}
|
|
177
204
|
else{
|
|
178
|
-
Check_Type(v_service, T_STRING);
|
|
179
205
|
service = StringValueCStr(v_service);
|
|
180
206
|
}
|
|
181
207
|
|
|
@@ -195,7 +221,6 @@ static VALUE rkrb5_get_init_creds_keytab(int argc, VALUE* argv, VALUE self){
|
|
|
195
221
|
}
|
|
196
222
|
}
|
|
197
223
|
else{
|
|
198
|
-
Check_Type(v_user, T_STRING);
|
|
199
224
|
user = StringValueCStr(v_user);
|
|
200
225
|
|
|
201
226
|
kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ);
|
|
@@ -216,7 +241,6 @@ static VALUE rkrb5_get_init_creds_keytab(int argc, VALUE* argv, VALUE self){
|
|
|
216
241
|
}
|
|
217
242
|
}
|
|
218
243
|
else{
|
|
219
|
-
Check_Type(v_keytab_name, T_STRING);
|
|
220
244
|
strncpy(keytab_name, StringValueCStr(v_keytab_name), MAX_KEYTAB_NAME_LEN - 1);
|
|
221
245
|
keytab_name[MAX_KEYTAB_NAME_LEN - 1] = '\0';
|
|
222
246
|
}
|
|
@@ -304,6 +328,9 @@ static VALUE rkrb5_change_password(VALUE self, VALUE v_old, VALUE v_new){
|
|
|
304
328
|
if(!ptr->princ)
|
|
305
329
|
rb_raise(cKrb5Exception, "no principal has been established");
|
|
306
330
|
|
|
331
|
+
krb5_free_cred_contents(ptr->ctx, &ptr->creds);
|
|
332
|
+
memset(&ptr->creds, 0, sizeof(ptr->creds));
|
|
333
|
+
|
|
307
334
|
kerror = krb5_get_init_creds_password(
|
|
308
335
|
ptr->ctx,
|
|
309
336
|
&ptr->creds,
|
|
@@ -328,8 +355,23 @@ static VALUE rkrb5_change_password(VALUE self, VALUE v_old, VALUE v_new){
|
|
|
328
355
|
&result_string
|
|
329
356
|
);
|
|
330
357
|
|
|
331
|
-
if(kerror)
|
|
358
|
+
if(kerror){
|
|
359
|
+
krb5_free_data_contents(ptr->ctx, &result_string);
|
|
360
|
+
krb5_free_data_contents(ptr->ctx, &pw_result_string);
|
|
332
361
|
rb_raise(cKrb5Exception, "krb5_change_password: %s", error_message(kerror));
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if(pw_result){
|
|
365
|
+
VALUE v_msg = (result_string.length > 0)
|
|
366
|
+
? rb_str_new(result_string.data, result_string.length)
|
|
367
|
+
: rb_str_new_cstr("password change rejected");
|
|
368
|
+
krb5_free_data_contents(ptr->ctx, &result_string);
|
|
369
|
+
krb5_free_data_contents(ptr->ctx, &pw_result_string);
|
|
370
|
+
rb_raise(cKrb5Exception, "krb5_change_password: %s", StringValueCStr(v_msg));
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
krb5_free_data_contents(ptr->ctx, &result_string);
|
|
374
|
+
krb5_free_data_contents(ptr->ctx, &pw_result_string);
|
|
333
375
|
|
|
334
376
|
return Qtrue;
|
|
335
377
|
}
|
|
@@ -355,6 +397,15 @@ static VALUE rkrb5_get_init_creds_passwd(int argc, VALUE* argv, VALUE self){
|
|
|
355
397
|
if(!ptr->ctx)
|
|
356
398
|
rb_raise(cKrb5Exception, "no context has been established");
|
|
357
399
|
|
|
400
|
+
// Free resources from a previous call to avoid leaks on repeated use.
|
|
401
|
+
if(ptr->princ){
|
|
402
|
+
krb5_free_principal(ptr->ctx, ptr->princ);
|
|
403
|
+
ptr->princ = NULL;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
krb5_free_cred_contents(ptr->ctx, &ptr->creds);
|
|
407
|
+
memset(&ptr->creds, 0, sizeof(ptr->creds));
|
|
408
|
+
|
|
358
409
|
rb_scan_args(argc, argv, "21", &v_user, &v_pass, &v_service);
|
|
359
410
|
|
|
360
411
|
Check_Type(v_user, T_STRING);
|
|
@@ -419,6 +470,15 @@ static VALUE rkrb5_authenticate_bang(int argc, VALUE* argv, VALUE self){
|
|
|
419
470
|
if(!ptr->ctx)
|
|
420
471
|
rb_raise(cKrb5Exception, "no context has been established");
|
|
421
472
|
|
|
473
|
+
// Free resources from a previous call to avoid leaks on repeated use.
|
|
474
|
+
if(ptr->princ){
|
|
475
|
+
krb5_free_principal(ptr->ctx, ptr->princ);
|
|
476
|
+
ptr->princ = NULL;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
krb5_free_cred_contents(ptr->ctx, &ptr->creds);
|
|
480
|
+
memset(&ptr->creds, 0, sizeof(ptr->creds));
|
|
481
|
+
|
|
422
482
|
// Require user and password, optional service
|
|
423
483
|
rb_scan_args(argc, argv, "21", &v_user, &v_pass, &v_service);
|
|
424
484
|
|
|
@@ -509,6 +569,11 @@ static VALUE rkrb5_close(VALUE self){
|
|
|
509
569
|
|
|
510
570
|
TypedData_Get_Struct(self, RUBY_KRB5, &rkrb5_data_type, ptr);
|
|
511
571
|
|
|
572
|
+
if(ptr->keytab){
|
|
573
|
+
krb5_kt_close(ptr->ctx, ptr->keytab);
|
|
574
|
+
ptr->keytab = NULL;
|
|
575
|
+
}
|
|
576
|
+
|
|
512
577
|
if(ptr->ctx)
|
|
513
578
|
krb5_free_cred_contents(ptr->ctx, &ptr->creds);
|
|
514
579
|
|
|
@@ -544,6 +609,12 @@ static VALUE rkrb5_get_default_principal(VALUE self){
|
|
|
544
609
|
if(!ptr->ctx)
|
|
545
610
|
rb_raise(cKrb5Exception, "no context has been established");
|
|
546
611
|
|
|
612
|
+
// Free previous principal to avoid leaks on repeated calls.
|
|
613
|
+
if(ptr->princ){
|
|
614
|
+
krb5_free_principal(ptr->ctx, ptr->princ);
|
|
615
|
+
ptr->princ = NULL;
|
|
616
|
+
}
|
|
617
|
+
|
|
547
618
|
// Get the default credentials cache
|
|
548
619
|
kerror = krb5_cc_default(ptr->ctx, &ccache);
|
|
549
620
|
|
|
@@ -562,9 +633,12 @@ static VALUE rkrb5_get_default_principal(VALUE self){
|
|
|
562
633
|
kerror = krb5_unparse_name(ptr->ctx, ptr->princ, &princ_name);
|
|
563
634
|
|
|
564
635
|
if(kerror)
|
|
565
|
-
rb_raise(cKrb5Exception, "
|
|
636
|
+
rb_raise(cKrb5Exception, "krb5_unparse_name: %s", error_message(kerror));
|
|
566
637
|
|
|
567
|
-
|
|
638
|
+
VALUE v_name = rb_str_new2(princ_name);
|
|
639
|
+
krb5_free_unparsed_name(ptr->ctx, princ_name);
|
|
640
|
+
|
|
641
|
+
return v_name;
|
|
568
642
|
}
|
|
569
643
|
|
|
570
644
|
/*
|
|
@@ -611,11 +685,15 @@ static VALUE rkrb5_get_permitted_enctypes(VALUE self){
|
|
|
611
685
|
v_enctypes = rb_hash_new();
|
|
612
686
|
|
|
613
687
|
for(i = 0; ktypes[i]; i++){
|
|
614
|
-
|
|
615
|
-
|
|
688
|
+
krb5_error_code enc_err = krb5_enctype_to_string(ktypes[i], encoding, 128);
|
|
689
|
+
if(enc_err){
|
|
690
|
+
krb5_free_enctypes(ptr->ctx, ktypes);
|
|
691
|
+
rb_raise(cKrb5Exception, "krb5_enctype_to_string: %s", error_message(enc_err));
|
|
616
692
|
}
|
|
617
693
|
rb_hash_aset(v_enctypes, INT2FIX(ktypes[i]), rb_str_new2(encoding));
|
|
618
694
|
}
|
|
695
|
+
|
|
696
|
+
krb5_free_enctypes(ptr->ctx, ktypes);
|
|
619
697
|
}
|
|
620
698
|
|
|
621
699
|
return v_enctypes;
|
|
@@ -730,8 +808,8 @@ void Init_rkerberos(void){
|
|
|
730
808
|
rb_define_alias(cKrb5, "default_realm", "get_default_realm");
|
|
731
809
|
rb_define_alias(cKrb5, "default_principal", "get_default_principal");
|
|
732
810
|
|
|
733
|
-
/* 0.2.
|
|
734
|
-
rb_define_const(cKrb5, "VERSION", rb_str_new2("0.2.
|
|
811
|
+
/* 0.2.3: The version of the custom rkerberos library */
|
|
812
|
+
rb_define_const(cKrb5, "VERSION", rb_str_new2("0.2.3"));
|
|
735
813
|
|
|
736
814
|
// Encoding type constants
|
|
737
815
|
|
data/rkerberos.gemspec
CHANGED
|
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |spec|
|
|
4
4
|
spec.name = 'rkerberos'
|
|
5
|
-
spec.version = '0.2.
|
|
5
|
+
spec.version = '0.2.3'
|
|
6
6
|
spec.authors = ['Daniel Berger', 'Dominic Cleal', 'Simon Levermann']
|
|
7
7
|
spec.license = 'Artistic-2.0'
|
|
8
8
|
spec.email = ['djberg96@gmail.com', 'dominic@cleal.org', 'simon-rubygems@slevermann.de']
|
data/spec/config_spec.rb
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# spec/config_spec.rb
|
|
2
2
|
# RSpec tests for Kerberos::Kadm5::Config
|
|
3
3
|
|
|
4
|
-
require '
|
|
4
|
+
require 'spec_helper'
|
|
5
5
|
|
|
6
|
-
RSpec.describe Kerberos::Kadm5::Config do
|
|
7
|
-
subject(:
|
|
6
|
+
RSpec.describe 'Kerberos::Kadm5::Config', :kadm5 do
|
|
7
|
+
subject(:klass){ Kerberos::Kadm5::Config }
|
|
8
|
+
let(:config) { klass.new }
|
|
8
9
|
|
|
9
10
|
it 'is frozen' do
|
|
10
11
|
expect(config).to be_frozen
|
|
@@ -14,6 +15,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
14
15
|
it 'responds to realm' do
|
|
15
16
|
expect(config).to respond_to(:realm)
|
|
16
17
|
end
|
|
18
|
+
|
|
17
19
|
it 'returns a String' do
|
|
18
20
|
expect(config.realm).to be_a(String)
|
|
19
21
|
end
|
|
@@ -23,6 +25,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
23
25
|
it 'responds to kadmind_port' do
|
|
24
26
|
expect(config).to respond_to(:kadmind_port)
|
|
25
27
|
end
|
|
28
|
+
|
|
26
29
|
it 'returns an Integer' do
|
|
27
30
|
expect(config.kadmind_port).to be_a(Integer)
|
|
28
31
|
end
|
|
@@ -32,6 +35,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
32
35
|
it 'responds to kpasswd_port' do
|
|
33
36
|
expect(config).to respond_to(:kpasswd_port)
|
|
34
37
|
end
|
|
38
|
+
|
|
35
39
|
it 'returns an Integer' do
|
|
36
40
|
expect(config.kpasswd_port).to be_a(Integer)
|
|
37
41
|
end
|
|
@@ -41,6 +45,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
41
45
|
it 'responds to admin_server' do
|
|
42
46
|
expect(config).to respond_to(:admin_server)
|
|
43
47
|
end
|
|
48
|
+
|
|
44
49
|
it 'returns a String' do
|
|
45
50
|
expect(config.admin_server).to be_a(String)
|
|
46
51
|
end
|
|
@@ -50,6 +55,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
50
55
|
it 'responds to acl_file' do
|
|
51
56
|
expect(config).to respond_to(:acl_file)
|
|
52
57
|
end
|
|
58
|
+
|
|
53
59
|
it 'returns a String' do
|
|
54
60
|
expect(config.acl_file).to be_a(String)
|
|
55
61
|
end
|
|
@@ -59,6 +65,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
59
65
|
it 'responds to dict_file' do
|
|
60
66
|
expect(config).to respond_to(:dict_file)
|
|
61
67
|
end
|
|
68
|
+
|
|
62
69
|
it 'returns a String or nil' do
|
|
63
70
|
expect([String, NilClass]).to include(config.dict_file.class)
|
|
64
71
|
end
|
|
@@ -68,6 +75,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
68
75
|
it 'responds to stash_file' do
|
|
69
76
|
expect(config).to respond_to(:stash_file)
|
|
70
77
|
end
|
|
78
|
+
|
|
71
79
|
it 'returns a String or nil' do
|
|
72
80
|
expect([String, NilClass]).to include(config.stash_file.class)
|
|
73
81
|
end
|
|
@@ -77,6 +85,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
77
85
|
it 'responds to mkey_name' do
|
|
78
86
|
expect(config).to respond_to(:mkey_name)
|
|
79
87
|
end
|
|
88
|
+
|
|
80
89
|
it 'returns a String or nil' do
|
|
81
90
|
expect([String, NilClass]).to include(config.mkey_name.class)
|
|
82
91
|
end
|
|
@@ -86,6 +95,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
86
95
|
it 'responds to mkey_from_kbd' do
|
|
87
96
|
expect(config).to respond_to(:mkey_from_kbd)
|
|
88
97
|
end
|
|
98
|
+
|
|
89
99
|
it 'returns an Integer or nil' do
|
|
90
100
|
expect([Integer, NilClass]).to include(config.mkey_from_kbd.class)
|
|
91
101
|
end
|
|
@@ -95,6 +105,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
95
105
|
it 'responds to enctype' do
|
|
96
106
|
expect(config).to respond_to(:enctype)
|
|
97
107
|
end
|
|
108
|
+
|
|
98
109
|
it 'returns an Integer' do
|
|
99
110
|
expect(config.enctype).to be_a(Integer)
|
|
100
111
|
end
|
|
@@ -104,8 +115,9 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
104
115
|
it 'responds to max_life' do
|
|
105
116
|
expect(config).to respond_to(:max_life)
|
|
106
117
|
end
|
|
107
|
-
|
|
108
|
-
|
|
118
|
+
|
|
119
|
+
it 'returns an Integer' do
|
|
120
|
+
expect(config.max_life).to be_a(Integer)
|
|
109
121
|
end
|
|
110
122
|
end
|
|
111
123
|
|
|
@@ -113,8 +125,9 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
113
125
|
it 'responds to max_rlife' do
|
|
114
126
|
expect(config).to respond_to(:max_rlife)
|
|
115
127
|
end
|
|
116
|
-
|
|
117
|
-
|
|
128
|
+
|
|
129
|
+
it 'returns an Integer' do
|
|
130
|
+
expect(config.max_rlife).to be_a(Integer)
|
|
118
131
|
end
|
|
119
132
|
end
|
|
120
133
|
|
|
@@ -122,6 +135,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
122
135
|
it 'responds to expiration' do
|
|
123
136
|
expect(config).to respond_to(:expiration)
|
|
124
137
|
end
|
|
138
|
+
|
|
125
139
|
it 'returns a Time or nil' do
|
|
126
140
|
expect([Time, NilClass]).to include(config.expiration.class)
|
|
127
141
|
end
|
|
@@ -131,6 +145,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
131
145
|
it 'responds to kvno' do
|
|
132
146
|
expect(config).to respond_to(:kvno)
|
|
133
147
|
end
|
|
148
|
+
|
|
134
149
|
it 'returns an Integer or nil' do
|
|
135
150
|
expect([Integer, NilClass]).to include(config.kvno.class)
|
|
136
151
|
end
|
|
@@ -140,6 +155,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
140
155
|
it 'responds to iprop_enabled' do
|
|
141
156
|
expect(config).to respond_to(:iprop_enabled)
|
|
142
157
|
end
|
|
158
|
+
|
|
143
159
|
it 'returns a boolean' do
|
|
144
160
|
expect(!!config.iprop_enabled == config.iprop_enabled).to be true
|
|
145
161
|
end
|
|
@@ -149,6 +165,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
149
165
|
it 'responds to iprop_logfile' do
|
|
150
166
|
expect(config).to respond_to(:iprop_logfile)
|
|
151
167
|
end
|
|
168
|
+
|
|
152
169
|
it 'returns a String' do
|
|
153
170
|
expect(config.iprop_logfile).to be_a(String)
|
|
154
171
|
end
|
|
@@ -158,6 +175,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
158
175
|
it 'responds to iprop_poll_time' do
|
|
159
176
|
expect(config).to respond_to(:iprop_poll_time)
|
|
160
177
|
end
|
|
178
|
+
|
|
161
179
|
it 'returns an Integer' do
|
|
162
180
|
expect(config.iprop_poll_time).to be_a(Integer)
|
|
163
181
|
end
|
|
@@ -167,6 +185,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
167
185
|
it 'responds to iprop_port' do
|
|
168
186
|
expect(config).to respond_to(:iprop_port)
|
|
169
187
|
end
|
|
188
|
+
|
|
170
189
|
it 'returns an Integer or nil' do
|
|
171
190
|
expect([Integer, NilClass]).to include(config.iprop_port.class)
|
|
172
191
|
end
|
|
@@ -176,6 +195,7 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
176
195
|
it 'responds to num_keysalts' do
|
|
177
196
|
expect(config).to respond_to(:num_keysalts)
|
|
178
197
|
end
|
|
198
|
+
|
|
179
199
|
it 'returns an Integer' do
|
|
180
200
|
expect(config.num_keysalts).to be_a(Integer)
|
|
181
201
|
end
|
|
@@ -185,9 +205,11 @@ RSpec.describe Kerberos::Kadm5::Config do
|
|
|
185
205
|
it 'responds to keysalts' do
|
|
186
206
|
expect(config).to respond_to(:keysalts)
|
|
187
207
|
end
|
|
208
|
+
|
|
188
209
|
it 'returns an Array' do
|
|
189
210
|
expect(config.keysalts).to be_a(Array)
|
|
190
211
|
end
|
|
212
|
+
|
|
191
213
|
it 'contains KeySalt objects if not empty' do
|
|
192
214
|
unless config.keysalts.empty?
|
|
193
215
|
expect(config.keysalts.first).to be_a(Kerberos::Kadm5::KeySalt)
|
data/spec/context_spec.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# spec/context_spec.rb
|
|
2
2
|
# RSpec tests for Kerberos::Krb5::Context
|
|
3
3
|
|
|
4
|
-
require '
|
|
4
|
+
require 'spec_helper'
|
|
5
5
|
|
|
6
6
|
RSpec.describe Kerberos::Krb5::Context do
|
|
7
7
|
subject(:context) { described_class.new }
|
|
@@ -19,17 +19,18 @@ RSpec.describe Kerberos::Krb5::Context do
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
describe 'constructor options' do
|
|
22
|
+
let(:profile_path){ RSpec.configuration.krb5_conf }
|
|
23
|
+
|
|
22
24
|
it 'accepts secure: true to use a secure context' do
|
|
23
25
|
expect { described_class.new(secure: true) }.not_to raise_error
|
|
24
26
|
end
|
|
25
27
|
|
|
26
|
-
it 'accepts a profile path via :profile' do
|
|
27
|
-
profile_path = ENV['KRB5_CONFIG'] || '/etc/krb5.conf'
|
|
28
|
+
it 'accepts a profile path via :profile', :unix do
|
|
28
29
|
expect(File).to exist(profile_path)
|
|
29
30
|
expect { described_class.new(profile: profile_path) }.not_to raise_error
|
|
30
31
|
end
|
|
31
32
|
|
|
32
|
-
it 'validates profile argument type' do
|
|
33
|
+
it 'validates profile argument type', :unix do
|
|
33
34
|
expect { described_class.new(profile: 123) }.to raise_error(TypeError)
|
|
34
35
|
end
|
|
35
36
|
|
|
@@ -43,10 +44,8 @@ RSpec.describe Kerberos::Krb5::Context do
|
|
|
43
44
|
end
|
|
44
45
|
end
|
|
45
46
|
|
|
46
|
-
it 'accepts secure: true together with profile' do
|
|
47
|
-
profile_path = ENV['KRB5_CONFIG'] || '/etc/krb5.conf'
|
|
47
|
+
it 'accepts secure: true together with profile', :unix do
|
|
48
48
|
expect(File).to exist(profile_path)
|
|
49
|
-
|
|
50
49
|
ctx = nil
|
|
51
50
|
expect { ctx = described_class.new(secure: true, profile: profile_path) }.not_to raise_error
|
|
52
51
|
expect(ctx).to be_a(described_class)
|
|
@@ -1,51 +1,55 @@
|
|
|
1
1
|
# spec/credentials_cache_spec.rb
|
|
2
2
|
# RSpec tests for Kerberos::Krb5::CredentialsCache
|
|
3
3
|
|
|
4
|
-
require '
|
|
5
|
-
require 'etc'
|
|
4
|
+
require 'spec_helper'
|
|
6
5
|
require 'open3'
|
|
7
|
-
require 'tmpdir'
|
|
8
6
|
|
|
9
7
|
RSpec.describe Kerberos::Krb5::CredentialsCache do
|
|
10
|
-
let(:login) do
|
|
11
|
-
Etc.getlogin || ENV['USER'] || (Etc.getpwuid(Process.uid).name rescue nil)
|
|
12
|
-
end
|
|
13
8
|
let(:realm) { Kerberos::Krb5.new.default_realm }
|
|
14
|
-
let(:princ) {
|
|
15
|
-
let(:cfile) {
|
|
9
|
+
let(:princ) { RSpec.configuration.login + '@' + realm }
|
|
10
|
+
let(:cfile) { RSpec.configuration.krb5_cc_name }
|
|
16
11
|
let(:ccache) { described_class.new }
|
|
17
12
|
|
|
18
13
|
def cache_found?
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
if File::ALT_SEPARATOR
|
|
15
|
+
File.exist?(cfile)
|
|
16
|
+
else
|
|
17
|
+
found = true
|
|
18
|
+
Open3.popen3('klist') { |_, _, stderr| found = false unless stderr.gets.nil? }
|
|
19
|
+
found
|
|
20
|
+
end
|
|
22
21
|
end
|
|
23
22
|
|
|
24
23
|
after(:each) do
|
|
25
|
-
Open3.popen3('kdestroy') { sleep 0.1 }
|
|
24
|
+
Open3.popen3('kdestroy -q') { sleep 0.1 } if cache_found?
|
|
26
25
|
end
|
|
27
26
|
|
|
28
27
|
describe 'constructor' do
|
|
29
28
|
it 'can be called with no arguments' do
|
|
30
29
|
expect { described_class.new }.not_to raise_error
|
|
31
30
|
end
|
|
31
|
+
|
|
32
32
|
it 'does not create a cache with no arguments' do
|
|
33
33
|
described_class.new
|
|
34
34
|
expect(File.exist?(cfile)).to be false
|
|
35
35
|
expect(cache_found?).to be false
|
|
36
36
|
end
|
|
37
|
+
|
|
37
38
|
it 'creates a cache with a principal' do
|
|
38
39
|
expect { described_class.new(princ) }.not_to raise_error
|
|
39
40
|
expect(File.exist?(cfile)).to be true
|
|
40
41
|
expect(cache_found?).to be true
|
|
41
42
|
end
|
|
43
|
+
|
|
42
44
|
it 'accepts an explicit cache name' do
|
|
43
45
|
expect { described_class.new(princ, cfile) }.not_to raise_error
|
|
44
46
|
expect { described_class.new(nil, cfile) }.not_to raise_error
|
|
45
47
|
end
|
|
48
|
+
|
|
46
49
|
it 'raises error for non-string argument' do
|
|
47
50
|
expect { described_class.new(true) }.to raise_error(TypeError)
|
|
48
51
|
end
|
|
52
|
+
|
|
49
53
|
it 'accepts only up to two arguments' do
|
|
50
54
|
expect { described_class.new(princ, cfile, cfile) }.to raise_error(ArgumentError)
|
|
51
55
|
end
|
|
@@ -55,15 +59,18 @@ RSpec.describe Kerberos::Krb5::CredentialsCache do
|
|
|
55
59
|
it 'responds to close' do
|
|
56
60
|
expect(described_class.new(princ)).to respond_to(:close)
|
|
57
61
|
end
|
|
62
|
+
|
|
58
63
|
it 'does not delete credentials cache' do
|
|
59
64
|
c = described_class.new(princ)
|
|
60
65
|
expect { c.close }.not_to raise_error
|
|
61
66
|
expect(cache_found?).to be true
|
|
62
67
|
end
|
|
68
|
+
|
|
63
69
|
it 'can be called multiple times without error' do
|
|
64
70
|
c = described_class.new(princ)
|
|
65
71
|
expect { 3.times { c.close } }.not_to raise_error
|
|
66
72
|
end
|
|
73
|
+
|
|
67
74
|
it 'raises error when calling method on closed object' do
|
|
68
75
|
c = described_class.new(princ)
|
|
69
76
|
c.close
|
|
@@ -77,18 +84,43 @@ RSpec.describe Kerberos::Krb5::CredentialsCache do
|
|
|
77
84
|
expect(c).to respond_to(:default_name)
|
|
78
85
|
expect { c.default_name }.not_to raise_error
|
|
79
86
|
end
|
|
87
|
+
|
|
80
88
|
it 'returns a string' do
|
|
81
89
|
c = described_class.new(princ)
|
|
82
90
|
expect(c.default_name).to be_a(String)
|
|
83
91
|
end
|
|
84
92
|
end
|
|
85
93
|
|
|
94
|
+
describe '#cache_name and #cache_type' do
|
|
95
|
+
it 'returns the ccache name and type' do
|
|
96
|
+
c = described_class.new(princ)
|
|
97
|
+
expect(c).to respond_to(:cache_name)
|
|
98
|
+
expect(c).to respond_to(:cache_type)
|
|
99
|
+
|
|
100
|
+
expect(c.cache_name).to be_a(String)
|
|
101
|
+
expect(c.cache_type).to be_a(String)
|
|
102
|
+
|
|
103
|
+
# cache_name returns the residual portion of the cache name; default_name
|
|
104
|
+
# may include the type prefix (e.g. "FILE:"). ensure the suffix matches.
|
|
105
|
+
expect(c.cache_name).to eq(c.default_name.split(/\w{2,}:/).last)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
describe '#principal' do
|
|
110
|
+
it 'is an alias for primary_principal' do
|
|
111
|
+
c = described_class.new(princ)
|
|
112
|
+
expect(c).to respond_to(:principal)
|
|
113
|
+
expect(c.principal).to eq(c.primary_principal)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
86
117
|
describe '#primary_principal' do
|
|
87
118
|
it 'responds to primary_principal' do
|
|
88
119
|
c = described_class.new(princ)
|
|
89
120
|
expect(c).to respond_to(:primary_principal)
|
|
90
121
|
expect { c.primary_principal }.not_to raise_error
|
|
91
122
|
end
|
|
123
|
+
|
|
92
124
|
it 'returns expected results' do
|
|
93
125
|
c = described_class.new(princ)
|
|
94
126
|
expect(c.primary_principal).to be_a(String)
|
|
@@ -102,28 +134,63 @@ RSpec.describe Kerberos::Krb5::CredentialsCache do
|
|
|
102
134
|
c = described_class.new(princ)
|
|
103
135
|
expect(c).to respond_to(:destroy)
|
|
104
136
|
end
|
|
137
|
+
|
|
105
138
|
it 'deletes credentials cache' do
|
|
106
139
|
c = described_class.new(princ)
|
|
107
140
|
expect { c.destroy }.not_to raise_error
|
|
108
141
|
expect(cache_found?).to be false
|
|
109
142
|
end
|
|
143
|
+
|
|
110
144
|
it 'delete is an alias for destroy' do
|
|
111
145
|
c = described_class.new(princ)
|
|
112
146
|
expect(c).to respond_to(:delete)
|
|
113
147
|
expect(c.method(:delete)).to eq(c.method(:destroy))
|
|
114
148
|
end
|
|
149
|
+
|
|
115
150
|
it 'returns false if no credentials cache' do
|
|
116
151
|
c = described_class.new
|
|
117
152
|
expect(c.destroy).to be false
|
|
118
153
|
end
|
|
154
|
+
|
|
119
155
|
it 'raises error when calling method on destroyed object' do
|
|
120
156
|
c = described_class.new(princ)
|
|
121
157
|
c.destroy
|
|
122
158
|
expect { c.default_name }.to raise_error(Kerberos::Krb5::Exception)
|
|
123
159
|
end
|
|
160
|
+
|
|
124
161
|
it 'does not accept arguments' do
|
|
125
162
|
c = described_class.new(princ)
|
|
126
163
|
expect { c.destroy(true) }.to raise_error(ArgumentError)
|
|
127
164
|
end
|
|
128
165
|
end
|
|
166
|
+
|
|
167
|
+
describe '#dup' do
|
|
168
|
+
it 'returns a new cache object with the same properties' do
|
|
169
|
+
c = described_class.new(princ)
|
|
170
|
+
c2 = c.dup
|
|
171
|
+
expect(c2).to be_a(described_class)
|
|
172
|
+
expect(c2.default_name).to eq(c.default_name)
|
|
173
|
+
expect(c2.primary_principal).to eq(c.primary_principal)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it 'closing original does not affect duplicate' do
|
|
177
|
+
c = described_class.new(princ)
|
|
178
|
+
c2 = c.dup
|
|
179
|
+
c.close
|
|
180
|
+
expect { c2.default_name }.not_to raise_error
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it 'closing duplicate does not affect original' do
|
|
184
|
+
c = described_class.new(princ)
|
|
185
|
+
c2 = c.dup
|
|
186
|
+
c2.close
|
|
187
|
+
expect { c.default_name }.not_to raise_error
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it 'raises when duping closed cache' do
|
|
191
|
+
c = described_class.new(princ)
|
|
192
|
+
c.close
|
|
193
|
+
expect { c.dup }.to raise_error(Kerberos::Krb5::Exception)
|
|
194
|
+
end
|
|
195
|
+
end
|
|
129
196
|
end
|