summaryrefslogtreecommitdiff
path: root/ext/openssl/ossl_config.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/openssl/ossl_config.c')
-rw-r--r--ext/openssl/ossl_config.c624
1 files changed, 333 insertions, 291 deletions
diff --git a/ext/openssl/ossl_config.c b/ext/openssl/ossl_config.c
index 7e6f696d33..274875a978 100644
--- a/ext/openssl/ossl_config.c
+++ b/ext/openssl/ossl_config.c
@@ -1,414 +1,456 @@
/*
- * $Id$
* 'OpenSSL for Ruby' project
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
* All rights reserved.
*/
/*
- * This program is licenced under the same licence as Ruby.
- * (See the file 'LICENCE'.)
+ * This program is licensed under the same licence as Ruby.
+ * (See the file 'COPYING'.)
*/
#include "ossl.h"
-#define WrapConfig(klass, obj, conf) do { \
- if (!conf) { \
- ossl_raise(rb_eRuntimeError, "Config wasn't intitialized!"); \
- } \
- obj = Data_Wrap_Struct(klass, 0, NCONF_free, conf); \
-} while (0)
-#define GetConfig(obj, conf) do { \
- Data_Get_Struct(obj, CONF, conf); \
- if (!conf) { \
- ossl_raise(rb_eRuntimeError, "Config wasn't intitialized!"); \
- } \
-} while (0)
-#define SafeGetConfig(obj, conf) do { \
- OSSL_Check_Kind(obj, cConfig); \
- GetConfig(obj, conf); \
-} while(0);
+static VALUE cConfig, eConfigError;
-/*
- * Classes
- */
-VALUE cConfig;
-VALUE eConfigError;
-
-/*
- * Public
- */
+static void
+nconf_free(void *conf)
+{
+ NCONF_free(conf);
+}
-static CONF *parse_config(VALUE, CONF*);
+static const rb_data_type_t ossl_config_type = {
+ "OpenSSL/CONF",
+ {
+ 0, nconf_free,
+ },
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
+};
CONF *
-GetConfigPtr(VALUE obj)
+GetConfig(VALUE obj)
{
CONF *conf;
- SafeGetConfig(obj, conf);
-
+ TypedData_Get_Struct(obj, CONF, &ossl_config_type, conf);
+ if (!conf)
+ rb_raise(rb_eRuntimeError, "CONF is not initialized");
return conf;
}
-CONF *
-DupConfigPtr(VALUE obj)
+static VALUE
+config_s_alloc(VALUE klass)
{
- VALUE str;
-
- OSSL_Check_Kind(obj, cConfig);
- str = rb_funcall(obj, rb_intern("to_s"), 0);
+ VALUE obj;
+ CONF *conf;
- return parse_config(str, NULL);
+ obj = TypedData_Wrap_Struct(klass, &ossl_config_type, 0);
+ conf = NCONF_new(NULL);
+ if (!conf)
+ ossl_raise(eConfigError, "NCONF_new");
+ RTYPEDDATA_DATA(obj) = conf;
+ return obj;
}
-/*
- * Private
- */
-static CONF *
-parse_config(VALUE str, CONF *dst)
+static void
+config_load_bio(CONF *conf, BIO *bio)
{
- CONF *conf;
- BIO *bio;
long eline = -1;
- bio = ossl_obj2bio(str);
- conf = dst ? dst : NCONF_new(NULL);
- if(!conf){
- BIO_free(bio);
- ossl_raise(eConfigError, NULL);
- }
- if(!NCONF_load_bio(conf, bio, &eline)){
- BIO_free(bio);
- if(!dst) NCONF_free(conf);
- if (eline <= 0) ossl_raise(eConfigError, "wrong config format");
- else ossl_raise(eConfigError, "error in line %d", eline);
- ossl_raise(eConfigError, NULL);
+ if (!NCONF_load_bio(conf, bio, &eline)) {
+ BIO_free(bio);
+ if (eline <= 0)
+ ossl_raise(eConfigError, "wrong config format");
+ else
+ ossl_raise(eConfigError, "error in line %ld", eline);
}
BIO_free(bio);
- return conf;
-}
-
-static VALUE
-ossl_config_s_parse(VALUE klass, VALUE str)
-{
- CONF *conf;
- VALUE obj;
-
- conf = parse_config(str, NULL);
- WrapConfig(klass, obj, conf);
-
- return obj;
+ /*
+ * Clear the error queue even if it is parsed successfully.
+ * Particularly, when the .include directive refers to a non-existent file,
+ * it is only reported in the error queue.
+ */
+ ossl_clear_error();
}
+/*
+ * call-seq:
+ * Config.parse(string) -> OpenSSL::Config
+ *
+ * Parses a given _string_ as a blob that contains configuration for OpenSSL.
+ */
static VALUE
-ossl_config_s_alloc(VALUE klass)
+config_s_parse(VALUE klass, VALUE str)
{
- CONF *conf;
- VALUE obj;
-
- if(!(conf = NCONF_new(NULL)))
- ossl_raise(eConfigError, NULL);
- WrapConfig(klass, obj, conf);
+ VALUE obj = config_s_alloc(klass);
+ CONF *conf = GetConfig(obj);
+ BIO *bio;
+ bio = ossl_obj2bio(&str);
+ config_load_bio(conf, bio); /* Consumes BIO */
+ rb_obj_freeze(obj);
return obj;
}
-static VALUE
-ossl_config_copy(VALUE self, VALUE other)
-{
- VALUE str;
- CONF *conf;
-
- GetConfig(other, conf);
- str = rb_funcall(self, rb_intern("to_s"), 0);
- parse_config(str, conf);
-
- return self;
-}
+static VALUE config_get_sections(VALUE self);
+static VALUE config_get_section(VALUE self, VALUE section);
+/*
+ * call-seq:
+ * Config.parse_config(io) -> hash
+ *
+ * Parses the configuration data read from _io_ and returns the whole content
+ * as a Hash.
+ */
static VALUE
-ossl_config_initialize(int argc, VALUE *argv, VALUE self)
+config_s_parse_config(VALUE klass, VALUE io)
{
- CONF *conf;
- long eline = -1;
- char *filename;
- VALUE path;
-
- GetConfig(self, conf);
- rb_scan_args(argc, argv, "01", &path);
- if(!NIL_P(path)){
- SafeStringValue(path);
- filename = StringValuePtr(path);
- if (!NCONF_load(conf, filename, &eline)){
- if (eline <= 0)
- ossl_raise(eConfigError, "wrong config file %s", filename);
- else
- ossl_raise(eConfigError, "error in %s:%d", filename, eline);
- }
+ VALUE obj, sections, ret;
+ long i;
+
+ obj = config_s_parse(klass, io);
+ sections = config_get_sections(obj);
+ ret = rb_hash_new();
+ for (i = 0; i < RARRAY_LEN(sections); i++) {
+ VALUE section = rb_ary_entry(sections, i);
+ rb_hash_aset(ret, section, config_get_section(obj, section));
}
-#ifdef OSSL_NO_CONF_API
- else rb_raise(rb_eArgError, "wrong number of arguments(0 for 1)");
-#else
- else _CONF_new_data(conf);
-#endif
-
- return self;
+ return ret;
}
+/*
+ * call-seq:
+ * Config.new(filename) -> OpenSSL::Config
+ *
+ * Creates an instance of OpenSSL::Config from the content of the file
+ * specified by _filename_.
+ *
+ * This can be used in contexts like OpenSSL::X509::ExtensionFactory.config=
+ *
+ * This can raise IO exceptions based on the access, or availability of the
+ * file. A ConfigError exception may be raised depending on the validity of
+ * the data being configured.
+ */
static VALUE
-ossl_config_add_value(VALUE self, VALUE section, VALUE name, VALUE value)
+config_initialize(int argc, VALUE *argv, VALUE self)
{
-#ifdef OSSL_NO_CONF_API
- rb_notimplement();
-#else
- CONF *conf;
- CONF_VALUE *sv, *cv;
-
- GetConfig(self, conf);
- StringValue(section);
- StringValue(name);
- StringValue(value);
- if(!(sv = _CONF_get_section(conf, RSTRING(section)->ptr))){
- if(!(sv = _CONF_new_section(conf, RSTRING(section)->ptr))){
- ossl_raise(eConfigError, NULL);
- }
- }
- if(!(cv = OPENSSL_malloc(sizeof(CONF_VALUE)))){
- ossl_raise(eConfigError, NULL);
+ CONF *conf = GetConfig(self);
+ VALUE filename;
+
+ /* 0-arguments call has no use-case, but is kept for compatibility */
+ rb_scan_args(argc, argv, "01", &filename);
+ rb_check_frozen(self);
+ if (!NIL_P(filename)) {
+ BIO *bio = BIO_new_file(StringValueCStr(filename), "rb");
+ if (!bio)
+ ossl_raise(eConfigError, "BIO_new_file");
+ config_load_bio(conf, bio); /* Consumes BIO */
}
- cv->name = BUF_strdup(RSTRING(name)->ptr);
- cv->value = BUF_strdup(RSTRING(value)->ptr);
- if(!cv->name || !cv->value || !_CONF_add_string(conf, sv, cv)){
- OPENSSL_free(cv->name);
- OPENSSL_free(cv->value);
- OPENSSL_free(cv);
- ossl_raise(eConfigError, "_CONF_add_string failure");
- }
-
- return value;
-#endif
+ rb_obj_freeze(self);
+ return self;
}
static VALUE
-ossl_config_get_value(VALUE self, VALUE section, VALUE name)
+config_initialize_copy(VALUE self, VALUE other)
{
- CONF *conf;
- char *str;
-
- GetConfig(self, conf);
- StringValue(section);
- StringValue(name);
- str = NCONF_get_string(conf, RSTRING(section)->ptr, RSTRING(name)->ptr);
- if(!str){
- ERR_clear_error();
- return Qnil;
- }
+ CONF *conf = GetConfig(self);
+ VALUE str;
+ BIO *bio;
- return rb_str_new2(str);
+ str = rb_funcall(other, rb_intern("to_s"), 0);
+ rb_check_frozen(self);
+ bio = ossl_obj2bio(&str);
+ config_load_bio(conf, bio); /* Consumes BIO */
+ rb_obj_freeze(self);
+ return self;
}
+/*
+ * call-seq:
+ * config.get_value(section, key) -> string
+ *
+ * Gets the value of _key_ from the given _section_.
+ *
+ * Given the following configurating file being loaded:
+ *
+ * config = OpenSSL::Config.load('foo.cnf')
+ * #=> #<OpenSSL::Config sections=["default"]>
+ * puts config.to_s
+ * #=> [ default ]
+ * # foo=bar
+ *
+ * You can get a specific value from the config if you know the _section_
+ * and _key_ like so:
+ *
+ * config.get_value('default','foo')
+ * #=> "bar"
+ */
static VALUE
-ossl_config_get_value_old(int argc, VALUE *argv, VALUE self)
+config_get_value(VALUE self, VALUE section, VALUE key)
{
- VALUE section, name;
-
- rb_scan_args(argc, argv, "11", &section, &name);
-
- /* support conf.value(nil, "HOME") -> conf.get_value("", "HOME") */
- if (NIL_P(section)) section = rb_str_new2("");
- /* support conf.value("HOME") -> conf.get_value("", "HOME") */
- if (NIL_P(name)) {
- name = section;
- section = rb_str_new2("");
+ CONF *conf = GetConfig(self);
+ const char *str, *sectionp;
+
+ StringValueCStr(section);
+ StringValueCStr(key);
+ /* For compatibility; NULL means "default". */
+ sectionp = RSTRING_LEN(section) ? RSTRING_PTR(section) : NULL;
+ str = NCONF_get_string(conf, sectionp, RSTRING_PTR(key));
+ if (!str) {
+ ossl_clear_error();
+ return Qnil;
}
- /* NOTE: Don't care about conf.get_value(nil, nil) */
- rb_warn("Config#value is deprecated; use Config#get_value");
- return ossl_config_get_value(self, section, name);
-}
-
-static VALUE
-set_conf_section_i(VALUE i, VALUE *arg)
-{
- VALUE name, value;
-
- Check_Type(i, T_ARRAY);
- name = rb_ary_entry(i, 0);
- value = rb_ary_entry(i, 1);
- ossl_config_add_value(arg[0], arg[1], name, value);
-
- return Qnil;
-}
-
-static VALUE
-ossl_config_set_section(VALUE self, VALUE section, VALUE hash)
-{
- VALUE arg[2] = { self, section };
- rb_iterate(rb_each, hash, set_conf_section_i, (VALUE)arg);
- return hash;
+ return rb_str_new_cstr(str);
}
/*
- * Get all numbers as strings - use str.to_i to convert
- * long number = CONF_get_number(confp->config, sect, StringValuePtr(item));
+ * call-seq:
+ * config[section] -> hash
+ *
+ * Gets all key-value pairs in a specific _section_ from the current
+ * configuration.
+ *
+ * Given the following configurating file being loaded:
+ *
+ * config = OpenSSL::Config.load('foo.cnf')
+ * #=> #<OpenSSL::Config sections=["default"]>
+ * puts config.to_s
+ * #=> [ default ]
+ * # foo=bar
+ *
+ * You can get a hash of the specific section like so:
+ *
+ * config['default']
+ * #=> {"foo"=>"bar"}
+ *
*/
static VALUE
-ossl_config_get_section(VALUE self, VALUE section)
+config_get_section(VALUE self, VALUE section)
{
- CONF *conf;
+ CONF *conf = GetConfig(self);
STACK_OF(CONF_VALUE) *sk;
- CONF_VALUE *entry;
int i, entries;
VALUE hash;
hash = rb_hash_new();
- GetConfig(self, conf);
- if (!(sk = NCONF_get_section(conf, StringValuePtr(section)))) {
- ERR_clear_error();
- return hash;
+ StringValueCStr(section);
+ if (!(sk = NCONF_get_section(conf, RSTRING_PTR(section)))) {
+ ossl_clear_error();
+ return hash;
}
- if ((entries = sk_CONF_VALUE_num(sk)) < 0) {
- OSSL_Debug("# of items in section is < 0?!?");
- return hash;
+ entries = sk_CONF_VALUE_num(sk);
+ for (i = 0; i < entries; i++) {
+ CONF_VALUE *entry = sk_CONF_VALUE_value(sk, i);
+ rb_hash_aset(hash, rb_str_new_cstr(entry->name),
+ rb_str_new_cstr(entry->value));
}
- for (i=0; i<entries; i++) {
- entry = sk_CONF_VALUE_value(sk, i);
- rb_hash_aset(hash, rb_str_new2(entry->name), rb_str_new2(entry->value));
- }
-
return hash;
}
-static VALUE
-ossl_config_get_section_old(VALUE self, VALUE section)
-{
- rb_warn("Config#section is deprecated; use Config#[]");
- return ossl_config_get_section(self, section);
-}
-
-#ifdef IMPLEMENT_LHASH_DOALL_ARG_FN
static void
-get_conf_section(CONF_VALUE *cv, VALUE ary)
+get_conf_section_doall_arg(CONF_VALUE *cv, VALUE *aryp)
{
- if(cv->name) return;
- rb_ary_push(ary, rb_str_new2(cv->section));
+ if (cv->name)
+ return;
+ rb_ary_push(*aryp, rb_str_new_cstr(cv->section));
}
-static IMPLEMENT_LHASH_DOALL_ARG_FN(get_conf_section, CONF_VALUE*, VALUE);
+/* IMPLEMENT_LHASH_DOALL_ARG_CONST() requires >= OpenSSL 1.1.0 */
+static IMPLEMENT_LHASH_DOALL_ARG_FN(get_conf_section, CONF_VALUE, VALUE)
+/*
+ * call-seq:
+ * config.sections -> array of string
+ *
+ * Get the names of all sections in the current configuration.
+ */
static VALUE
-ossl_config_get_sections(VALUE self)
+config_get_sections(VALUE self)
{
- CONF *conf;
+ CONF *conf = GetConfig(self);
VALUE ary;
- GetConfig(self, conf);
ary = rb_ary_new();
- lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(get_conf_section), (void*)ary);
-
+ lh_doall_arg((_LHASH *)conf->data, LHASH_DOALL_ARG_FN(get_conf_section),
+ &ary);
return ary;
}
-#else
-static VALUE
-ossl_config_get_sections(VALUE self)
-{
- rb_warn("Config::sections don't work with %s", OPENSSL_VERSION_TEXT);
- return rb_ary_new();
-}
-#endif
-#ifdef IMPLEMENT_LHASH_DOALL_ARG_FN
static void
-dump_conf_value(CONF_VALUE *cv, VALUE str)
+dump_conf_value_doall_arg(CONF_VALUE *cv, VALUE *strp)
{
+ VALUE str = *strp;
STACK_OF(CONF_VALUE) *sk;
- CONF_VALUE *v;
int i, num;
- if (cv->name) return;
- sk = (STACK_OF(CONF_VALUE)*)cv->value;
+ if (cv->name)
+ return;
+ sk = (STACK_OF(CONF_VALUE) *)cv->value;
num = sk_CONF_VALUE_num(sk);
- rb_str_cat2(str, "[ ");
- rb_str_cat2(str, cv->section);
- rb_str_cat2(str, " ]\n");
- for(i = 0; i < num; i++){
- v = sk_CONF_VALUE_value(sk, i);
- rb_str_cat2(str, v->name ? v->name : "None");
- rb_str_cat2(str, "=");
- rb_str_cat2(str, v->value ? v->value : "None");
- rb_str_cat2(str, "\n");
+ rb_str_cat_cstr(str, "[ ");
+ rb_str_cat_cstr(str, cv->section);
+ rb_str_cat_cstr(str, " ]\n");
+ for (i = 0; i < num; i++){
+ CONF_VALUE *v = sk_CONF_VALUE_value(sk, i);
+ rb_str_cat_cstr(str, v->name ? v->name : "None");
+ rb_str_cat_cstr(str, "=");
+ rb_str_cat_cstr(str, v->value ? v->value : "None");
+ rb_str_cat_cstr(str, "\n");
}
- rb_str_cat2(str, "\n");
+ rb_str_cat_cstr(str, "\n");
}
-static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_conf_value, CONF_VALUE*, VALUE);
+static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_conf_value, CONF_VALUE, VALUE)
+/*
+ * call-seq:
+ * config.to_s -> string
+ *
+ *
+ * Gets the parsable form of the current configuration.
+ *
+ * Given the following configuration file being loaded:
+ *
+ * config = OpenSSL::Config.load('baz.cnf')
+ * #=> #<OpenSSL::Config sections=["default"]>
+ * puts config.to_s
+ * #=> [ default ]
+ * # foo=bar
+ * # baz=buz
+ *
+ * You can get the serialized configuration using #to_s and then parse
+ * it later:
+ *
+ * serialized_config = config.to_s
+ * # much later...
+ * new_config = OpenSSL::Config.parse(serialized_config)
+ * #=> #<OpenSSL::Config sections=["default"]>
+ * puts new_config
+ * #=> [ default ]
+ * foo=bar
+ * baz=buz
+ */
static VALUE
-dump_conf(CONF *conf)
+config_to_s(VALUE self)
{
+ CONF *conf = GetConfig(self);
VALUE str;
- str = rb_str_new(0, 0);
- lh_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_conf_value), (void*)str);
-
+ str = rb_str_new(NULL, 0);
+ lh_doall_arg((_LHASH *)conf->data, LHASH_DOALL_ARG_FN(dump_conf_value),
+ &str);
return str;
}
-static VALUE
-ossl_config_to_s(VALUE self)
+static void
+each_conf_value_doall_arg(CONF_VALUE *cv, void *unused)
{
- CONF *conf;
-
- GetConfig(self, conf);
+ STACK_OF(CONF_VALUE) *sk;
+ VALUE section;
+ int i, num;
- return dump_conf(conf);
+ if (cv->name)
+ return;
+ sk = (STACK_OF(CONF_VALUE) *)cv->value;
+ num = sk_CONF_VALUE_num(sk);
+ section = rb_str_new_cstr(cv->section);
+ for (i = 0; i < num; i++){
+ CONF_VALUE *v = sk_CONF_VALUE_value(sk, i);
+ VALUE name = v->name ? rb_str_new_cstr(v->name) : Qnil;
+ VALUE value = v->value ? rb_str_new_cstr(v->value) : Qnil;
+ rb_yield(rb_ary_new3(3, section, name, value));
+ }
}
-#else
+
+static IMPLEMENT_LHASH_DOALL_ARG_FN(each_conf_value, CONF_VALUE, void)
+
+/*
+ * call-seq:
+ * config.each { |section, key, value| }
+ *
+ * Retrieves the section and its pairs for the current configuration.
+ *
+ * config.each do |section, key, value|
+ * # ...
+ * end
+ */
static VALUE
-ossl_config_to_s(VALUE self)
+config_each(VALUE self)
{
- rb_warn("Config::to_s don't work with %s", OPENSSL_VERSION_TEXT);
- return rb_str_new(0, 0);
+ CONF *conf = GetConfig(self);
+
+ RETURN_ENUMERATOR(self, 0, 0);
+
+ lh_doall_arg((_LHASH *)conf->data, LHASH_DOALL_ARG_FN(each_conf_value),
+ NULL);
+ return self;
}
-#endif
+/*
+ * call-seq:
+ * config.inspect -> string
+ *
+ * String representation of this configuration object, including the class
+ * name and its sections.
+ */
static VALUE
-ossl_config_inspect(VALUE self)
+config_inspect(VALUE self)
{
- VALUE str, ary = ossl_config_get_sections(self);
- char *cname = rb_class2name(rb_obj_class(self));
+ VALUE str, ary = config_get_sections(self);
+ const char *cname = rb_class2name(rb_obj_class(self));
- str = rb_str_new2("#<");
- rb_str_cat2(str, cname);
- rb_str_cat2(str, " sections=");
+ str = rb_str_new_cstr("#<");
+ rb_str_cat_cstr(str, cname);
+ rb_str_cat_cstr(str, " sections=");
rb_str_append(str, rb_inspect(ary));
- rb_str_cat2(str, ">");
+ rb_str_cat_cstr(str, ">");
return str;
}
-/*
- * INIT
- */
void
-Init_ossl_config()
+Init_ossl_config(void)
{
- eConfigError = rb_define_class_under(mOSSL, "ConfigError", eOSSLError);
+ char *path;
+ VALUE path_str;
+
+ /* Document-class: OpenSSL::Config
+ *
+ * Configuration for the openssl library.
+ *
+ * Many system's installation of openssl library will depend on your system
+ * configuration. See the value of OpenSSL::Config::DEFAULT_CONFIG_FILE for
+ * the location of the file for your host.
+ *
+ * See also https://docs.openssl.org/master/man5/config/
+ */
cConfig = rb_define_class_under(mOSSL, "Config", rb_cObject);
- rb_define_const(cConfig, "DEFAULT_CONFIG_FILE",
- rb_str_new2(CONF_get1_default_config_file()));
- rb_define_singleton_method(cConfig, "parse", ossl_config_s_parse, 1);
+ /* Document-class: OpenSSL::ConfigError
+ *
+ * General error for openssl library configuration files. Including formatting,
+ * parsing errors, etc.
+ */
+ eConfigError = rb_define_class_under(mOSSL, "ConfigError", eOSSLError);
+
+ rb_include_module(cConfig, rb_mEnumerable);
+ rb_define_singleton_method(cConfig, "parse", config_s_parse, 1);
+ rb_define_singleton_method(cConfig, "parse_config", config_s_parse_config, 1);
rb_define_alias(CLASS_OF(cConfig), "load", "new");
- rb_define_alloc_func(cConfig, ossl_config_s_alloc);
- rb_define_copy_func(cConfig, ossl_config_copy);
- rb_define_method(cConfig, "initialize", ossl_config_initialize, -1);
- rb_define_method(cConfig, "get_value", ossl_config_get_value, 2);
- rb_define_method(cConfig, "value", ossl_config_get_value_old, -1);
- rb_define_method(cConfig, "add_value", ossl_config_add_value, 3);
- rb_define_method(cConfig, "[]", ossl_config_get_section, 1);
- rb_define_method(cConfig, "section", ossl_config_get_section_old, 1);
- rb_define_method(cConfig, "[]=", ossl_config_set_section, 2);
- rb_define_method(cConfig, "sections", ossl_config_get_sections, 0);
- rb_define_method(cConfig, "to_s", ossl_config_to_s, 0);
- rb_define_method(cConfig, "inspect", ossl_config_inspect, 0);
+ rb_define_alloc_func(cConfig, config_s_alloc);
+ rb_define_method(cConfig, "initialize", config_initialize, -1);
+ rb_define_method(cConfig, "initialize_copy", config_initialize_copy, 1);
+ rb_define_method(cConfig, "get_value", config_get_value, 2);
+ rb_define_method(cConfig, "[]", config_get_section, 1);
+ rb_define_method(cConfig, "sections", config_get_sections, 0);
+ rb_define_method(cConfig, "to_s", config_to_s, 0);
+ rb_define_method(cConfig, "each", config_each, 0);
+ rb_define_method(cConfig, "inspect", config_inspect, 0);
+
+ /* Document-const: DEFAULT_CONFIG_FILE
+ *
+ * The default system configuration file for OpenSSL.
+ */
+ path = CONF_get1_default_config_file();
+ path_str = rb_obj_freeze(ossl_buf2str(path, rb_long2int(strlen(path))));
+ rb_define_const(cConfig, "DEFAULT_CONFIG_FILE", path_str);
}