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.
escape with backslash
escape with backslash and doubled dq
escaped char map
The default system configuration file for openssl
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 193
def clear_comments(line)
# FCOMMENT
if m = line.match(/\A([\t\n\f ]*);.*\z/)
return m[1]
end
# COMMENT
scanned = []
while m = line.match(/[#'"\\]/)
scanned << m.pre_match
c = m[0]
line = m.post_match
case c
when '#'
line = nil
break
when "'", '"'
regexp = (c == "'") ? QUOTE_REGEXP_SQ : QUOTE_REGEXP_DQ
scanned << c
if m = line.match(regexp)
scanned << m[0]
line = m.post_match
else
scanned << line
line = nil
break
end
when "\\"
scanned << c
scanned << line.slice!(0, 1)
else
raise 'must not reaced'
end
end
scanned << line
scanned.join
end
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 178
def extract_reference(value)
rest = ''
if m = value.match(/\(([^)]*)\)|\{([^}]*)\}/)
value = m[1] || m[2]
rest = m.post_match
elsif [?(, ?{].include?(value[0])
raise ConfigError, "no close brace"
end
if m = value.match(/[a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]*)?/)
return m[0], m.post_match + rest
else
raise
end
end
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 230
def get_definition(io_stack)
if line = get_line(io_stack)
while /[^\\]\\\z/ =~ line
if extra = get_line(io_stack)
line += extra
else
break
end
end
return line.strip
end
end
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 243
def get_line(io_stack)
while io = io_stack.last
if line = io.gets
return line.gsub(/[\r\n]*/, '')
end
io_stack.pop
end
end
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 265
def initialize(filename = nil)
@data = {}
if filename
File.open(filename.to_s) do |file|
Config.parse_config(file).each do |section, hash|
self[section] = hash
end
end
end
end
Creates an instance of OpenSSL’s configuration class.
This can be used in contexts like OpenSSL::X509::ExtensionFactory.config=
If the optional filename parameter is provided, then it is read in and parsed via parse_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.
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 37
def parse(string)
c = new()
parse_config(StringIO.new(string)).each do |section, hash|
c[section] = hash
end
c
end
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 53
def parse_config(io)
begin
parse_config_lines(io)
rescue ConfigError => e
e.message.replace("error in line #{io.lineno}: " + e.message)
raise
end
end
Parses the configuration data read from io, see also parse.
Raises a ConfigError
on invalid configuration data.
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 77
def parse_config_lines(io)
section = 'default'
data = {section => {}}
io_stack = [io]
while definition = get_definition(io_stack)
definition = clear_comments(definition)
next if definition.empty?
case definition
when /\A\[/
if /\[([^\]]*)\]/ =~ definition
section = $1.strip
data[section] ||= {}
else
raise ConfigError, "missing close square bracket"
end
when /\A\.include (\s*=\s*)?(.+)\z/
path = $2
if File.directory?(path)
files = Dir.glob(File.join(path, "*.{cnf,conf}"), File::FNM_EXTGLOB)
else
files = [path]
end
files.each do |filename|
begin
io_stack << StringIO.new(File.read(filename))
rescue
raise ConfigError, "could not include file '%s'" % filename
end
end
when /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/
if $2
section = $1
key = $2
else
key = $1
end
value = unescape_value(data, section, $3)
(data[section] ||= {})[key] = value.strip
else
raise ConfigError, "missing equal sign"
end
end
data
end
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 135
def unescape_value(data, section, value)
scanned = []
while m = value.match(/['"\\$]/)
scanned << m.pre_match
c = m[0]
value = m.post_match
case c
when "'"
if m = value.match(QUOTE_REGEXP_SQ)
scanned << m[1].gsub(/\\(.)/, '\\1')
value = m.post_match
else
break
end
when '"'
if m = value.match(QUOTE_REGEXP_DQ)
scanned << m[1].gsub(/""/, '').gsub(/\\(.)/, '\\1')
value = m.post_match
else
break
end
when "\\"
c = value.slice!(0, 1)
scanned << (ESCAPE_MAP[c] || c)
when "$"
ref, value = extract_reference(value)
refsec = section
if ref.index('::')
refsec, ref = ref.split('::', 2)
end
if v = get_key_string(data, refsec, ref)
scanned << v
else
raise ConfigError, "variable has no value"
end
else
raise 'must not reaced'
end
end
scanned << value
scanned.join
end
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 359
def [](section)
@data[section] || {}
end
Get 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"}
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 396
def []=(section, pairs)
check_modify
@data[section] ||= {}
pairs.each do |key, value|
self.add_value(section, key, value)
end
end
Sets a specific section name with a Hash
pairs.
Given the following configuration being created:
config = OpenSSL::Config.new #=> #<OpenSSL::Config sections=[]> config['default'] = {"foo"=>"bar","baz"=>"buz"} #=> {"foo"=>"bar", "baz"=>"buz"} puts config.to_s #=> [ default ] # foo=bar # baz=buz
It’s important to note that this will essentially merge any of the keys in pairs with the existing section. For example:
config['default'] #=> {"foo"=>"bar", "baz"=>"buz"} config['default'] = {"foo" => "changed"} #=> {"foo"=>"changed"} config['default'] #=> {"foo"=>"changed", "baz"=>"buz"}
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 338
def add_value(section, key, value)
check_modify
(@data[section] ||= {})[key] = value
end
Set
the target key with a given value under a specific 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 set the value of foo under the default section to a new value:
config.add_value('default', 'foo', 'buzz') #=> "buzz" puts config.to_s #=> [ default ] # foo=buzz
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 484
def check_modify
raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen?
end
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 457
def each
@data.each do |section, hash|
hash.each do |key, value|
yield [section, key, value]
end
end
end
For a block.
Receive the section and its pairs for the current configuration.
config.each do |section, key, value| # ... end
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 488
def get_key_string(section, key)
Config.get_key_string(@data, section, key)
end
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 293
def get_value(section, key)
if section.nil?
raise TypeError.new('nil not allowed')
end
section = 'default' if section.empty?
get_key_string(section, key)
end
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"
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 480
def initialize_copy(other)
@data = other.data.dup
end
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 468
def inspect
"#<#{self.class.name} sections=#{sections.inspect}>"
end
String
representation of this configuration object, including the class name and its sections.
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 406
def sections
@data.keys
end
Get the names of all sections in the current configuration
# File tmp/rubies/ruby-2.7.6/ext/openssl/lib/openssl/config.rb, line 436
def to_s
ary = []
@data.keys.sort.each do |section|
ary << "[ #{section} ]\n"
@data[section].keys.each do |key|
ary << "#{key}=#{@data[section][key]}\n"
end
ary << "\n"
end
ary.join
end
Get the parsable form of the current configuration
Given the following configuration being created:
config = OpenSSL::Config.new #=> #<OpenSSL::Config sections=[]> config['default'] = {"foo"=>"bar","baz"=>"buz"} #=> {"foo"=>"bar", "baz"=>"buz"} puts config.to_s #=> [ default ] # foo=bar # baz=buz
You can parse 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