rubysl-openssl 0.0.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +0 -1
  3. data/.travis.yml +7 -0
  4. data/README.md +2 -2
  5. data/Rakefile +0 -1
  6. data/ext/rubysl/openssl/extconf.h +50 -0
  7. data/ext/rubysl/openssl/extconf.rb +144 -0
  8. data/ext/rubysl/openssl/openssl_missing.c +343 -0
  9. data/ext/rubysl/openssl/openssl_missing.h +191 -0
  10. data/ext/rubysl/openssl/ossl.c +552 -0
  11. data/ext/rubysl/openssl/ossl.h +233 -0
  12. data/ext/rubysl/openssl/ossl_asn1.c +1160 -0
  13. data/ext/rubysl/openssl/ossl_asn1.h +59 -0
  14. data/ext/rubysl/openssl/ossl_bio.c +86 -0
  15. data/ext/rubysl/openssl/ossl_bio.h +21 -0
  16. data/ext/rubysl/openssl/ossl_bn.c +852 -0
  17. data/ext/rubysl/openssl/ossl_bn.h +25 -0
  18. data/ext/rubysl/openssl/ossl_cipher.c +569 -0
  19. data/ext/rubysl/openssl/ossl_cipher.h +22 -0
  20. data/ext/rubysl/openssl/ossl_config.c +75 -0
  21. data/ext/rubysl/openssl/ossl_config.h +22 -0
  22. data/ext/rubysl/openssl/ossl_digest.c +259 -0
  23. data/ext/rubysl/openssl/ossl_digest.h +22 -0
  24. data/ext/rubysl/openssl/ossl_engine.c +411 -0
  25. data/ext/rubysl/openssl/ossl_engine.h +20 -0
  26. data/ext/rubysl/openssl/ossl_hmac.c +268 -0
  27. data/ext/rubysl/openssl/ossl_hmac.h +19 -0
  28. data/ext/rubysl/openssl/ossl_ns_spki.c +257 -0
  29. data/ext/rubysl/openssl/ossl_ns_spki.h +21 -0
  30. data/ext/rubysl/openssl/ossl_ocsp.c +769 -0
  31. data/ext/rubysl/openssl/ossl_ocsp.h +24 -0
  32. data/ext/rubysl/openssl/ossl_pkcs12.c +210 -0
  33. data/ext/rubysl/openssl/ossl_pkcs12.h +15 -0
  34. data/ext/rubysl/openssl/ossl_pkcs5.c +99 -0
  35. data/ext/rubysl/openssl/ossl_pkcs5.h +6 -0
  36. data/ext/rubysl/openssl/ossl_pkcs7.c +1039 -0
  37. data/ext/rubysl/openssl/ossl_pkcs7.h +22 -0
  38. data/ext/rubysl/openssl/ossl_pkey.c +240 -0
  39. data/ext/rubysl/openssl/ossl_pkey.h +141 -0
  40. data/ext/rubysl/openssl/ossl_pkey_dh.c +532 -0
  41. data/ext/rubysl/openssl/ossl_pkey_dsa.c +484 -0
  42. data/ext/rubysl/openssl/ossl_pkey_ec.c +1593 -0
  43. data/ext/rubysl/openssl/ossl_pkey_rsa.c +593 -0
  44. data/ext/rubysl/openssl/ossl_rand.c +202 -0
  45. data/ext/rubysl/openssl/ossl_rand.h +20 -0
  46. data/ext/rubysl/openssl/ossl_ssl.c +1484 -0
  47. data/ext/rubysl/openssl/ossl_ssl.h +36 -0
  48. data/ext/rubysl/openssl/ossl_ssl_session.c +307 -0
  49. data/ext/rubysl/openssl/ossl_version.h +16 -0
  50. data/ext/rubysl/openssl/ossl_x509.c +104 -0
  51. data/ext/rubysl/openssl/ossl_x509.h +114 -0
  52. data/ext/rubysl/openssl/ossl_x509attr.c +274 -0
  53. data/ext/rubysl/openssl/ossl_x509cert.c +764 -0
  54. data/ext/rubysl/openssl/ossl_x509crl.c +535 -0
  55. data/ext/rubysl/openssl/ossl_x509ext.c +458 -0
  56. data/ext/rubysl/openssl/ossl_x509name.c +399 -0
  57. data/ext/rubysl/openssl/ossl_x509req.c +466 -0
  58. data/ext/rubysl/openssl/ossl_x509revoked.c +229 -0
  59. data/ext/rubysl/openssl/ossl_x509store.c +625 -0
  60. data/ext/rubysl/openssl/ruby_missing.h +41 -0
  61. data/lib/openssl.rb +1 -0
  62. data/lib/openssl/bn.rb +35 -0
  63. data/lib/openssl/buffering.rb +241 -0
  64. data/lib/openssl/cipher.rb +65 -0
  65. data/lib/openssl/config.rb +316 -0
  66. data/lib/openssl/digest.rb +61 -0
  67. data/lib/openssl/net/ftptls.rb +53 -0
  68. data/lib/openssl/net/telnets.rb +251 -0
  69. data/lib/openssl/pkcs7.rb +25 -0
  70. data/lib/openssl/ssl-internal.rb +187 -0
  71. data/lib/openssl/ssl.rb +1 -0
  72. data/lib/openssl/x509-internal.rb +153 -0
  73. data/lib/openssl/x509.rb +1 -0
  74. data/lib/rubysl/openssl.rb +28 -0
  75. data/lib/rubysl/openssl/version.rb +5 -0
  76. data/rubysl-openssl.gemspec +19 -18
  77. data/spec/cipher_spec.rb +16 -0
  78. data/spec/config/freeze_spec.rb +17 -0
  79. data/spec/hmac/digest_spec.rb +15 -0
  80. data/spec/hmac/hexdigest_spec.rb +15 -0
  81. data/spec/random/pseudo_bytes_spec.rb +5 -0
  82. data/spec/random/random_bytes_spec.rb +5 -0
  83. data/spec/random/shared/random_bytes.rb +28 -0
  84. data/spec/shared/constants.rb +11 -0
  85. data/spec/x509/name/parse_spec.rb +47 -0
  86. metadata +153 -89
  87. data/lib/rubysl-openssl.rb +0 -7
  88. data/lib/rubysl-openssl/version.rb +0 -5
@@ -0,0 +1,41 @@
1
+ /*
2
+ * $Id: ruby_missing.h 12496 2007-06-08 15:02:04Z technorama $
3
+ * 'OpenSSL for Ruby' project
4
+ * Copyright (C) 2001-2003 Michal Rokos <m.rokos@sh.cvut.cz>
5
+ * All rights reserved.
6
+ */
7
+ /*
8
+ * This program is licenced under the same licence as Ruby.
9
+ * (See the file 'LICENCE'.)
10
+ */
11
+ #if !defined(_OSSL_RUBY_MISSING_H_)
12
+ #define _OSSL_RUBY_MISSING_H_
13
+
14
+ #define rb_define_copy_func(klass, func) \
15
+ rb_define_method(klass, "initialize_copy", func, 1)
16
+
17
+
18
+ #ifndef GetReadFile
19
+ #define FPTR_TO_FD(fptr) (fptr->fd)
20
+ #else
21
+ #define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))
22
+ #endif
23
+
24
+ #ifndef HAVE_RB_IO_T
25
+ #define rb_io_t OpenFile
26
+ #endif
27
+
28
+ #ifndef HAVE_RB_STR_SET_LEN
29
+ /* these methods should probably be backported to 1.8 */
30
+ #define rb_str_set_len(str, length) do { \
31
+ RSTRING(str)->ptr[length] = 0; \
32
+ RSTRING(str)->len = length; \
33
+ } while(0)
34
+ #endif /* ! HAVE_RB_STR_SET_LEN */
35
+
36
+ #ifndef HAVE_RB_BLOCK_CALL
37
+ /* the openssl module doesn't use arg[3-4] and arg2 is always rb_each */
38
+ #define rb_block_call(arg1, arg2, arg3, arg4, arg5, arg6) rb_iterate(rb_each, arg1, arg5, arg6)
39
+ #endif /* ! HAVE_RB_BLOCK_CALL */
40
+
41
+ #endif /* _OSSL_RUBY_MISSING_H_ */
@@ -0,0 +1 @@
1
+ require "rubysl/openssl"
@@ -0,0 +1,35 @@
1
+ =begin
2
+ = $RCSfile$ -- Ruby-space definitions that completes C-space funcs for BN
3
+
4
+ = Info
5
+ 'OpenSSL for Ruby 2' project
6
+ Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz>
7
+ All rights reserved.
8
+
9
+ = Licence
10
+ This program is licenced under the same licence as Ruby.
11
+ (See the file 'LICENCE'.)
12
+
13
+ = Version
14
+ $Id: bn.rb 31657 2011-05-20 22:25:35Z shyouhei $
15
+ =end
16
+
17
+ ##
18
+ # Should we care what if somebody require this file directly?
19
+ #require 'openssl'
20
+
21
+ module OpenSSL
22
+ class BN
23
+ include Comparable
24
+ end # BN
25
+ end # OpenSSL
26
+
27
+ ##
28
+ # Add double dispatch to Integer
29
+ #
30
+ class Integer
31
+ def to_bn
32
+ OpenSSL::BN::new(self.to_s(16), 16)
33
+ end
34
+ end # Integer
35
+
@@ -0,0 +1,241 @@
1
+ =begin
2
+ = $RCSfile$ -- Buffering mix-in module.
3
+
4
+ = Info
5
+ 'OpenSSL for Ruby 2' project
6
+ Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org>
7
+ All rights reserved.
8
+
9
+ = Licence
10
+ This program is licenced under the same licence as Ruby.
11
+ (See the file 'LICENCE'.)
12
+
13
+ = Version
14
+ $Id: buffering.rb 28004 2010-05-24 23:58:49Z shyouhei $
15
+ =end
16
+
17
+ module OpenSSL
18
+ module Buffering
19
+ include Enumerable
20
+ attr_accessor :sync
21
+ BLOCK_SIZE = 1024*16
22
+
23
+ def initialize(*args)
24
+ @eof = false
25
+ @rbuffer = ""
26
+ @sync = @io.sync
27
+ end
28
+
29
+ #
30
+ # for reading.
31
+ #
32
+ private
33
+
34
+ def fill_rbuff
35
+ begin
36
+ @rbuffer << self.sysread(BLOCK_SIZE)
37
+ rescue Errno::EAGAIN
38
+ retry
39
+ rescue EOFError
40
+ @eof = true
41
+ end
42
+ end
43
+
44
+ def consume_rbuff(size=nil)
45
+ if @rbuffer.empty?
46
+ nil
47
+ else
48
+ size = @rbuffer.size unless size
49
+ ret = @rbuffer[0, size]
50
+ @rbuffer[0, size] = ""
51
+ ret
52
+ end
53
+ end
54
+
55
+ public
56
+
57
+ def read(size=nil, buf=nil)
58
+ if size == 0
59
+ if buf
60
+ buf.clear
61
+ else
62
+ buf = ""
63
+ end
64
+ return @eof ? nil : buf
65
+ end
66
+ until @eof
67
+ break if size && size <= @rbuffer.size
68
+ fill_rbuff
69
+ end
70
+ ret = consume_rbuff(size) || ""
71
+ if buf
72
+ buf.replace(ret)
73
+ ret = buf
74
+ end
75
+ (size && ret.empty?) ? nil : ret
76
+ end
77
+
78
+ def readpartial(maxlen, buf=nil)
79
+ if maxlen == 0
80
+ if buf
81
+ buf.clear
82
+ else
83
+ buf = ""
84
+ end
85
+ return @eof ? nil : buf
86
+ end
87
+ if @rbuffer.empty?
88
+ begin
89
+ return sysread(maxlen, buf)
90
+ rescue Errno::EAGAIN
91
+ retry
92
+ end
93
+ end
94
+ ret = consume_rbuff(maxlen)
95
+ if buf
96
+ buf.replace(ret)
97
+ ret = buf
98
+ end
99
+ raise EOFError if ret.empty?
100
+ ret
101
+ end
102
+
103
+ def gets(eol=$/)
104
+ idx = @rbuffer.index(eol)
105
+ until @eof
106
+ break if idx
107
+ fill_rbuff
108
+ idx = @rbuffer.index(eol)
109
+ end
110
+ if eol.is_a?(Regexp)
111
+ size = idx ? idx+$&.size : nil
112
+ else
113
+ size = idx ? idx+eol.size : nil
114
+ end
115
+ consume_rbuff(size)
116
+ end
117
+
118
+ def each(eol=$/)
119
+ while line = self.gets(eol)
120
+ yield line
121
+ end
122
+ end
123
+ alias each_line each
124
+
125
+ def readlines(eol=$/)
126
+ ary = []
127
+ while line = self.gets(eol)
128
+ ary << line
129
+ end
130
+ ary
131
+ end
132
+
133
+ def readline(eol=$/)
134
+ raise EOFError if eof?
135
+ gets(eol)
136
+ end
137
+
138
+ def getc
139
+ c = read(1)
140
+ c ? c[0] : nil
141
+ end
142
+
143
+ def each_byte
144
+ while c = getc
145
+ yield(c)
146
+ end
147
+ end
148
+
149
+ def readchar
150
+ raise EOFError if eof?
151
+ getc
152
+ end
153
+
154
+ def ungetc(c)
155
+ @rbuffer[0,0] = c.chr
156
+ end
157
+
158
+ def eof?
159
+ fill_rbuff if !@eof && @rbuffer.empty?
160
+ @eof && @rbuffer.empty?
161
+ end
162
+ alias eof eof?
163
+
164
+ #
165
+ # for writing.
166
+ #
167
+ private
168
+
169
+ def do_write(s)
170
+ @wbuffer = "" unless defined? @wbuffer
171
+ @wbuffer << s
172
+ @sync ||= false
173
+ if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/)
174
+ remain = idx ? idx + $/.size : @wbuffer.length
175
+ nwritten = 0
176
+ while remain > 0
177
+ str = @wbuffer[nwritten,remain]
178
+ begin
179
+ nwrote = syswrite(str)
180
+ rescue Errno::EAGAIN
181
+ retry
182
+ end
183
+ remain -= nwrote
184
+ nwritten += nwrote
185
+ end
186
+ @wbuffer[0,nwritten] = ""
187
+ end
188
+ end
189
+
190
+ public
191
+
192
+ def write(s)
193
+ do_write(s)
194
+ s.length
195
+ end
196
+
197
+ def << (s)
198
+ do_write(s)
199
+ self
200
+ end
201
+
202
+ def puts(*args)
203
+ s = ""
204
+ if args.empty?
205
+ s << "\n"
206
+ end
207
+ args.each{|arg|
208
+ s << arg.to_s
209
+ if $/ && /\n\z/ !~ s
210
+ s << "\n"
211
+ end
212
+ }
213
+ do_write(s)
214
+ nil
215
+ end
216
+
217
+ def print(*args)
218
+ s = ""
219
+ args.each{ |arg| s << arg.to_s }
220
+ do_write(s)
221
+ nil
222
+ end
223
+
224
+ def printf(s, *args)
225
+ do_write(s % args)
226
+ nil
227
+ end
228
+
229
+ def flush
230
+ osync = @sync
231
+ @sync = true
232
+ do_write ""
233
+ @sync = osync
234
+ end
235
+
236
+ def close
237
+ flush rescue nil
238
+ sysclose
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,65 @@
1
+ =begin
2
+ = $RCSfile$ -- Ruby-space predefined Cipher subclasses
3
+
4
+ = Info
5
+ 'OpenSSL for Ruby 2' project
6
+ Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz>
7
+ All rights reserved.
8
+
9
+ = Licence
10
+ This program is licenced under the same licence as Ruby.
11
+ (See the file 'LICENCE'.)
12
+
13
+ = Version
14
+ $Id: cipher.rb 12496 2007-06-08 15:02:04Z technorama $
15
+ =end
16
+
17
+ ##
18
+ # Should we care what if somebody require this file directly?
19
+ #require 'openssl'
20
+
21
+ module OpenSSL
22
+ class Cipher
23
+ %w(AES CAST5 BF DES IDEA RC2 RC4 RC5).each{|name|
24
+ klass = Class.new(Cipher){
25
+ define_method(:initialize){|*args|
26
+ cipher_name = args.inject(name){|n, arg| "#{n}-#{arg}" }
27
+ super(cipher_name)
28
+ }
29
+ }
30
+ const_set(name, klass)
31
+ }
32
+
33
+ %w(128 192 256).each{|keylen|
34
+ klass = Class.new(Cipher){
35
+ define_method(:initialize){|mode|
36
+ mode ||= "CBC"
37
+ cipher_name = "AES-#{keylen}-#{mode}"
38
+ super(cipher_name)
39
+ }
40
+ }
41
+ const_set("AES#{keylen}", klass)
42
+ }
43
+
44
+ # Generate, set, and return a random key.
45
+ # You must call cipher.encrypt or cipher.decrypt before calling this method.
46
+ def random_key
47
+ str = OpenSSL::Random.random_bytes(self.key_len)
48
+ self.key = str
49
+ return str
50
+ end
51
+
52
+ # Generate, set, and return a random iv.
53
+ # You must call cipher.encrypt or cipher.decrypt before calling this method.
54
+ def random_iv
55
+ str = OpenSSL::Random.random_bytes(self.iv_len)
56
+ self.iv = str
57
+ return str
58
+ end
59
+
60
+ # This class is only provided for backwards compatibility. Use OpenSSL::Digest in the future.
61
+ class Cipher < Cipher
62
+ # add warning
63
+ end
64
+ end # Cipher
65
+ end # OpenSSL
@@ -0,0 +1,316 @@
1
+ =begin
2
+ = Ruby-space definitions that completes C-space funcs for Config
3
+
4
+ = Info
5
+ Copyright (C) 2010 Hiroshi Nakamura <nahi@ruby-lang.org>
6
+
7
+ = Licence
8
+ This program is licenced under the same licence as Ruby.
9
+ (See the file 'LICENCE'.)
10
+
11
+ =end
12
+
13
+ ##
14
+ # Should we care what if somebody require this file directly?
15
+ #require 'openssl'
16
+ require 'stringio'
17
+
18
+ module OpenSSL
19
+ class Config
20
+ include Enumerable
21
+
22
+ class << self
23
+ def parse(str)
24
+ c = new()
25
+ parse_config(StringIO.new(str)).each do |section, hash|
26
+ c[section] = hash
27
+ end
28
+ c
29
+ end
30
+
31
+ alias load new
32
+
33
+ def parse_config(io)
34
+ begin
35
+ parse_config_lines(io)
36
+ rescue ConfigError => e
37
+ e.message.replace("error in line #{io.lineno}: " + e.message)
38
+ raise
39
+ end
40
+ end
41
+
42
+ def get_key_string(data, section, key) # :nodoc:
43
+ if v = data[section] && data[section][key]
44
+ return v
45
+ elsif section == 'ENV'
46
+ if v = ENV[key]
47
+ return v
48
+ end
49
+ end
50
+ if v = data['default'] && data['default'][key]
51
+ return v
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def parse_config_lines(io)
58
+ section = 'default'
59
+ data = {section => {}}
60
+ while definition = get_definition(io)
61
+ definition = clear_comments(definition)
62
+ next if definition.empty?
63
+ if definition[0] == ?[
64
+ if /\[([^\]]*)\]/ =~ definition
65
+ section = $1.strip
66
+ data[section] ||= {}
67
+ else
68
+ raise ConfigError, "missing close square bracket"
69
+ end
70
+ else
71
+ if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition
72
+ if $2
73
+ section = $1
74
+ key = $2
75
+ else
76
+ key = $1
77
+ end
78
+ value = unescape_value(data, section, $3)
79
+ (data[section] ||= {})[key] = value.strip
80
+ else
81
+ raise ConfigError, "missing equal sign"
82
+ end
83
+ end
84
+ end
85
+ data
86
+ end
87
+
88
+ # escape with backslash
89
+ QUOTE_REGEXP_SQ = /\A([^'\\]*(?:\\.[^'\\]*)*)'/
90
+ # escape with backslash and doubled dq
91
+ QUOTE_REGEXP_DQ = /\A([^"\\]*(?:""[^"\\]*|\\.[^"\\]*)*)"/
92
+ # escaped char map
93
+ ESCAPE_MAP = {
94
+ "r" => "\r",
95
+ "n" => "\n",
96
+ "b" => "\b",
97
+ "t" => "\t",
98
+ }
99
+
100
+ def unescape_value(data, section, value)
101
+ scanned = []
102
+ while m = value.match(/['"\\$]/)
103
+ scanned << m.pre_match
104
+ c = m[0]
105
+ value = m.post_match
106
+ case c
107
+ when "'"
108
+ if m = value.match(QUOTE_REGEXP_SQ)
109
+ scanned << m[1].gsub(/\\(.)/, '\\1')
110
+ value = m.post_match
111
+ else
112
+ break
113
+ end
114
+ when '"'
115
+ if m = value.match(QUOTE_REGEXP_DQ)
116
+ scanned << m[1].gsub(/""/, '').gsub(/\\(.)/, '\\1')
117
+ value = m.post_match
118
+ else
119
+ break
120
+ end
121
+ when "\\"
122
+ c = value.slice!(0, 1)
123
+ scanned << (ESCAPE_MAP[c] || c)
124
+ when "$"
125
+ ref, value = extract_reference(value)
126
+ refsec = section
127
+ if ref.index('::')
128
+ refsec, ref = ref.split('::', 2)
129
+ end
130
+ if v = get_key_string(data, refsec, ref)
131
+ scanned << v
132
+ else
133
+ raise ConfigError, "variable has no value"
134
+ end
135
+ else
136
+ raise 'must not reaced'
137
+ end
138
+ end
139
+ scanned << value
140
+ scanned.join
141
+ end
142
+
143
+ def extract_reference(value)
144
+ rest = ''
145
+ if m = value.match(/\(([^)]*)\)|\{([^}]*)\}/)
146
+ value = m[1] || m[2]
147
+ rest = m.post_match
148
+ elsif [?(, ?{].include?(value[0])
149
+ raise ConfigError, "no close brace"
150
+ end
151
+ if m = value.match(/[a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]*)?/)
152
+ return m[0], m.post_match + rest
153
+ else
154
+ raise
155
+ end
156
+ end
157
+
158
+ def clear_comments(line)
159
+ # FCOMMENT
160
+ if m = line.match(/\A([\t\n\f ]*);.*\z/)
161
+ return m[1]
162
+ end
163
+ # COMMENT
164
+ scanned = []
165
+ while m = line.match(/[#'"\\]/)
166
+ scanned << m.pre_match
167
+ c = m[0]
168
+ line = m.post_match
169
+ case c
170
+ when '#'
171
+ line = nil
172
+ break
173
+ when "'", '"'
174
+ regexp = (c == "'") ? QUOTE_REGEXP_SQ : QUOTE_REGEXP_DQ
175
+ scanned << c
176
+ if m = line.match(regexp)
177
+ scanned << m[0]
178
+ line = m.post_match
179
+ else
180
+ scanned << line
181
+ line = nil
182
+ break
183
+ end
184
+ when "\\"
185
+ scanned << c
186
+ scanned << line.slice!(0, 1)
187
+ else
188
+ raise 'must not reaced'
189
+ end
190
+ end
191
+ scanned << line
192
+ scanned.join
193
+ end
194
+
195
+ def get_definition(io)
196
+ if line = get_line(io)
197
+ while /[^\\]\\\z/ =~ line
198
+ if extra = get_line(io)
199
+ line += extra
200
+ else
201
+ break
202
+ end
203
+ end
204
+ return line.strip
205
+ end
206
+ end
207
+
208
+ def get_line(io)
209
+ if line = io.gets
210
+ line.gsub(/[\r\n]*/, '')
211
+ end
212
+ end
213
+ end
214
+
215
+ def initialize(filename = nil)
216
+ @data = {}
217
+ if filename
218
+ File.open(filename.to_s) do |file|
219
+ Config.parse_config(file).each do |section, hash|
220
+ self[section] = hash
221
+ end
222
+ end
223
+ end
224
+ end
225
+
226
+ def get_value(section, key)
227
+ if section.nil?
228
+ raise TypeError.new('nil not allowed')
229
+ end
230
+ section = 'default' if section.empty?
231
+ get_key_string(section, key)
232
+ end
233
+
234
+ def value(arg1, arg2 = nil)
235
+ warn('Config#value is deprecated; use Config#get_value')
236
+ if arg2.nil?
237
+ section, key = 'default', arg1
238
+ else
239
+ section, key = arg1, arg2
240
+ end
241
+ section ||= 'default'
242
+ section = 'default' if section.empty?
243
+ get_key_string(section, key)
244
+ end
245
+
246
+ def add_value(section, key, value)
247
+ check_modify
248
+ (@data[section] ||= {})[key] = value
249
+ end
250
+
251
+ def [](section)
252
+ @data[section] || {}
253
+ end
254
+
255
+ def section(name)
256
+ warn('Config#section is deprecated; use Config#[]')
257
+ @data[name] || {}
258
+ end
259
+
260
+ def []=(section, pairs)
261
+ check_modify
262
+ @data[section] ||= {}
263
+ pairs.each do |key, value|
264
+ self.add_value(section, key, value)
265
+ end
266
+ end
267
+
268
+ def sections
269
+ @data.keys
270
+ end
271
+
272
+ def to_s
273
+ ary = []
274
+ @data.keys.sort.each do |section|
275
+ ary << "[ #{section} ]\n"
276
+ @data[section].keys.each do |key|
277
+ ary << "#{key}=#{@data[section][key]}\n"
278
+ end
279
+ ary << "\n"
280
+ end
281
+ ary.join
282
+ end
283
+
284
+ def each
285
+ @data.each do |section, hash|
286
+ hash.each do |key, value|
287
+ yield(section, key, value)
288
+ end
289
+ end
290
+ end
291
+
292
+ def inspect
293
+ "#<#{self.class.name} sections=#{sections.inspect}>"
294
+ end
295
+
296
+ protected
297
+
298
+ def data
299
+ @data
300
+ end
301
+
302
+ private
303
+
304
+ def initialize_copy(other)
305
+ @data = other.data.dup
306
+ end
307
+
308
+ def check_modify
309
+ raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen?
310
+ end
311
+
312
+ def get_key_string(section, key)
313
+ Config.get_key_string(@data, section, key)
314
+ end
315
+ end
316
+ end