~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to ext/openssl/ossl_config.c

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum, Daigo Moriwaki, Lucas Nussbaum
  • Date: 2011-07-25 20:27:20 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20110725202720-9qfs7iam0ml7e1kc
Tags: 1.9.2.290-1
[ Daigo Moriwaki ]
* New upstream release.
* Removed debian/patches/110411_disable_osslv2.patch, which has been applied
  by the upstream.
* Added a patch: debian/patches/debian/patches/110716-bigdecimal,
  which was backported from the upstream (r30993)
  (CVE-2011-0188; Closes: 628450)

[ Lucas Nussbaum ]
* Build-depend on tcl-dev and tk-dev instead of {tcl,tk}8.4-dev.
* Update Lucas' email address.
* Add 110825-ossl-config.diff: backport changes to the OpenSSL
  extension to fix test failure.
* Add patch 110720_tcltk_disable_rpath.diff: disable rpath in tcltk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
 */
11
11
#include "ossl.h"
12
12
 
13
 
#define WrapConfig(klass, obj, conf) do { \
14
 
    if (!conf) { \
15
 
        ossl_raise(rb_eRuntimeError, "Config wasn't intitialized!"); \
16
 
    } \
17
 
    obj = Data_Wrap_Struct(klass, 0, NCONF_free, conf); \
18
 
} while (0)
19
 
#define GetConfig(obj, conf) do { \
20
 
    Data_Get_Struct(obj, CONF, conf); \
21
 
    if (!conf) { \
22
 
        ossl_raise(rb_eRuntimeError, "Config wasn't intitialized!"); \
23
 
    } \
24
 
} while (0)
25
 
#define SafeGetConfig(obj, conf) do { \
26
 
    OSSL_Check_Kind(obj, cConfig); \
27
 
    GetConfig(obj, conf); \
28
 
} while(0);
29
13
 
30
14
/*
31
15
 * Classes
39
23
 
40
24
static CONF *parse_config(VALUE, CONF*);
41
25
 
 
26
/*
 
27
 * GetConfigPtr is a public C-level function for getting OpenSSL CONF struct
 
28
 * from an OpenSSL::Config(eConfig) instance.  We decided to implement
 
29
 * OpenSSL::Config in Ruby level but we need to pass native CONF struct for
 
30
 * some OpenSSL features such as X509V3_EXT_*.
 
31
 */
42
32
CONF *
43
33
GetConfigPtr(VALUE obj)
44
34
{
45
35
    CONF *conf;
46
 
 
47
 
    SafeGetConfig(obj, conf);
48
 
 
49
 
    return conf;
50
 
}
51
 
 
52
 
CONF *
53
 
DupConfigPtr(VALUE obj)
54
 
{
55
36
    VALUE str;
 
37
    BIO *bio;
 
38
    long eline = -1;
56
39
 
57
40
    OSSL_Check_Kind(obj, cConfig);
58
41
    str = rb_funcall(obj, rb_intern("to_s"), 0);
59
 
 
60
 
    return parse_config(str, NULL);
61
 
}
62
 
 
63
 
/*
64
 
 * Private
65
 
 */
66
 
static CONF *
67
 
parse_config(VALUE str, CONF *dst)
68
 
{
69
 
    CONF *conf;
70
 
    BIO *bio;
71
 
    long eline = -1;
72
 
 
73
42
    bio = ossl_obj2bio(str);
74
 
    conf = dst ? dst : NCONF_new(NULL);
 
43
    conf = NCONF_new(NULL);
75
44
    if(!conf){
76
45
        BIO_free(bio);
77
46
        ossl_raise(eConfigError, NULL);
78
47
    }
79
48
    if(!NCONF_load_bio(conf, bio, &eline)){
80
49
        BIO_free(bio);
81
 
        if(!dst) NCONF_free(conf);
 
50
        NCONF_free(conf);
82
51
        if (eline <= 0) ossl_raise(eConfigError, "wrong config format");
83
52
        else ossl_raise(eConfigError, "error in line %d", eline);
84
53
        ossl_raise(eConfigError, NULL);
88
57
    return conf;
89
58
}
90
59
 
91
 
static VALUE
92
 
ossl_config_s_parse(VALUE klass, VALUE str)
93
 
{
94
 
    CONF *conf;
95
 
    VALUE obj;
96
 
 
97
 
    conf = parse_config(str, NULL);
98
 
    WrapConfig(klass, obj, conf);
99
 
 
100
 
    return obj;
101
 
}
102
 
 
103
 
static VALUE
104
 
ossl_config_s_alloc(VALUE klass)
105
 
{
106
 
    CONF *conf;
107
 
    VALUE obj;
108
 
 
109
 
    if(!(conf = NCONF_new(NULL)))
110
 
        ossl_raise(eConfigError, NULL);
111
 
    WrapConfig(klass, obj, conf);
112
 
 
113
 
    return obj;
114
 
}
115
 
 
116
 
static VALUE
117
 
ossl_config_copy(VALUE self, VALUE other)
118
 
{
119
 
    VALUE str;
120
 
    CONF *conf;
121
 
 
122
 
    str = rb_funcall(self, rb_intern("to_s"), 0);
123
 
    GetConfig(other, conf);
124
 
    parse_config(str, conf);
125
 
 
126
 
    return self;
127
 
}
128
 
 
129
 
static VALUE
130
 
ossl_config_initialize(int argc, VALUE *argv, VALUE self)
131
 
{
132
 
    CONF *conf;
133
 
    long eline = -1;
134
 
    char *filename;
135
 
    VALUE path;
136
 
 
137
 
    rb_scan_args(argc, argv, "01", &path);
138
 
    if(!NIL_P(path)){
139
 
        SafeStringValue(path);
140
 
        filename = StringValuePtr(path);
141
 
        GetConfig(self, conf);
142
 
        if (!NCONF_load(conf, filename, &eline)){
143
 
            if (eline <= 0)
144
 
                ossl_raise(eConfigError, "wrong config file %s", filename);
145
 
            else
146
 
                ossl_raise(eConfigError, "error in %s:%d", filename, eline);
147
 
        }
148
 
    }
149
 
#ifdef OSSL_NO_CONF_API
150
 
    else rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
151
 
#else
152
 
    else {
153
 
        GetConfig(self, conf);
154
 
        _CONF_new_data(conf);
155
 
    }
156
 
#endif
157
 
 
158
 
    return self;
159
 
}
160
 
 
161
 
static VALUE
162
 
ossl_config_add_value(VALUE self, VALUE section, VALUE name, VALUE value)
163
 
{
164
 
#ifdef OSSL_NO_CONF_API
165
 
    rb_notimplement();
166
 
#else
167
 
    CONF *conf;
168
 
    CONF_VALUE *sv, *cv;
169
 
 
170
 
    StringValue(section);
171
 
    StringValue(name);
172
 
    StringValue(value);
173
 
    GetConfig(self, conf);
174
 
    if(!(sv = _CONF_get_section(conf, RSTRING_PTR(section)))){
175
 
        if(!(sv = _CONF_new_section(conf, RSTRING_PTR(section)))){
176
 
            ossl_raise(eConfigError, NULL);
177
 
        }
178
 
    }
179
 
    if(!(cv = OPENSSL_malloc(sizeof(CONF_VALUE)))){
180
 
        ossl_raise(eConfigError, NULL);
181
 
    }
182
 
    cv->name = BUF_strdup(RSTRING_PTR(name));
183
 
    cv->value = BUF_strdup(RSTRING_PTR(value));
184
 
    if(!cv->name || !cv->value || !_CONF_add_string(conf, sv, cv)){
185
 
        OPENSSL_free(cv->name);
186
 
        OPENSSL_free(cv->value);
187
 
        OPENSSL_free(cv);
188
 
        ossl_raise(eConfigError, "_CONF_add_string failure");
189
 
    }
190
 
 
191
 
    return value;
192
 
#endif
193
 
}
194
 
 
195
 
static void
196
 
rb_ossl_config_modify_check(VALUE config)
197
 
{
198
 
    if (OBJ_FROZEN(config)) rb_error_frozen("OpenSSL::Config");
199
 
    if (!OBJ_UNTRUSTED(config) && rb_safe_level() >= 4)
200
 
        rb_raise(rb_eSecurityError, "Insecure: can't modify OpenSSL config");
201
 
}
202
 
 
203
 
#if !defined(OSSL_NO_CONF_API)
204
 
static VALUE
205
 
ossl_config_add_value_m(VALUE self, VALUE section, VALUE name, VALUE value)
206
 
{
207
 
    rb_ossl_config_modify_check(self);
208
 
    return ossl_config_add_value(self, section, name, value);
209
 
}
210
 
#else
211
 
#define ossl_config_add_value_m rb_f_notimplement
212
 
#endif
213
 
 
214
 
static VALUE
215
 
ossl_config_get_value(VALUE self, VALUE section, VALUE name)
216
 
{
217
 
    CONF *conf;
218
 
    char *str;
219
 
 
220
 
    StringValue(section);
221
 
    StringValue(name);
222
 
    GetConfig(self, conf);
223
 
    str = NCONF_get_string(conf, RSTRING_PTR(section), RSTRING_PTR(name));
224
 
    if(!str){
225
 
        ERR_clear_error();
226
 
        return Qnil;
227
 
    }
228
 
 
229
 
    return rb_str_new2(str);
230
 
}
231
 
 
232
 
static VALUE
233
 
ossl_config_get_value_old(int argc, VALUE *argv, VALUE self)
234
 
{
235
 
    VALUE section, name;
236
 
 
237
 
    rb_scan_args(argc, argv, "11", &section, &name);
238
 
 
239
 
    /* support conf.value(nil, "HOME") -> conf.get_value("", "HOME") */
240
 
    if (NIL_P(section)) section = rb_str_new2("");
241
 
    /* support conf.value("HOME") -> conf.get_value("", "HOME") */
242
 
    if (NIL_P(name)) {
243
 
        name = section;
244
 
        section = rb_str_new2("");
245
 
    }
246
 
    /* NOTE: Don't care about conf.get_value(nil, nil) */
247
 
    rb_warn("Config#value is deprecated; use Config#get_value");
248
 
    return ossl_config_get_value(self, section, name);
249
 
}
250
 
 
251
 
static VALUE
252
 
set_conf_section_i(VALUE i, VALUE *arg)
253
 
{
254
 
    VALUE name, value;
255
 
 
256
 
    Check_Type(i, T_ARRAY);
257
 
    name = rb_ary_entry(i, 0);
258
 
    value = rb_ary_entry(i, 1);
259
 
    ossl_config_add_value(arg[0], arg[1], name, value);
260
 
 
261
 
    return Qnil;
262
 
}
263
 
 
264
 
static VALUE
265
 
ossl_config_set_section(VALUE self, VALUE section, VALUE hash)
266
 
{
267
 
    VALUE arg[2];
268
 
 
269
 
    rb_ossl_config_modify_check(self);
270
 
    arg[0] = self;
271
 
    arg[1] = section;
272
 
    rb_block_call(hash, rb_intern("each"), 0, 0, set_conf_section_i, (VALUE)arg);
273
 
    return hash;
274
 
}
275
 
 
276
 
/*
277
 
 * Get all numbers as strings - use str.to_i to convert
278
 
 * long number = CONF_get_number(confp->config, sect, StringValuePtr(item));
279
 
 */
280
 
static VALUE
281
 
ossl_config_get_section(VALUE self, VALUE section)
282
 
{
283
 
    CONF *conf;
284
 
    STACK_OF(CONF_VALUE) *sk;
285
 
    CONF_VALUE *entry;
286
 
    int i, entries;
287
 
    VALUE hash;
288
 
 
289
 
    hash = rb_hash_new();
290
 
    StringValue(section);
291
 
    GetConfig(self, conf);
292
 
    if (!(sk = NCONF_get_section(conf, StringValuePtr(section)))) {
293
 
        ERR_clear_error();
294
 
        return hash;
295
 
    }
296
 
    if ((entries = sk_CONF_VALUE_num(sk)) < 0) {
297
 
        OSSL_Debug("# of items in section is < 0?!?");
298
 
        return hash;
299
 
    }
300
 
    for (i=0; i<entries; i++) {
301
 
        entry = sk_CONF_VALUE_value(sk, i);
302
 
        rb_hash_aset(hash, rb_str_new2(entry->name), rb_str_new2(entry->value));
303
 
    }
304
 
 
305
 
    return hash;
306
 
}
307
 
 
308
 
static VALUE
309
 
ossl_config_get_section_old(VALUE self, VALUE section)
310
 
{
311
 
    rb_warn("Config#section is deprecated; use Config#[]");
312
 
    return ossl_config_get_section(self, section);
313
 
}
314
 
 
315
 
#if defined(IMPLEMENT_LHASH_DOALL_ARG_FN) && defined(LHASH_OF)
316
 
static void
317
 
get_conf_section_doall_arg(CONF_VALUE *cv, void *tmp)
318
 
{
319
 
    VALUE ary = (VALUE)tmp;
320
 
    if(cv->name) return;
321
 
    rb_ary_push(ary, rb_str_new2(cv->section));
322
 
}
323
 
 
324
 
static IMPLEMENT_LHASH_DOALL_ARG_FN(get_conf_section, CONF_VALUE, void)
325
 
 
326
 
static VALUE
327
 
ossl_config_get_sections(VALUE self)
328
 
{
329
 
    CONF *conf;
330
 
    VALUE ary;
331
 
 
332
 
    GetConfig(self, conf);
333
 
    ary = rb_ary_new();
334
 
    lh_doall_arg((_LHASH *)conf->data, LHASH_DOALL_ARG_FN(get_conf_section),
335
 
                 (void*)ary);
336
 
 
337
 
    return ary;
338
 
}
339
 
 
340
 
static void
341
 
dump_conf_value_doall_arg(CONF_VALUE *cv, void *tmp)
342
 
{
343
 
    VALUE str = (VALUE)tmp;
344
 
    STACK_OF(CONF_VALUE) *sk;
345
 
    CONF_VALUE *v;
346
 
    int i, num;
347
 
 
348
 
    if (cv->name) return;
349
 
    sk = (STACK_OF(CONF_VALUE)*)cv->value;
350
 
    num = sk_CONF_VALUE_num(sk);
351
 
    rb_str_cat2(str, "[ ");
352
 
    rb_str_cat2(str, cv->section);
353
 
    rb_str_cat2(str, " ]\n");
354
 
    for(i = 0; i < num; i++){
355
 
        v = sk_CONF_VALUE_value(sk, i);
356
 
        rb_str_cat2(str, v->name ? v->name : "None");
357
 
        rb_str_cat2(str, "=");
358
 
        rb_str_cat2(str, v->value ? v->value : "None");
359
 
        rb_str_cat2(str, "\n");
360
 
    }
361
 
    rb_str_cat2(str, "\n");
362
 
}
363
 
 
364
 
static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_conf_value, CONF_VALUE, void)
365
 
 
366
 
static VALUE
367
 
dump_conf(CONF *conf)
368
 
{
369
 
    VALUE str;
370
 
 
371
 
    str = rb_str_new(0, 0);
372
 
    lh_doall_arg((_LHASH *)conf->data, LHASH_DOALL_ARG_FN(dump_conf_value),
373
 
                 (void*)str);
374
 
 
375
 
    return str;
376
 
}
377
 
 
378
 
static VALUE
379
 
ossl_config_to_s(VALUE self)
380
 
{
381
 
    CONF *conf;
382
 
 
383
 
    GetConfig(self, conf);
384
 
 
385
 
    return dump_conf(conf);
386
 
}
387
 
 
388
 
static void
389
 
each_conf_value_doall_arg(CONF_VALUE *cv, void *dummy)
390
 
{
391
 
    STACK_OF(CONF_VALUE) *sk;
392
 
    CONF_VALUE *v;
393
 
    VALUE section, name, value, args;
394
 
    int i, num;
395
 
 
396
 
    if (cv->name) return;
397
 
    sk = (STACK_OF(CONF_VALUE)*)cv->value;
398
 
    num = sk_CONF_VALUE_num(sk);
399
 
    section = rb_str_new2(cv->section);
400
 
    for(i = 0; i < num; i++){
401
 
        v = sk_CONF_VALUE_value(sk, i);
402
 
        name = v->name ? rb_str_new2(v->name) : Qnil;
403
 
        value = v->value ? rb_str_new2(v->value) : Qnil;
404
 
        args = rb_ary_new3(3, section, name, value);
405
 
        rb_yield(args);
406
 
    }
407
 
}
408
 
 
409
 
static IMPLEMENT_LHASH_DOALL_ARG_FN(each_conf_value, CONF_VALUE, void *)
410
 
 
411
 
static VALUE
412
 
ossl_config_each(VALUE self)
413
 
{
414
 
    CONF *conf;
415
 
 
416
 
    RETURN_ENUMERATOR(self, 0, 0);
417
 
 
418
 
    GetConfig(self, conf);
419
 
    lh_doall_arg((_LHASH *)conf->data, LHASH_DOALL_ARG_FN(each_conf_value),
420
 
                 (void*)NULL);
421
 
 
422
 
    return self;
423
 
}
424
 
#else
425
 
static VALUE
426
 
ossl_config_get_sections(VALUE self)
427
 
{
428
 
    rb_warn("#sections don't work with %s", OPENSSL_VERSION_TEXT);
429
 
    return rb_ary_new();
430
 
}
431
 
 
432
 
static VALUE
433
 
ossl_config_to_s(VALUE self)
434
 
{
435
 
    rb_warn("#to_s don't work with %s", OPENSSL_VERSION_TEXT);
436
 
    return rb_str_new(0, 0);
437
 
}
438
 
 
439
 
static VALUE
440
 
ossl_config_each(VALUE self)
441
 
{
442
 
    rb_warn("#each don't work with %s", OPENSSL_VERSION_TEXT);
443
 
    return self;
444
 
}
445
 
#endif
446
 
 
447
 
static VALUE
448
 
ossl_config_inspect(VALUE self)
449
 
{
450
 
    VALUE str, ary = ossl_config_get_sections(self);
451
 
    const char *cname = rb_class2name(rb_obj_class(self));
452
 
 
453
 
    str = rb_str_new2("#<");
454
 
    rb_str_cat2(str, cname);
455
 
    rb_str_cat2(str, " sections=");
456
 
    rb_str_append(str, rb_inspect(ary));
457
 
    rb_str_cat2(str, ">");
458
 
 
459
 
    return str;
460
 
}
461
60
 
462
61
/*
463
62
 * INIT
473
72
    rb_define_const(cConfig, "DEFAULT_CONFIG_FILE",
474
73
                    rb_str_new2(default_config_file));
475
74
    OPENSSL_free(default_config_file);
476
 
    rb_include_module(cConfig, rb_mEnumerable);
477
 
    rb_define_singleton_method(cConfig, "parse", ossl_config_s_parse, 1);
478
 
    rb_define_alias(CLASS_OF(cConfig), "load", "new");
479
 
    rb_define_alloc_func(cConfig, ossl_config_s_alloc);
480
 
    rb_define_copy_func(cConfig, ossl_config_copy);
481
 
    rb_define_method(cConfig, "initialize", ossl_config_initialize, -1);
482
 
    rb_define_method(cConfig, "get_value", ossl_config_get_value, 2);
483
 
    rb_define_method(cConfig, "value", ossl_config_get_value_old, -1);
484
 
    rb_define_method(cConfig, "add_value", ossl_config_add_value_m, 3);
485
 
    rb_define_method(cConfig, "[]", ossl_config_get_section, 1);
486
 
    rb_define_method(cConfig, "section", ossl_config_get_section_old, 1);
487
 
    rb_define_method(cConfig, "[]=", ossl_config_set_section, 2);
488
 
    rb_define_method(cConfig, "sections", ossl_config_get_sections, 0);
489
 
    rb_define_method(cConfig, "to_s", ossl_config_to_s, 0);
490
 
    rb_define_method(cConfig, "each", ossl_config_each, 0);
491
 
    rb_define_method(cConfig, "inspect", ossl_config_inspect, 0);
 
75
    /* methods are defined by openssl/config.rb */
492
76
}