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.
- checksums.yaml +7 -0
- data/lib/webrick.rb +6 -6
- data/lib/webrick/accesslog.rb +9 -1
- data/lib/webrick/cgi.rb +51 -2
- data/lib/webrick/compat.rb +2 -1
- data/lib/webrick/config.rb +42 -5
- data/lib/webrick/cookie.rb +68 -6
- data/lib/webrick/htmlutils.rb +4 -2
- data/lib/webrick/httpauth.rb +1 -0
- data/lib/webrick/httpauth/authenticator.rb +13 -8
- data/lib/webrick/httpauth/basicauth.rb +3 -3
- data/lib/webrick/httpauth/digestauth.rb +25 -9
- data/lib/webrick/httpauth/htdigest.rb +8 -4
- data/lib/webrick/httpauth/htgroup.rb +1 -0
- data/lib/webrick/httpauth/htpasswd.rb +7 -3
- data/lib/webrick/httpauth/userdb.rb +1 -0
- data/lib/webrick/httpproxy.rb +47 -14
- data/lib/webrick/httprequest.rb +142 -16
- data/lib/webrick/httpresponse.rb +96 -24
- data/lib/webrick/https.rb +24 -1
- data/lib/webrick/httpserver.rb +20 -4
- data/lib/webrick/httpservlet.rb +1 -0
- data/lib/webrick/httpservlet/abstract.rb +2 -1
- data/lib/webrick/httpservlet/cgi_runner.rb +1 -0
- data/lib/webrick/httpservlet/cgihandler.rb +19 -5
- data/lib/webrick/httpservlet/erbhandler.rb +2 -1
- data/lib/webrick/httpservlet/filehandler.rb +87 -34
- data/lib/webrick/httpservlet/prochandler.rb +14 -0
- data/lib/webrick/httpstatus.rb +24 -10
- data/lib/webrick/httputils.rb +129 -13
- data/lib/webrick/httpversion.rb +28 -1
- data/lib/webrick/log.rb +22 -2
- data/lib/webrick/server.rb +203 -60
- data/lib/webrick/ssl.rb +80 -5
- data/lib/webrick/utils.rb +97 -67
- data/lib/webrick/version.rb +6 -1
- metadata +59 -69
- data/README.txt +0 -21
- data/sample/webrick/demo-app.rb +0 -66
- data/sample/webrick/demo-multipart.cgi +0 -12
- data/sample/webrick/demo-servlet.rb +0 -6
- data/sample/webrick/demo-urlencoded.cgi +0 -12
- data/sample/webrick/hello.cgi +0 -11
- data/sample/webrick/hello.rb +0 -8
- data/sample/webrick/httpd.rb +0 -23
- data/sample/webrick/httpproxy.rb +0 -25
- data/sample/webrick/httpsd.rb +0 -33
- data/test/openssl/utils.rb +0 -313
- data/test/ruby/envutil.rb +0 -208
- data/test/webrick/test_cgi.rb +0 -134
- data/test/webrick/test_cookie.rb +0 -131
- data/test/webrick/test_filehandler.rb +0 -285
- data/test/webrick/test_httpauth.rb +0 -167
- data/test/webrick/test_httpproxy.rb +0 -282
- data/test/webrick/test_httprequest.rb +0 -411
- data/test/webrick/test_httpresponse.rb +0 -49
- data/test/webrick/test_httpserver.rb +0 -305
- data/test/webrick/test_httputils.rb +0 -96
- data/test/webrick/test_httpversion.rb +0 -40
- data/test/webrick/test_server.rb +0 -67
- data/test/webrick/test_utils.rb +0 -64
- data/test/webrick/utils.rb +0 -58
- data/test/webrick/webrick.cgi +0 -36
- 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.
|
data/sample/webrick/demo-app.rb
DELETED
@@ -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,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
|
data/sample/webrick/hello.cgi
DELETED
data/sample/webrick/hello.rb
DELETED
data/sample/webrick/httpd.rb
DELETED
@@ -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
|
data/sample/webrick/httpproxy.rb
DELETED
@@ -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
|
data/sample/webrick/httpsd.rb
DELETED
@@ -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
|
data/test/openssl/utils.rb
DELETED
@@ -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)
|