webrick 1.3.1 → 1.4.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of webrick might be problematic. Click here for more details.

Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/lib/webrick.rb +6 -6
  3. data/lib/webrick/accesslog.rb +9 -1
  4. data/lib/webrick/cgi.rb +51 -2
  5. data/lib/webrick/compat.rb +2 -1
  6. data/lib/webrick/config.rb +42 -5
  7. data/lib/webrick/cookie.rb +68 -6
  8. data/lib/webrick/htmlutils.rb +4 -2
  9. data/lib/webrick/httpauth.rb +1 -0
  10. data/lib/webrick/httpauth/authenticator.rb +13 -8
  11. data/lib/webrick/httpauth/basicauth.rb +3 -3
  12. data/lib/webrick/httpauth/digestauth.rb +25 -9
  13. data/lib/webrick/httpauth/htdigest.rb +8 -4
  14. data/lib/webrick/httpauth/htgroup.rb +1 -0
  15. data/lib/webrick/httpauth/htpasswd.rb +7 -3
  16. data/lib/webrick/httpauth/userdb.rb +1 -0
  17. data/lib/webrick/httpproxy.rb +47 -14
  18. data/lib/webrick/httprequest.rb +142 -16
  19. data/lib/webrick/httpresponse.rb +96 -24
  20. data/lib/webrick/https.rb +24 -1
  21. data/lib/webrick/httpserver.rb +20 -4
  22. data/lib/webrick/httpservlet.rb +1 -0
  23. data/lib/webrick/httpservlet/abstract.rb +2 -1
  24. data/lib/webrick/httpservlet/cgi_runner.rb +1 -0
  25. data/lib/webrick/httpservlet/cgihandler.rb +19 -5
  26. data/lib/webrick/httpservlet/erbhandler.rb +2 -1
  27. data/lib/webrick/httpservlet/filehandler.rb +87 -34
  28. data/lib/webrick/httpservlet/prochandler.rb +14 -0
  29. data/lib/webrick/httpstatus.rb +24 -10
  30. data/lib/webrick/httputils.rb +129 -13
  31. data/lib/webrick/httpversion.rb +28 -1
  32. data/lib/webrick/log.rb +22 -2
  33. data/lib/webrick/server.rb +203 -60
  34. data/lib/webrick/ssl.rb +80 -5
  35. data/lib/webrick/utils.rb +97 -67
  36. data/lib/webrick/version.rb +6 -1
  37. metadata +59 -69
  38. data/README.txt +0 -21
  39. data/sample/webrick/demo-app.rb +0 -66
  40. data/sample/webrick/demo-multipart.cgi +0 -12
  41. data/sample/webrick/demo-servlet.rb +0 -6
  42. data/sample/webrick/demo-urlencoded.cgi +0 -12
  43. data/sample/webrick/hello.cgi +0 -11
  44. data/sample/webrick/hello.rb +0 -8
  45. data/sample/webrick/httpd.rb +0 -23
  46. data/sample/webrick/httpproxy.rb +0 -25
  47. data/sample/webrick/httpsd.rb +0 -33
  48. data/test/openssl/utils.rb +0 -313
  49. data/test/ruby/envutil.rb +0 -208
  50. data/test/webrick/test_cgi.rb +0 -134
  51. data/test/webrick/test_cookie.rb +0 -131
  52. data/test/webrick/test_filehandler.rb +0 -285
  53. data/test/webrick/test_httpauth.rb +0 -167
  54. data/test/webrick/test_httpproxy.rb +0 -282
  55. data/test/webrick/test_httprequest.rb +0 -411
  56. data/test/webrick/test_httpresponse.rb +0 -49
  57. data/test/webrick/test_httpserver.rb +0 -305
  58. data/test/webrick/test_httputils.rb +0 -96
  59. data/test/webrick/test_httpversion.rb +0 -40
  60. data/test/webrick/test_server.rb +0 -67
  61. data/test/webrick/test_utils.rb +0 -64
  62. data/test/webrick/utils.rb +0 -58
  63. data/test/webrick/webrick.cgi +0 -36
  64. data/test/webrick/webrick_long_filename.cgi +0 -36
data/README.txt DELETED
@@ -1,21 +0,0 @@
1
- = WEB server toolkit.
2
-
3
- WEBrick is an HTTP server toolkit that can be configured as an HTTPS server,
4
- a proxy server, and a virtual-host server. WEBrick features complete
5
- logging of both server operations and HTTP access. WEBrick supports both
6
- basic and digest authentication in addition to algorithms not in RFC 2617.
7
-
8
- A WEBrick servers can be composed of multiple WEBrick servers or servlets to
9
- provide differing behavior on a per-host or per-path basis. WEBrick
10
- includes servlets for handling CGI scripts, ERb pages, ruby blocks and
11
- directory listings.
12
-
13
- WEBrick also includes tools for daemonizing a process and starting a process
14
- at a higher privilege level and dropping permissions.
15
-
16
- == Copyright
17
-
18
- Author: IPR -- Internet Programming with Ruby -- writers
19
-
20
- Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
21
- Copyright (c) 2002 Internet Programming with Ruby writers. All rights reserved.
@@ -1,66 +0,0 @@
1
- require "pp"
2
-
3
- module DemoApplication
4
- def initialize(config, enctype)
5
- super
6
- @enctype = enctype
7
- end
8
-
9
- def do_GET(req, res)
10
- if req.path_info != "/"
11
- res.set_redirect(WEBrick::HTTPStatus::Found, req.script_name + "/")
12
- end
13
- res.body =<<-_end_of_html_
14
- <HTML>
15
- <FORM method="POST" enctype=#{@enctype}>
16
- text: <INPUT type="text" name="text"><BR>
17
- file: <INPUT type="file" name="file"><BR>
18
- check:
19
- <INPUT type="checkbox" name="check" value="a">a,
20
- <INPUT type="checkbox" name="check" value="b">b,
21
- <INPUT type="checkbox" name="check" value="c">c,
22
- <BR>
23
- <INPUT type="submit">
24
- </FORM>
25
- </HTML>
26
- _end_of_html_
27
- res['content-type'] = 'text/html; charset=iso-8859-1'
28
- end
29
-
30
- def do_POST(req, res)
31
- if req["content-length"].to_i > 1024*10
32
- raise WEBrick::HTTPStatus::Forbidden, "file size too large"
33
- end
34
- res.body =<<-_end_of_html_
35
- <HTML>
36
- <H2>Query Parameters</H2>
37
- #{display_query(req.query)}
38
- <A href="#{req.path}">return</A>
39
- <H2>Request</H2>
40
- <PRE>#{WEBrick::HTMLUtils::escape(PP::pp(req, "", 80))}</PRE>
41
- <H2>Response</H2>
42
- <PRE>#{WEBrick::HTMLUtils::escape(PP::pp(res, "", 80))}</PRE>
43
- </HTML>
44
- _end_of_html_
45
- res['content-type'] = 'text/html; charset=iso-8859-1'
46
- end
47
-
48
- private
49
-
50
- def display_query(q)
51
- ret = ""
52
- q.each{|key, val|
53
- ret << "<H3>#{WEBrick::HTMLUtils::escape(key)}</H3>"
54
- ret << "<TABLE border=1>"
55
- ret << make_tr("val", val.inspect)
56
- ret << make_tr("val.to_a", val.to_a.inspect)
57
- ret << make_tr("val.to_ary", val.to_ary.inspect)
58
- ret << "</TABLE>"
59
- }
60
- ret
61
- end
62
-
63
- def make_tr(arg0, arg1)
64
- "<TR><TD>#{arg0}</TD><TD>#{WEBrick::HTMLUtils::escape(arg1)}</TD></TR>"
65
- end
66
- end
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require "webrick/cgi"
3
- require "webrick/https" # should load if it runs on HTTPS server
4
- require "./demo-app"
5
-
6
- class DemoCGI < WEBrick::CGI
7
- include DemoApplication
8
- end
9
-
10
- config = { :NPH => false }
11
- cgi = DemoCGI.new(config, "multipart/form-data")
12
- cgi.start
@@ -1,6 +0,0 @@
1
- require "webrick"
2
- require "./demo-app"
3
-
4
- class DemoServlet < WEBrick::HTTPServlet::AbstractServlet
5
- include DemoApplication
6
- end
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require "webrick/cgi"
3
- require "webrick/https" # should load if it runs on HTTPS server
4
- require "./demo-app"
5
-
6
- class DemoCGI < WEBrick::CGI
7
- include DemoApplication
8
- end
9
-
10
- config = { :NPH => false }
11
- cgi = DemoCGI.new(config, "application/x-www-form-urlencoded")
12
- cgi.start
@@ -1,11 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require "webrick/cgi"
3
-
4
- class HelloCGI < WEBrick::CGI
5
- def do_GET(req, res)
6
- res["content-type"] = "text/plain"
7
- res.body = "Hello, world.\n"
8
- end
9
- end
10
-
11
- HelloCGI.new.start
@@ -1,8 +0,0 @@
1
- require "webrick"
2
-
3
- class HelloServlet < WEBrick::HTTPServlet::AbstractServlet
4
- def do_GET(req, res)
5
- res["content-type"] = "text/plain"
6
- res.body = "Hello, world.\n"
7
- end
8
- end
@@ -1,23 +0,0 @@
1
- require "webrick"
2
-
3
- httpd = WEBrick::HTTPServer.new(
4
- :DocumentRoot => File::dirname(__FILE__),
5
- :Port => 10080,
6
- :Logger => WEBrick::Log.new($stderr, WEBrick::Log::DEBUG),
7
- :AccessLog => [
8
- [ $stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
9
- [ $stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT ],
10
- [ $stderr, WEBrick::AccessLog::AGENT_LOG_FORMAT ],
11
- ],
12
- :CGIPathEnv => ENV["PATH"] # PATH environment variable for CGI.
13
- )
14
-
15
- require "./hello"
16
- httpd.mount("/hello", HelloServlet)
17
-
18
- require "./demo-servlet"
19
- httpd.mount("/urlencoded", DemoServlet, "application/x-www-form-urlencoded")
20
- httpd.mount("/multipart", DemoServlet, "multipart/form-data")
21
-
22
- trap(:INT){ httpd.shutdown }
23
- httpd.start
@@ -1,25 +0,0 @@
1
- require "webrick"
2
- require "webrick/httpproxy"
3
-
4
- # The :ProxyContentHandler proc will be invoked before sending a response to
5
- # the User-Agent. You can inspect the pair of request and response messages
6
- # (or edit the response message if necessary).
7
-
8
- pch = Proc.new{|req, res|
9
- p [ req.request_line, res.status_line ]
10
- }
11
-
12
- def upstream_proxy
13
- if prx = ENV["http_proxy"]
14
- return URI.parse(prx)
15
- end
16
- return nil
17
- end
18
-
19
- httpd = WEBrick::HTTPProxyServer.new(
20
- :Port => 10080,
21
- :ProxyContentHandler => pch,
22
- :ProxyURI => upstream_proxy
23
- )
24
- Signal.trap(:INT){ httpd.shutdown }
25
- httpd.start
@@ -1,33 +0,0 @@
1
- require "webrick"
2
- require "webrick/https"
3
-
4
- hostname = WEBrick::Utils::getservername
5
- subject = [["O", "ruby-lang.org"], ["OU", "sample"], ["CN", hostname]]
6
- comment = "Comment for self-signed certificate"
7
-
8
- httpd = WEBrick::HTTPServer.new(
9
- :DocumentRoot => File::dirname(__FILE__),
10
- :Port => 10443,
11
- :SSLEnable => true,
12
-
13
- # Specify key pair and server certificate.
14
- # :SSLPrivateKey => OpenSSL::PKey::RSA.new(File.read("server.key")),
15
- # :SSLCertificate => OpenSSL::X509::Certificate.new(File.read("server.crt")),
16
-
17
- # specify the following SSL options if you want to use auto
18
- # generated self-signed certificate.
19
- :SSLCertName => subject,
20
- :SSLComment => comment,
21
-
22
- :CGIPathEnv => ENV["PATH"] # PATH environment variable for CGI.
23
- )
24
-
25
- require "./hello"
26
- httpd.mount("/hello", HelloServlet)
27
-
28
- require "./demo-servlet"
29
- httpd.mount("/urlencoded", DemoServlet, "application/x-www-form-urlencoded")
30
- httpd.mount("/multipart", DemoServlet, "multipart/form-data")
31
-
32
- trap(:INT){ httpd.shutdown }
33
- httpd.start
@@ -1,313 +0,0 @@
1
- begin
2
- require "openssl"
3
- rescue LoadError
4
- end
5
- require "test/unit"
6
- require "digest/md5"
7
- require 'tempfile'
8
- require "rbconfig"
9
- require "socket"
10
- require_relative '../ruby/envutil'
11
-
12
- module OpenSSL::TestUtils
13
- TEST_KEY_RSA1024 = OpenSSL::PKey::RSA.new <<-_end_of_pem_
14
- -----BEGIN RSA PRIVATE KEY-----
15
- MIICXgIBAAKBgQDLwsSw1ECnPtT+PkOgHhcGA71nwC2/nL85VBGnRqDxOqjVh7Cx
16
- aKPERYHsk4BPCkE3brtThPWc9kjHEQQ7uf9Y1rbCz0layNqHyywQEVLFmp1cpIt/
17
- Q3geLv8ZD9pihowKJDyMDiN6ArYUmZczvW4976MU3+l54E6lF/JfFEU5hwIDAQAB
18
- AoGBAKSl/MQarye1yOysqX6P8fDFQt68VvtXkNmlSiKOGuzyho0M+UVSFcs6k1L0
19
- maDE25AMZUiGzuWHyaU55d7RXDgeskDMakD1v6ZejYtxJkSXbETOTLDwUWTn618T
20
- gnb17tU1jktUtU67xK/08i/XodlgnQhs6VoHTuCh3Hu77O6RAkEA7+gxqBuZR572
21
- 74/akiW/SuXm0SXPEviyO1MuSRwtI87B02D0qgV8D1UHRm4AhMnJ8MCs1809kMQE
22
- JiQUCrp9mQJBANlt2ngBO14us6NnhuAseFDTBzCHXwUUu1YKHpMMmxpnGqaldGgX
23
- sOZB3lgJsT9VlGf3YGYdkLTNVbogQKlKpB8CQQDiSwkb4vyQfDe8/NpU5Not0fII
24
- 8jsDUCb+opWUTMmfbxWRR3FBNu8wnym/m19N4fFj8LqYzHX4KY0oVPu6qvJxAkEA
25
- wa5snNekFcqONLIE4G5cosrIrb74sqL8GbGb+KuTAprzj5z1K8Bm0UW9lTjVDjDi
26
- qRYgZfZSL+x1P/54+xTFSwJAY1FxA/N3QPCXCjPh5YqFxAMQs2VVYTfg+t0MEcJD
27
- dPMQD5JX6g5HKnHFg2mZtoXQrWmJSn7p8GJK8yNTopEErA==
28
- -----END RSA PRIVATE KEY-----
29
- _end_of_pem_
30
-
31
- TEST_KEY_RSA2048 = OpenSSL::PKey::RSA.new <<-_end_of_pem_
32
- -----BEGIN RSA PRIVATE KEY-----
33
- MIIEpAIBAAKCAQEAuV9ht9J7k4NBs38jOXvvTKY9gW8nLICSno5EETR1cuF7i4pN
34
- s9I1QJGAFAX0BEO4KbzXmuOvfCpD3CU+Slp1enenfzq/t/e/1IRW0wkJUJUFQign
35
- 4CtrkJL+P07yx18UjyPlBXb81ApEmAB5mrJVSrWmqbjs07JbuS4QQGGXLc+Su96D
36
- kYKmSNVjBiLxVVSpyZfAY3hD37d60uG+X8xdW5v68JkRFIhdGlb6JL8fllf/A/bl
37
- NwdJOhVr9mESHhwGjwfSeTDPfd8ZLE027E5lyAVX9KZYcU00mOX+fdxOSnGqS/8J
38
- DRh0EPHDL15RcJjV2J6vZjPb0rOYGDoMcH+94wIDAQABAoIBAAzsamqfYQAqwXTb
39
- I0CJtGg6msUgU7HVkOM+9d3hM2L791oGHV6xBAdpXW2H8LgvZHJ8eOeSghR8+dgq
40
- PIqAffo4x1Oma+FOg3A0fb0evyiACyrOk+EcBdbBeLo/LcvahBtqnDfiUMQTpy6V
41
- seSoFCwuN91TSCeGIsDpRjbG1vxZgtx+uI+oH5+ytqJOmfCksRDCkMglGkzyfcl0
42
- Xc5CUhIJ0my53xijEUQl19rtWdMnNnnkdbG8PT3LZlOta5Do86BElzUYka0C6dUc
43
- VsBDQ0Nup0P6rEQgy7tephHoRlUGTYamsajGJaAo1F3IQVIrRSuagi7+YpSpCqsW
44
- wORqorkCgYEA7RdX6MDVrbw7LePnhyuaqTiMK+055/R1TqhB1JvvxJ1CXk2rDL6G
45
- 0TLHQ7oGofd5LYiemg4ZVtWdJe43BPZlVgT6lvL/iGo8JnrncB9Da6L7nrq/+Rvj
46
- XGjf1qODCK+LmreZWEsaLPURIoR/Ewwxb9J2zd0CaMjeTwafJo1CZvcCgYEAyCgb
47
- aqoWvUecX8VvARfuA593Lsi50t4MEArnOXXcd1RnXoZWhbx5rgO8/ATKfXr0BK/n
48
- h2GF9PfKzHFm/4V6e82OL7gu/kLy2u9bXN74vOvWFL5NOrOKPM7Kg+9I131kNYOw
49
- Ivnr/VtHE5s0dY7JChYWE1F3vArrOw3T00a4CXUCgYEA0SqY+dS2LvIzW4cHCe9k
50
- IQqsT0yYm5TFsUEr4sA3xcPfe4cV8sZb9k/QEGYb1+SWWZ+AHPV3UW5fl8kTbSNb
51
- v4ng8i8rVVQ0ANbJO9e5CUrepein2MPL0AkOATR8M7t7dGGpvYV0cFk8ZrFx0oId
52
- U0PgYDotF/iueBWlbsOM430CgYEAqYI95dFyPI5/AiSkY5queeb8+mQH62sdcCCr
53
- vd/w/CZA/K5sbAo4SoTj8dLk4evU6HtIa0DOP63y071eaxvRpTNqLUOgmLh+D6gS
54
- Cc7TfLuFrD+WDBatBd5jZ+SoHccVrLR/4L8jeodo5FPW05A+9gnKXEXsTxY4LOUC
55
- 9bS4e1kCgYAqVXZh63JsMwoaxCYmQ66eJojKa47VNrOeIZDZvd2BPVf30glBOT41
56
- gBoDG3WMPZoQj9pb7uMcrnvs4APj2FIhMU8U15LcPAj59cD6S6rWnAxO8NFK7HQG
57
- 4Jxg3JNNf8ErQoCHb1B3oVdXJkmbJkARoDpBKmTCgKtP8ADYLmVPQw==
58
- -----END RSA PRIVATE KEY-----
59
- _end_of_pem_
60
-
61
- TEST_KEY_DSA256 = OpenSSL::PKey::DSA.new <<-_end_of_pem_
62
- -----BEGIN DSA PRIVATE KEY-----
63
- MIH3AgEAAkEAhk2libbY2a8y2Pt21+YPYGZeW6wzaW2yfj5oiClXro9XMR7XWLkE
64
- 9B7XxLNFCS2gmCCdMsMW1HulaHtLFQmB2wIVAM43JZrcgpu6ajZ01VkLc93gu/Ed
65
- AkAOhujZrrKV5CzBKutKLb0GVyVWmdC7InoNSMZEeGU72rT96IjM59YzoqmD0pGM
66
- 3I1o4cGqg1D1DfM1rQlnN1eSAkBq6xXfEDwJ1mLNxF6q8Zm/ugFYWR5xcX/3wFiT
67
- b4+EjHP/DbNh9Vm5wcfnDBJ1zKvrMEf2xqngYdrV/3CiGJeKAhRvL57QvJZcQGvn
68
- ISNX5cMzFHRW3Q==
69
- -----END DSA PRIVATE KEY-----
70
- _end_of_pem_
71
-
72
- TEST_KEY_DSA512 = OpenSSL::PKey::DSA.new <<-_end_of_pem_
73
- -----BEGIN DSA PRIVATE KEY-----
74
- MIH4AgEAAkEA5lB4GvEwjrsMlGDqGsxrbqeFRh6o9OWt6FgTYiEEHaOYhkIxv0Ok
75
- RZPDNwOG997mDjBnvDJ1i56OmS3MbTnovwIVAJgub/aDrSDB4DZGH7UyarcaGy6D
76
- AkB9HdFw/3td8K4l1FZHv7TCZeJ3ZLb7dF3TWoGUP003RCqoji3/lHdKoVdTQNuR
77
- S/m6DlCwhjRjiQ/lBRgCLCcaAkEAjN891JBjzpMj4bWgsACmMggFf57DS0Ti+5++
78
- Q1VB8qkJN7rA7/2HrCR3gTsWNb1YhAsnFsoeRscC+LxXoXi9OAIUBG98h4tilg6S
79
- 55jreJD3Se3slps=
80
- -----END DSA PRIVATE KEY-----
81
- _end_of_pem_
82
-
83
- if defined?(OpenSSL::PKey::EC)
84
-
85
- TEST_KEY_EC_P256V1 = OpenSSL::PKey::EC.new <<-_end_of_pem_
86
- -----BEGIN EC PRIVATE KEY-----
87
- MHcCAQEEIID49FDqcf1O1eO8saTgG70UbXQw9Fqwseliit2aWhH1oAoGCCqGSM49
88
- AwEHoUQDQgAEFglk2c+oVUIKQ64eZG9bhLNPWB7lSZ/ArK41eGy5wAzU/0G51Xtt
89
- CeBUl+MahZtn9fO1JKdF4qJmS39dXnpENg==
90
- -----END EC PRIVATE KEY-----
91
- _end_of_pem_
92
-
93
- end
94
-
95
- TEST_KEY_DH512 = OpenSSL::PKey::DH.new <<-_end_of_pem_
96
- -----BEGIN DH PARAMETERS-----
97
- MEYCQQDmWXGPqk76sKw/edIOdhAQD4XzjJ+AR/PTk2qzaGs+u4oND2yU5D2NN4wr
98
- aPgwHyJBiK1/ebK3tYcrSKrOoRyrAgEC
99
- -----END DH PARAMETERS-----
100
- _end_of_pem_
101
-
102
- module_function
103
-
104
- def issue_cert(dn, key, serial, not_before, not_after, extensions,
105
- issuer, issuer_key, digest)
106
- cert = OpenSSL::X509::Certificate.new
107
- issuer = cert unless issuer
108
- issuer_key = key unless issuer_key
109
- cert.version = 2
110
- cert.serial = serial
111
- cert.subject = dn
112
- cert.issuer = issuer.subject
113
- cert.public_key = key.public_key
114
- cert.not_before = not_before
115
- cert.not_after = not_after
116
- ef = OpenSSL::X509::ExtensionFactory.new
117
- ef.subject_certificate = cert
118
- ef.issuer_certificate = issuer
119
- extensions.each{|oid, value, critical|
120
- cert.add_extension(ef.create_extension(oid, value, critical))
121
- }
122
- cert.sign(issuer_key, digest)
123
- cert
124
- end
125
-
126
- def issue_crl(revoke_info, serial, lastup, nextup, extensions,
127
- issuer, issuer_key, digest)
128
- crl = OpenSSL::X509::CRL.new
129
- crl.issuer = issuer.subject
130
- crl.version = 1
131
- crl.last_update = lastup
132
- crl.next_update = nextup
133
- revoke_info.each{|rserial, time, reason_code|
134
- revoked = OpenSSL::X509::Revoked.new
135
- revoked.serial = rserial
136
- revoked.time = time
137
- enum = OpenSSL::ASN1::Enumerated(reason_code)
138
- ext = OpenSSL::X509::Extension.new("CRLReason", enum)
139
- revoked.add_extension(ext)
140
- crl.add_revoked(revoked)
141
- }
142
- ef = OpenSSL::X509::ExtensionFactory.new
143
- ef.issuer_certificate = issuer
144
- ef.crl = crl
145
- crlnum = OpenSSL::ASN1::Integer(serial)
146
- crl.add_extension(OpenSSL::X509::Extension.new("crlNumber", crlnum))
147
- extensions.each{|oid, value, critical|
148
- crl.add_extension(ef.create_extension(oid, value, critical))
149
- }
150
- crl.sign(issuer_key, digest)
151
- crl
152
- end
153
-
154
- def get_subject_key_id(cert)
155
- asn1_cert = OpenSSL::ASN1.decode(cert)
156
- tbscert = asn1_cert.value[0]
157
- pkinfo = tbscert.value[6]
158
- publickey = pkinfo.value[1]
159
- pkvalue = publickey.value
160
- OpenSSL::Digest::SHA1.hexdigest(pkvalue).scan(/../).join(":").upcase
161
- end
162
-
163
- def silent
164
- begin
165
- back, $VERBOSE = $VERBOSE, nil
166
- yield
167
- ensure
168
- $VERBOSE = back
169
- end
170
- end
171
-
172
- class OpenSSL::SSLTestCase < Test::Unit::TestCase
173
- RUBY = EnvUtil.rubybin
174
- SSL_SERVER = File.join(File.dirname(__FILE__), "ssl_server.rb")
175
- PORT = 20443
176
- ITERATIONS = ($0 == __FILE__) ? 100 : 10
177
-
178
- def setup
179
- @ca_key = OpenSSL::TestUtils::TEST_KEY_RSA2048
180
- @svr_key = OpenSSL::TestUtils::TEST_KEY_RSA1024
181
- @cli_key = OpenSSL::TestUtils::TEST_KEY_DSA256
182
- @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
183
- @svr = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
184
- @cli = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
185
- now = Time.at(Time.now.to_i)
186
- ca_exts = [
187
- ["basicConstraints","CA:TRUE",true],
188
- ["keyUsage","cRLSign,keyCertSign",true],
189
- ]
190
- ee_exts = [
191
- ["keyUsage","keyEncipherment,digitalSignature",true],
192
- ]
193
- @ca_cert = issue_cert(@ca, @ca_key, 1, now, now+3600, ca_exts, nil, nil, OpenSSL::Digest::SHA1.new)
194
- @svr_cert = issue_cert(@svr, @svr_key, 2, now, now+1800, ee_exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
195
- @cli_cert = issue_cert(@cli, @cli_key, 3, now, now+1800, ee_exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
196
- @server = nil
197
- end
198
-
199
- def teardown
200
- end
201
-
202
- def issue_cert(*arg)
203
- OpenSSL::TestUtils.issue_cert(*arg)
204
- end
205
-
206
- def issue_crl(*arg)
207
- OpenSSL::TestUtils.issue_crl(*arg)
208
- end
209
-
210
- def readwrite_loop(ctx, ssl)
211
- while line = ssl.gets
212
- if line =~ /^STARTTLS$/
213
- ssl.accept
214
- next
215
- end
216
- ssl.write(line)
217
- end
218
- rescue OpenSSL::SSL::SSLError
219
- rescue IOError
220
- ensure
221
- ssl.close rescue nil
222
- end
223
-
224
- def server_loop(ctx, ssls, server_proc)
225
- loop do
226
- ssl = nil
227
- begin
228
- ssl = ssls.accept
229
- rescue OpenSSL::SSL::SSLError
230
- retry
231
- end
232
-
233
- Thread.start do
234
- Thread.current.abort_on_exception = true
235
- server_proc.call(ctx, ssl)
236
- end
237
- end
238
- rescue Errno::EBADF, IOError, Errno::EINVAL, Errno::ECONNABORTED, Errno::ENOTSOCK
239
- end
240
-
241
- DHParam = OpenSSL::PKey::DH.new(128)
242
- def start_server(port0, verify_mode, start_immediately, args = {}, &block)
243
- ctx_proc = args[:ctx_proc]
244
- server_proc = args[:server_proc]
245
- server_proc ||= method(:readwrite_loop)
246
-
247
- store = OpenSSL::X509::Store.new
248
- store.add_cert(@ca_cert)
249
- store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
250
- ctx = OpenSSL::SSL::SSLContext.new
251
- ctx.cert_store = store
252
- #ctx.extra_chain_cert = [ ca_cert ]
253
- ctx.cert = @svr_cert
254
- ctx.key = @svr_key
255
- ctx.tmp_dh_callback = proc { DHParam }
256
- ctx.verify_mode = verify_mode
257
- ctx_proc.call(ctx) if ctx_proc
258
-
259
- Socket.do_not_reverse_lookup = true
260
- tcps = nil
261
- port = port0
262
- begin
263
- tcps = TCPServer.new("127.0.0.1", port)
264
- rescue Errno::EADDRINUSE
265
- port += 1
266
- retry
267
- end
268
-
269
- ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
270
- ssls.start_immediately = start_immediately
271
-
272
- begin
273
- server = Thread.new do
274
- Thread.current.abort_on_exception = true
275
- server_loop(ctx, ssls, server_proc)
276
- end
277
-
278
- $stderr.printf("%s started: pid=%d port=%d\n", SSL_SERVER, $$, port) if $DEBUG
279
-
280
- block.call(server, port.to_i)
281
- ensure
282
- begin
283
- begin
284
- tcps.shutdown
285
- rescue Errno::ENOTCONN
286
- # when `Errno::ENOTCONN: Socket is not connected' on some platforms,
287
- # call #close instead of #shutdown.
288
- tcps.close
289
- tcps = nil
290
- end if (tcps)
291
- if (server)
292
- server.join(5)
293
- if server.alive?
294
- server.kill
295
- server.join
296
- flunk("TCPServer was closed and SSLServer is still alive") unless $!
297
- end
298
- end
299
- ensure
300
- tcps.close if (tcps)
301
- end
302
- end
303
- end
304
-
305
- def starttls(ssl)
306
- ssl.puts("STARTTLS")
307
- sleep 1 # When this line is eliminated, process on Cygwin blocks
308
- # forever at ssl.connect. But I don't know why it does.
309
- ssl.connect
310
- end
311
- end
312
-
313
- end if defined?(OpenSSL)