PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/ruby-2.1.9/lib/ruby/2.1.0/openssl/config.rb

https://gitlab.com/MarcuSacramento/ferramentas
Ruby | 472 lines | 274 code | 28 blank | 170 comment | 25 complexity | cf3bb34625f49492113f9f93d52c311a MD5 | raw file
  1. =begin
  2. = Ruby-space definitions that completes C-space funcs for Config
  3. = Info
  4. Copyright (C) 2010 Hiroshi Nakamura <nahi@ruby-lang.org>
  5. = Licence
  6. This program is licenced under the same licence as Ruby.
  7. (See the file 'LICENCE'.)
  8. =end
  9. require 'stringio'
  10. module OpenSSL
  11. ##
  12. # = OpenSSL::Config
  13. #
  14. # Configuration for the openssl library.
  15. #
  16. # Many system's installation of openssl library will depend on your system
  17. # configuration. See the value of OpenSSL::Config::DEFAULT_CONFIG_FILE for
  18. # the location of the file for your host.
  19. #
  20. # See also http://www.openssl.org/docs/apps/config.html
  21. class Config
  22. include Enumerable
  23. class << self
  24. ##
  25. # Parses a given +string+ as a blob that contains configuration for openssl.
  26. #
  27. # If the source of the IO is a file, then consider using #parse_config.
  28. def parse(string)
  29. c = new()
  30. parse_config(StringIO.new(string)).each do |section, hash|
  31. c[section] = hash
  32. end
  33. c
  34. end
  35. ##
  36. # load is an alias to ::new
  37. alias load new
  38. ##
  39. # Parses the configuration data read from +io+, see also #parse.
  40. #
  41. # Raises a ConfigError on invalid configuration data.
  42. def parse_config(io)
  43. begin
  44. parse_config_lines(io)
  45. rescue ConfigError => e
  46. e.message.replace("error in line #{io.lineno}: " + e.message)
  47. raise
  48. end
  49. end
  50. def get_key_string(data, section, key) # :nodoc:
  51. if v = data[section] && data[section][key]
  52. return v
  53. elsif section == 'ENV'
  54. if v = ENV[key]
  55. return v
  56. end
  57. end
  58. if v = data['default'] && data['default'][key]
  59. return v
  60. end
  61. end
  62. private
  63. def parse_config_lines(io)
  64. section = 'default'
  65. data = {section => {}}
  66. while definition = get_definition(io)
  67. definition = clear_comments(definition)
  68. next if definition.empty?
  69. if definition[0] == ?[
  70. if /\[([^\]]*)\]/ =~ definition
  71. section = $1.strip
  72. data[section] ||= {}
  73. else
  74. raise ConfigError, "missing close square bracket"
  75. end
  76. else
  77. if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition
  78. if $2
  79. section = $1
  80. key = $2
  81. else
  82. key = $1
  83. end
  84. value = unescape_value(data, section, $3)
  85. (data[section] ||= {})[key] = value.strip
  86. else
  87. raise ConfigError, "missing equal sign"
  88. end
  89. end
  90. end
  91. data
  92. end
  93. # escape with backslash
  94. QUOTE_REGEXP_SQ = /\A([^'\\]*(?:\\.[^'\\]*)*)'/
  95. # escape with backslash and doubled dq
  96. QUOTE_REGEXP_DQ = /\A([^"\\]*(?:""[^"\\]*|\\.[^"\\]*)*)"/
  97. # escaped char map
  98. ESCAPE_MAP = {
  99. "r" => "\r",
  100. "n" => "\n",
  101. "b" => "\b",
  102. "t" => "\t",
  103. }
  104. def unescape_value(data, section, value)
  105. scanned = []
  106. while m = value.match(/['"\\$]/)
  107. scanned << m.pre_match
  108. c = m[0]
  109. value = m.post_match
  110. case c
  111. when "'"
  112. if m = value.match(QUOTE_REGEXP_SQ)
  113. scanned << m[1].gsub(/\\(.)/, '\\1')
  114. value = m.post_match
  115. else
  116. break
  117. end
  118. when '"'
  119. if m = value.match(QUOTE_REGEXP_DQ)
  120. scanned << m[1].gsub(/""/, '').gsub(/\\(.)/, '\\1')
  121. value = m.post_match
  122. else
  123. break
  124. end
  125. when "\\"
  126. c = value.slice!(0, 1)
  127. scanned << (ESCAPE_MAP[c] || c)
  128. when "$"
  129. ref, value = extract_reference(value)
  130. refsec = section
  131. if ref.index('::')
  132. refsec, ref = ref.split('::', 2)
  133. end
  134. if v = get_key_string(data, refsec, ref)
  135. scanned << v
  136. else
  137. raise ConfigError, "variable has no value"
  138. end
  139. else
  140. raise 'must not reaced'
  141. end
  142. end
  143. scanned << value
  144. scanned.join
  145. end
  146. def extract_reference(value)
  147. rest = ''
  148. if m = value.match(/\(([^)]*)\)|\{([^}]*)\}/)
  149. value = m[1] || m[2]
  150. rest = m.post_match
  151. elsif [?(, ?{].include?(value[0])
  152. raise ConfigError, "no close brace"
  153. end
  154. if m = value.match(/[a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]*)?/)
  155. return m[0], m.post_match + rest
  156. else
  157. raise
  158. end
  159. end
  160. def clear_comments(line)
  161. # FCOMMENT
  162. if m = line.match(/\A([\t\n\f ]*);.*\z/)
  163. return m[1]
  164. end
  165. # COMMENT
  166. scanned = []
  167. while m = line.match(/[#'"\\]/)
  168. scanned << m.pre_match
  169. c = m[0]
  170. line = m.post_match
  171. case c
  172. when '#'
  173. line = nil
  174. break
  175. when "'", '"'
  176. regexp = (c == "'") ? QUOTE_REGEXP_SQ : QUOTE_REGEXP_DQ
  177. scanned << c
  178. if m = line.match(regexp)
  179. scanned << m[0]
  180. line = m.post_match
  181. else
  182. scanned << line
  183. line = nil
  184. break
  185. end
  186. when "\\"
  187. scanned << c
  188. scanned << line.slice!(0, 1)
  189. else
  190. raise 'must not reaced'
  191. end
  192. end
  193. scanned << line
  194. scanned.join
  195. end
  196. def get_definition(io)
  197. if line = get_line(io)
  198. while /[^\\]\\\z/ =~ line
  199. if extra = get_line(io)
  200. line += extra
  201. else
  202. break
  203. end
  204. end
  205. return line.strip
  206. end
  207. end
  208. def get_line(io)
  209. if line = io.gets
  210. line.gsub(/[\r\n]*/, '')
  211. end
  212. end
  213. end
  214. ##
  215. # Creates an instance of OpenSSL's configuration class.
  216. #
  217. # This can be used in contexts like OpenSSL::X509::ExtensionFactory.config=
  218. #
  219. # If the optional +filename+ parameter is provided, then it is read in and
  220. # parsed via #parse_config.
  221. #
  222. # This can raise IO exceptions based on the access, or availability of the
  223. # file. A ConfigError exception may be raised depending on the validity of
  224. # the data being configured.
  225. #
  226. def initialize(filename = nil)
  227. @data = {}
  228. if filename
  229. File.open(filename.to_s) do |file|
  230. Config.parse_config(file).each do |section, hash|
  231. self[section] = hash
  232. end
  233. end
  234. end
  235. end
  236. ##
  237. # Gets the value of +key+ from the given +section+
  238. #
  239. # Given the following configurating file being loaded:
  240. #
  241. # config = OpenSSL::Config.load('foo.cnf')
  242. # #=> #<OpenSSL::Config sections=["default"]>
  243. # puts config.to_s
  244. # #=> [ default ]
  245. # # foo=bar
  246. #
  247. # You can get a specific value from the config if you know the +section+
  248. # and +key+ like so:
  249. #
  250. # config.get_value('default','foo')
  251. # #=> "bar"
  252. #
  253. def get_value(section, key)
  254. if section.nil?
  255. raise TypeError.new('nil not allowed')
  256. end
  257. section = 'default' if section.empty?
  258. get_key_string(section, key)
  259. end
  260. ##
  261. #
  262. # *Deprecated*
  263. #
  264. # Use #get_value instead
  265. def value(arg1, arg2 = nil) # :nodoc:
  266. warn('Config#value is deprecated; use Config#get_value')
  267. if arg2.nil?
  268. section, key = 'default', arg1
  269. else
  270. section, key = arg1, arg2
  271. end
  272. section ||= 'default'
  273. section = 'default' if section.empty?
  274. get_key_string(section, key)
  275. end
  276. ##
  277. # Set the target +key+ with a given +value+ under a specific +section+.
  278. #
  279. # Given the following configurating file being loaded:
  280. #
  281. # config = OpenSSL::Config.load('foo.cnf')
  282. # #=> #<OpenSSL::Config sections=["default"]>
  283. # puts config.to_s
  284. # #=> [ default ]
  285. # # foo=bar
  286. #
  287. # You can set the value of +foo+ under the +default+ section to a new
  288. # value:
  289. #
  290. # config.add_value('default', 'foo', 'buzz')
  291. # #=> "buzz"
  292. # puts config.to_s
  293. # #=> [ default ]
  294. # # foo=buzz
  295. #
  296. def add_value(section, key, value)
  297. check_modify
  298. (@data[section] ||= {})[key] = value
  299. end
  300. ##
  301. # Get a specific +section+ from the current configuration
  302. #
  303. # Given the following configurating file being loaded:
  304. #
  305. # config = OpenSSL::Config.load('foo.cnf')
  306. # #=> #<OpenSSL::Config sections=["default"]>
  307. # puts config.to_s
  308. # #=> [ default ]
  309. # # foo=bar
  310. #
  311. # You can get a hash of the specific section like so:
  312. #
  313. # config['default']
  314. # #=> {"foo"=>"bar"}
  315. #
  316. def [](section)
  317. @data[section] || {}
  318. end
  319. ##
  320. # Deprecated
  321. #
  322. # Use #[] instead
  323. def section(name) # :nodoc:
  324. warn('Config#section is deprecated; use Config#[]')
  325. @data[name] || {}
  326. end
  327. ##
  328. # Sets a specific +section+ name with a Hash +pairs+
  329. #
  330. # Given the following configuration being created:
  331. #
  332. # config = OpenSSL::Config.new
  333. # #=> #<OpenSSL::Config sections=[]>
  334. # config['default'] = {"foo"=>"bar","baz"=>"buz"}
  335. # #=> {"foo"=>"bar", "baz"=>"buz"}
  336. # puts config.to_s
  337. # #=> [ default ]
  338. # # foo=bar
  339. # # baz=buz
  340. #
  341. # It's important to note that this will essentially merge any of the keys
  342. # in +pairs+ with the existing +section+. For example:
  343. #
  344. # config['default']
  345. # #=> {"foo"=>"bar", "baz"=>"buz"}
  346. # config['default'] = {"foo" => "changed"}
  347. # #=> {"foo"=>"changed"}
  348. # config['default']
  349. # #=> {"foo"=>"changed", "baz"=>"buz"}
  350. #
  351. def []=(section, pairs)
  352. check_modify
  353. @data[section] ||= {}
  354. pairs.each do |key, value|
  355. self.add_value(section, key, value)
  356. end
  357. end
  358. ##
  359. # Get the names of all sections in the current configuration
  360. def sections
  361. @data.keys
  362. end
  363. ##
  364. # Get the parsable form of the current configuration
  365. #
  366. # Given the following configuration being created:
  367. #
  368. # config = OpenSSL::Config.new
  369. # #=> #<OpenSSL::Config sections=[]>
  370. # config['default'] = {"foo"=>"bar","baz"=>"buz"}
  371. # #=> {"foo"=>"bar", "baz"=>"buz"}
  372. # puts config.to_s
  373. # #=> [ default ]
  374. # # foo=bar
  375. # # baz=buz
  376. #
  377. # You can parse get the serialized configuration using #to_s and then parse
  378. # it later:
  379. #
  380. # serialized_config = config.to_s
  381. # # much later...
  382. # new_config = OpenSSL::Config.parse(serialized_config)
  383. # #=> #<OpenSSL::Config sections=["default"]>
  384. # puts new_config
  385. # #=> [ default ]
  386. # foo=bar
  387. # baz=buz
  388. #
  389. def to_s
  390. ary = []
  391. @data.keys.sort.each do |section|
  392. ary << "[ #{section} ]\n"
  393. @data[section].keys.each do |key|
  394. ary << "#{key}=#{@data[section][key]}\n"
  395. end
  396. ary << "\n"
  397. end
  398. ary.join
  399. end
  400. ##
  401. # For a block.
  402. #
  403. # Receive the section and its pairs for the current configuration.
  404. #
  405. # config.each do |section, key, value|
  406. # # ...
  407. # end
  408. #
  409. def each
  410. @data.each do |section, hash|
  411. hash.each do |key, value|
  412. yield [section, key, value]
  413. end
  414. end
  415. end
  416. ##
  417. # String representation of this configuration object, including the class
  418. # name and its sections.
  419. def inspect
  420. "#<#{self.class.name} sections=#{sections.inspect}>"
  421. end
  422. protected
  423. def data # :nodoc:
  424. @data
  425. end
  426. private
  427. def initialize_copy(other)
  428. @data = other.data.dup
  429. end
  430. def check_modify
  431. raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen?
  432. end
  433. def get_key_string(section, key)
  434. Config.get_key_string(@data, section, key)
  435. end
  436. end
  437. end