rkerberos 0.2.3 → 0.3.1
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 +30 -0
- data/EXAMPLES.md +1015 -0
- data/MANIFEST.md +17 -12
- data/README.md +17 -6
- data/ext/rkerberos/ccache.c +99 -26
- data/ext/rkerberos/config.c +62 -10
- data/ext/rkerberos/context.c +132 -14
- data/ext/rkerberos/kadm5.c +332 -116
- data/ext/rkerberos/keytab.c +230 -79
- data/ext/rkerberos/policy.c +25 -23
- data/ext/rkerberos/principal.c +139 -11
- data/ext/rkerberos/rkerberos.c +269 -52
- data/ext/rkerberos/rkerberos.h +14 -0
- data/rkerberos.gemspec +10 -7
- data/spec/config_spec.rb +41 -0
- data/spec/context_spec.rb +96 -0
- data/spec/credentials_cache_spec.rb +82 -26
- data/spec/kadm5_spec.rb +319 -5
- data/spec/krb5_keytab_spec.rb +275 -20
- data/spec/krb5_spec.rb +186 -21
- data/spec/policy_spec.rb +4 -0
- data/spec/principal_spec.rb +116 -10
- metadata +9 -8
data/ext/rkerberos/principal.c
CHANGED
|
@@ -4,13 +4,22 @@ VALUE cKrb5Principal;
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
// TypedData functions for RUBY_KRB5_PRINC
|
|
7
|
+
static void rkrb5_princ_typed_mark(void *ptr) {
|
|
8
|
+
if (!ptr) return;
|
|
9
|
+
RUBY_KRB5_PRINC *p = (RUBY_KRB5_PRINC *)ptr;
|
|
10
|
+
if (p->rb_context != Qnil)
|
|
11
|
+
rb_gc_mark(p->rb_context);
|
|
12
|
+
}
|
|
13
|
+
|
|
7
14
|
static void rkrb5_princ_typed_free(void *ptr) {
|
|
8
15
|
if (!ptr) return;
|
|
9
16
|
RUBY_KRB5_PRINC *p = (RUBY_KRB5_PRINC *)ptr;
|
|
10
17
|
if (p->principal)
|
|
11
18
|
krb5_free_principal(p->ctx, p->principal);
|
|
12
|
-
if (p->ctx)
|
|
19
|
+
if (p->ctx && p->rb_context == Qnil)
|
|
13
20
|
krb5_free_context(p->ctx);
|
|
21
|
+
else if (p->rb_context != Qnil)
|
|
22
|
+
rkrb5_context_release(p->rb_context);
|
|
14
23
|
free(p);
|
|
15
24
|
}
|
|
16
25
|
|
|
@@ -20,7 +29,7 @@ static size_t rkrb5_princ_typed_size(const void *ptr) {
|
|
|
20
29
|
|
|
21
30
|
static const rb_data_type_t rkrb5_princ_data_type = {
|
|
22
31
|
"RUBY_KRB5_PRINC",
|
|
23
|
-
{
|
|
32
|
+
{rkrb5_princ_typed_mark, rkrb5_princ_typed_free, rkrb5_princ_typed_size,},
|
|
24
33
|
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
|
|
25
34
|
};
|
|
26
35
|
|
|
@@ -28,34 +37,68 @@ static const rb_data_type_t rkrb5_princ_data_type = {
|
|
|
28
37
|
static VALUE rkrb5_princ_allocate(VALUE klass){
|
|
29
38
|
RUBY_KRB5_PRINC* ptr = ALLOC(RUBY_KRB5_PRINC);
|
|
30
39
|
memset(ptr, 0, sizeof(RUBY_KRB5_PRINC));
|
|
40
|
+
ptr->rb_context = Qnil;
|
|
31
41
|
return TypedData_Wrap_Struct(klass, &rkrb5_princ_data_type, ptr);
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
/*
|
|
35
45
|
* call-seq:
|
|
36
|
-
* Kerberos::Krb5::Principal.new(name)
|
|
46
|
+
* Kerberos::Krb5::Principal.new(name: nil, context: nil)
|
|
37
47
|
*
|
|
38
48
|
* Creates and returns a new Krb5::Principal object. If a block is provided
|
|
39
49
|
* then it yields itself.
|
|
40
50
|
*
|
|
51
|
+
* A principal +name+ may be provided as a keyword argument. If not provided
|
|
52
|
+
* or nil, the principal attribute will be nil.
|
|
53
|
+
*
|
|
54
|
+
* An optional +context+ keyword argument may be provided. If given, it must
|
|
55
|
+
* be a Kerberos::Krb5::Context object and will be used instead of creating
|
|
56
|
+
* a new context via krb5_init_context.
|
|
57
|
+
*
|
|
41
58
|
* Example:
|
|
42
59
|
*
|
|
43
|
-
* principal1 = Kerberos::Krb5::Principal.new('Jon')
|
|
60
|
+
* principal1 = Kerberos::Krb5::Principal.new(name: 'Jon')
|
|
44
61
|
*
|
|
45
|
-
* principal2 = Kerberos::Krb5::Principal.new('Jon') do |pr|
|
|
62
|
+
* principal2 = Kerberos::Krb5::Principal.new(name: 'Jon') do |pr|
|
|
46
63
|
* pr.expire_time = Time.now + 20000
|
|
47
64
|
* end
|
|
65
|
+
*
|
|
66
|
+
* ctx = Kerberos::Krb5::Context.new
|
|
67
|
+
* principal3 = Kerberos::Krb5::Principal.new(name: 'Jon', context: ctx)
|
|
48
68
|
*/
|
|
49
|
-
static VALUE rkrb5_princ_initialize(VALUE
|
|
69
|
+
static VALUE rkrb5_princ_initialize(int argc, VALUE* argv, VALUE self){
|
|
50
70
|
RUBY_KRB5_PRINC* ptr;
|
|
51
71
|
krb5_error_code kerror;
|
|
72
|
+
VALUE v_opts = Qnil;
|
|
73
|
+
VALUE v_name = Qnil;
|
|
74
|
+
VALUE v_context = Qnil;
|
|
75
|
+
ID kw_table[2] = { rb_intern("name"), rb_intern("context") };
|
|
76
|
+
VALUE kw_vals[2];
|
|
52
77
|
|
|
53
78
|
TypedData_Get_Struct(self, RUBY_KRB5_PRINC, &rkrb5_princ_data_type, ptr);
|
|
54
79
|
|
|
55
|
-
|
|
80
|
+
rb_scan_args(argc, argv, "0:", &v_opts);
|
|
81
|
+
|
|
82
|
+
if(NIL_P(v_opts))
|
|
83
|
+
v_opts = rb_hash_new();
|
|
56
84
|
|
|
57
|
-
|
|
58
|
-
|
|
85
|
+
rb_get_kwargs(v_opts, kw_table, 0, 2, kw_vals);
|
|
86
|
+
v_name = kw_vals[0] == Qundef ? Qnil : kw_vals[0];
|
|
87
|
+
v_context = kw_vals[1] == Qundef ? Qnil : kw_vals[1];
|
|
88
|
+
|
|
89
|
+
// Initialize or borrow the context
|
|
90
|
+
if(!NIL_P(v_context)){
|
|
91
|
+
ptr->ctx = rkrb5_context_borrow(v_context);
|
|
92
|
+
ptr->rb_context = v_context;
|
|
93
|
+
}
|
|
94
|
+
else{
|
|
95
|
+
kerror = krb5_init_context(&ptr->ctx);
|
|
96
|
+
|
|
97
|
+
if(kerror)
|
|
98
|
+
rb_raise(cKrb5Exception, "krb5_init_context failed: %s", error_message(kerror));
|
|
99
|
+
|
|
100
|
+
ptr->rb_context = Qnil;
|
|
101
|
+
}
|
|
59
102
|
|
|
60
103
|
if(NIL_P(v_name)){
|
|
61
104
|
rb_iv_set(self, "@principal", Qnil);
|
|
@@ -94,6 +137,36 @@ static VALUE rkrb5_princ_initialize(VALUE self, VALUE v_name){
|
|
|
94
137
|
return self;
|
|
95
138
|
}
|
|
96
139
|
|
|
140
|
+
/*
|
|
141
|
+
* call-seq:
|
|
142
|
+
* principal.close
|
|
143
|
+
*
|
|
144
|
+
* Releases the principal and its Kerberos context lease. Once closed, the
|
|
145
|
+
* principal cannot be reused.
|
|
146
|
+
*/
|
|
147
|
+
static VALUE rkrb5_princ_close(VALUE self){
|
|
148
|
+
RUBY_KRB5_PRINC* ptr;
|
|
149
|
+
|
|
150
|
+
TypedData_Get_Struct(self, RUBY_KRB5_PRINC, &rkrb5_princ_data_type, ptr);
|
|
151
|
+
|
|
152
|
+
if(!ptr->ctx)
|
|
153
|
+
return self;
|
|
154
|
+
|
|
155
|
+
if(ptr->principal)
|
|
156
|
+
krb5_free_principal(ptr->ctx, ptr->principal);
|
|
157
|
+
|
|
158
|
+
if(ptr->rb_context == Qnil)
|
|
159
|
+
krb5_free_context(ptr->ctx);
|
|
160
|
+
else
|
|
161
|
+
rkrb5_context_release(ptr->rb_context);
|
|
162
|
+
|
|
163
|
+
ptr->ctx = NULL;
|
|
164
|
+
ptr->principal = NULL;
|
|
165
|
+
ptr->rb_context = Qnil;
|
|
166
|
+
|
|
167
|
+
return self;
|
|
168
|
+
}
|
|
169
|
+
|
|
97
170
|
/*
|
|
98
171
|
* call-seq:
|
|
99
172
|
* principal.realm
|
|
@@ -102,13 +175,16 @@ static VALUE rkrb5_princ_initialize(VALUE self, VALUE v_name){
|
|
|
102
175
|
*/
|
|
103
176
|
static VALUE rkrb5_princ_get_realm(VALUE self){
|
|
104
177
|
RUBY_KRB5_PRINC* ptr;
|
|
178
|
+
krb5_data* realm;
|
|
105
179
|
|
|
106
180
|
TypedData_Get_Struct(self, RUBY_KRB5_PRINC, &rkrb5_princ_data_type, ptr);
|
|
107
181
|
|
|
108
182
|
if(!ptr->principal)
|
|
109
183
|
rb_raise(cKrb5Exception, "no principal has been established");
|
|
110
184
|
|
|
111
|
-
|
|
185
|
+
realm = krb5_princ_realm(ptr->ctx, ptr->principal);
|
|
186
|
+
|
|
187
|
+
return rb_str_new(realm->data, realm->length);
|
|
112
188
|
}
|
|
113
189
|
|
|
114
190
|
/*
|
|
@@ -144,6 +220,10 @@ static VALUE rkrb5_princ_equal(VALUE self, VALUE v_other){
|
|
|
144
220
|
VALUE v_bool = Qfalse;
|
|
145
221
|
|
|
146
222
|
TypedData_Get_Struct(self, RUBY_KRB5_PRINC, &rkrb5_princ_data_type, ptr1);
|
|
223
|
+
|
|
224
|
+
if(!rb_obj_is_kind_of(v_other, cKrb5Principal))
|
|
225
|
+
return Qfalse;
|
|
226
|
+
|
|
147
227
|
TypedData_Get_Struct(v_other, RUBY_KRB5_PRINC, &rkrb5_princ_data_type, ptr2);
|
|
148
228
|
|
|
149
229
|
if(!ptr1->principal || !ptr2->principal)
|
|
@@ -233,6 +313,51 @@ static VALUE rkrb5_princ_inspect(VALUE self){
|
|
|
233
313
|
return v_str;
|
|
234
314
|
}
|
|
235
315
|
|
|
316
|
+
/*
|
|
317
|
+
* call-seq:
|
|
318
|
+
* principal.principal_type -> Integer
|
|
319
|
+
*
|
|
320
|
+
* Returns the type of the principal as an integer, e.g.
|
|
321
|
+
* KRB5_NT_PRINCIPAL (1), KRB5_NT_SRV_HST (2), etc.
|
|
322
|
+
*/
|
|
323
|
+
static VALUE rkrb5_princ_get_type(VALUE self){
|
|
324
|
+
RUBY_KRB5_PRINC* ptr;
|
|
325
|
+
|
|
326
|
+
TypedData_Get_Struct(self, RUBY_KRB5_PRINC, &rkrb5_princ_data_type, ptr);
|
|
327
|
+
|
|
328
|
+
if(!ptr->principal)
|
|
329
|
+
rb_raise(cKrb5Exception, "no principal has been established");
|
|
330
|
+
|
|
331
|
+
return INT2FIX(krb5_princ_type(ptr->ctx, ptr->principal));
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/*
|
|
335
|
+
* call-seq:
|
|
336
|
+
* principal.components -> Array
|
|
337
|
+
*
|
|
338
|
+
* Returns an array of the component strings that make up this principal
|
|
339
|
+
* name (excluding the realm). For example, "admin/instance@REALM" would
|
|
340
|
+
* return ["admin", "instance"].
|
|
341
|
+
*/
|
|
342
|
+
static VALUE rkrb5_princ_components(VALUE self){
|
|
343
|
+
RUBY_KRB5_PRINC* ptr;
|
|
344
|
+
|
|
345
|
+
TypedData_Get_Struct(self, RUBY_KRB5_PRINC, &rkrb5_princ_data_type, ptr);
|
|
346
|
+
|
|
347
|
+
if(!ptr->principal)
|
|
348
|
+
rb_raise(cKrb5Exception, "no principal has been established");
|
|
349
|
+
|
|
350
|
+
int n = krb5_princ_size(ptr->ctx, ptr->principal);
|
|
351
|
+
VALUE v_array = rb_ary_new_capa(n);
|
|
352
|
+
|
|
353
|
+
for(int i = 0; i < n; i++){
|
|
354
|
+
krb5_data* component = krb5_princ_component(ptr->ctx, ptr->principal, i);
|
|
355
|
+
rb_ary_push(v_array, rb_str_new(component->data, component->length));
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return v_array;
|
|
359
|
+
}
|
|
360
|
+
|
|
236
361
|
void Init_principal(void){
|
|
237
362
|
/* The Kerberos::Krb5::Principal class encapsulates a Kerberos principal. */
|
|
238
363
|
cKrb5Principal = rb_define_class_under(cKrb5, "Principal", rb_cObject);
|
|
@@ -243,7 +368,7 @@ void Init_principal(void){
|
|
|
243
368
|
|
|
244
369
|
// Constructor
|
|
245
370
|
|
|
246
|
-
rb_define_method(cKrb5Principal, "initialize", rkrb5_princ_initialize, 1);
|
|
371
|
+
rb_define_method(cKrb5Principal, "initialize", rkrb5_princ_initialize, -1);
|
|
247
372
|
|
|
248
373
|
// Instance Methods
|
|
249
374
|
|
|
@@ -251,6 +376,9 @@ void Init_principal(void){
|
|
|
251
376
|
rb_define_method(cKrb5Principal, "realm", rkrb5_princ_get_realm, 0);
|
|
252
377
|
rb_define_method(cKrb5Principal, "realm=", rkrb5_princ_set_realm, 1);
|
|
253
378
|
rb_define_method(cKrb5Principal, "==", rkrb5_princ_equal, 1);
|
|
379
|
+
rb_define_method(cKrb5Principal, "principal_type", rkrb5_princ_get_type, 0);
|
|
380
|
+
rb_define_method(cKrb5Principal, "components", rkrb5_princ_components, 0);
|
|
381
|
+
rb_define_method(cKrb5Principal, "close", rkrb5_princ_close, 0);
|
|
254
382
|
|
|
255
383
|
// Attributes
|
|
256
384
|
|