rubysl-drb 1.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +3 -2
- data/lib/drb/acl.rb +128 -24
- data/lib/drb/drb.rb +349 -299
- data/lib/drb/eq.rb +1 -3
- data/lib/drb/extserv.rb +16 -7
- data/lib/drb/extservm.rb +17 -13
- data/lib/drb/gw.rb +40 -2
- data/lib/drb/invokemethod.rb +6 -6
- data/lib/drb/observer.rb +13 -10
- data/lib/drb/ssl.rb +246 -93
- data/lib/drb/timeridconv.rb +53 -43
- data/lib/drb/unix.rb +32 -25
- data/lib/rubysl/drb/version.rb +1 -1
- data/rubysl-drb.gemspec +3 -1
- data/spec/drbserver/here_spec.rb +6 -0
- data/spec/drbserver/verbose_spec.rb +4 -4
- metadata +20 -17
data/lib/drb/eq.rb
CHANGED
data/lib/drb/extserv.rb
CHANGED
@@ -1,19 +1,24 @@
|
|
1
1
|
=begin
|
2
2
|
external service
|
3
|
-
|
3
|
+
Copyright (c) 2000,2002 Masatoshi SEKI
|
4
4
|
=end
|
5
5
|
|
6
6
|
require 'drb/drb'
|
7
|
+
require 'monitor'
|
7
8
|
|
8
9
|
module DRb
|
9
10
|
class ExtServ
|
11
|
+
include MonitorMixin
|
10
12
|
include DRbUndumped
|
11
13
|
|
12
14
|
def initialize(there, name, server=nil)
|
15
|
+
super()
|
13
16
|
@server = server || DRb::primary_server
|
14
17
|
@name = name
|
15
18
|
ro = DRbObject.new(nil, there)
|
16
|
-
|
19
|
+
synchronize do
|
20
|
+
@invoker = ro.regist(name, DRbObject.new(self, @server.uri))
|
21
|
+
end
|
17
22
|
end
|
18
23
|
attr_reader :server
|
19
24
|
|
@@ -22,11 +27,13 @@ module DRb
|
|
22
27
|
end
|
23
28
|
|
24
29
|
def stop_service
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
+
synchronize do
|
31
|
+
@invoker.unregist(@name)
|
32
|
+
server = @server
|
33
|
+
@server = nil
|
34
|
+
server.stop_service
|
35
|
+
true
|
36
|
+
end
|
30
37
|
end
|
31
38
|
|
32
39
|
def alive?
|
@@ -35,6 +42,8 @@ module DRb
|
|
35
42
|
end
|
36
43
|
end
|
37
44
|
|
45
|
+
# :stopdoc:
|
46
|
+
|
38
47
|
if __FILE__ == $0
|
39
48
|
class Foo
|
40
49
|
include DRbUndumped
|
data/lib/drb/extservm.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
=begin
|
2
2
|
external service manager
|
3
|
-
|
3
|
+
Copyright (c) 2000 Masatoshi SEKI
|
4
4
|
=end
|
5
5
|
|
6
6
|
require 'drb/drb'
|
@@ -21,7 +21,7 @@ module DRb
|
|
21
21
|
def self.command=(cmd)
|
22
22
|
@@command = cmd
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def initialize
|
26
26
|
super()
|
27
27
|
@cond = new_cond
|
@@ -51,20 +51,20 @@ module DRb
|
|
51
51
|
end
|
52
52
|
self
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
def unregist(name)
|
56
56
|
synchronize do
|
57
|
-
|
57
|
+
@servers.delete(name)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
private
|
62
62
|
def invoke_thread
|
63
63
|
Thread.new do
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
while true
|
65
|
+
name = @queue.pop
|
66
|
+
invoke_service_command(name, @@command[name])
|
67
|
+
end
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -75,15 +75,19 @@ module DRb
|
|
75
75
|
def invoke_service_command(name, command)
|
76
76
|
raise "invalid command. name: #{name}" unless command
|
77
77
|
synchronize do
|
78
|
-
|
79
|
-
|
78
|
+
return if @servers.include?(name)
|
79
|
+
@servers[name] = false
|
80
80
|
end
|
81
81
|
uri = @uri || DRb.uri
|
82
|
-
if
|
83
|
-
|
82
|
+
if command.respond_to? :to_ary
|
83
|
+
command = command.to_ary + [uri, name]
|
84
|
+
pid = spawn(*command)
|
84
85
|
else
|
85
|
-
|
86
|
+
pid = spawn("#{command} #{uri} #{name}")
|
86
87
|
end
|
88
|
+
th = Process.detach(pid)
|
89
|
+
th[:drb_service] = name
|
90
|
+
th
|
87
91
|
end
|
88
92
|
end
|
89
93
|
end
|
data/lib/drb/gw.rb
CHANGED
@@ -2,8 +2,36 @@ require 'drb/drb'
|
|
2
2
|
require 'monitor'
|
3
3
|
|
4
4
|
module DRb
|
5
|
+
|
6
|
+
# Gateway id conversion forms a gateway between different DRb protocols or
|
7
|
+
# networks.
|
8
|
+
#
|
9
|
+
# The gateway needs to install this id conversion and create servers for
|
10
|
+
# each of the protocols or networks it will be a gateway between. It then
|
11
|
+
# needs to create a server that attaches to each of these networks. For
|
12
|
+
# example:
|
13
|
+
#
|
14
|
+
# require 'drb/drb'
|
15
|
+
# require 'drb/unix'
|
16
|
+
# require 'drb/gw'
|
17
|
+
#
|
18
|
+
# DRb.install_id_conv DRb::GWIdConv.new
|
19
|
+
# gw = DRb::GW.new
|
20
|
+
# s1 = DRb::DRbServer.new 'drbunix:/path/to/gateway', gw
|
21
|
+
# s2 = DRb::DRbServer.new 'druby://example:10000', gw
|
22
|
+
#
|
23
|
+
# s1.thread.join
|
24
|
+
# s2.thread.join
|
25
|
+
#
|
26
|
+
# Each client must register services with the gateway, for example:
|
27
|
+
#
|
28
|
+
# DRb.start_service 'drbunix:', nil # an anonymous server
|
29
|
+
# gw = DRbObject.new nil, 'drbunix:/path/to/gateway'
|
30
|
+
# gw[:unix] = some_service
|
31
|
+
# DRb.thread.join
|
32
|
+
|
5
33
|
class GWIdConv < DRbIdConv
|
6
|
-
def to_obj(ref)
|
34
|
+
def to_obj(ref) # :nodoc:
|
7
35
|
if Array === ref && ref[0] == :DRbObject
|
8
36
|
return DRbObject.new_with(ref[1], ref[2])
|
9
37
|
end
|
@@ -11,19 +39,29 @@ module DRb
|
|
11
39
|
end
|
12
40
|
end
|
13
41
|
|
42
|
+
# The GW provides a synchronized store for participants in the gateway to
|
43
|
+
# communicate.
|
44
|
+
|
14
45
|
class GW
|
15
46
|
include MonitorMixin
|
47
|
+
|
48
|
+
# Creates a new GW
|
49
|
+
|
16
50
|
def initialize
|
17
51
|
super()
|
18
52
|
@hash = {}
|
19
53
|
end
|
20
54
|
|
55
|
+
# Retrieves +key+ from the GW
|
56
|
+
|
21
57
|
def [](key)
|
22
58
|
synchronize do
|
23
59
|
@hash[key]
|
24
60
|
end
|
25
61
|
end
|
26
62
|
|
63
|
+
# Stores value +v+ at +key+ in the GW
|
64
|
+
|
27
65
|
def []=(key, v)
|
28
66
|
synchronize do
|
29
67
|
@hash[key] = v
|
@@ -31,7 +69,7 @@ module DRb
|
|
31
69
|
end
|
32
70
|
end
|
33
71
|
|
34
|
-
class DRbObject
|
72
|
+
class DRbObject # :nodoc:
|
35
73
|
def self._load(s)
|
36
74
|
uri, ref = Marshal.load(s)
|
37
75
|
if DRb.uri == uri
|
data/lib/drb/invokemethod.rb
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
module DRb
|
4
4
|
class DRbServer
|
5
|
-
module InvokeMethod18Mixin
|
5
|
+
module InvokeMethod18Mixin # :nodoc: all
|
6
6
|
def block_yield(x)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
if x.size == 1 && x[0].class == Array
|
8
|
+
x[0] = DRbArray.new(x[0])
|
9
|
+
end
|
10
|
+
@block.call(*x)
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def perform_with_block
|
14
14
|
@obj.__send__(@msg_id, *@argv) do |*x|
|
15
15
|
jump_error = nil
|
data/lib/drb/observer.rb
CHANGED
@@ -1,21 +1,24 @@
|
|
1
1
|
require 'observer'
|
2
2
|
|
3
3
|
module DRb
|
4
|
+
# The Observable module extended to DRb. See Observable for details.
|
4
5
|
module DRbObservable
|
5
6
|
include Observable
|
6
7
|
|
8
|
+
# Notifies observers of a change in state. See also
|
9
|
+
# Observable#notify_observers
|
7
10
|
def notify_observers(*arg)
|
8
11
|
if defined? @observer_state and @observer_state
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
if defined? @observer_peers
|
13
|
+
@observer_peers.each do |observer, method|
|
14
|
+
begin
|
15
|
+
observer.send(method, *arg)
|
16
|
+
rescue
|
17
|
+
delete_observer(observer)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
@observer_state = false
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
data/lib/drb/ssl.rb
CHANGED
@@ -5,124 +5,248 @@ require 'singleton'
|
|
5
5
|
|
6
6
|
module DRb
|
7
7
|
|
8
|
+
# The protocol for DRb over an SSL socket
|
9
|
+
#
|
10
|
+
# The URI for a DRb socket over SSL is:
|
11
|
+
# <code>drbssl://<host>:<port>?<option></code>. The option is optional
|
8
12
|
class DRbSSLSocket < DRbTCPSocket
|
9
13
|
|
14
|
+
# SSLConfig handles the needed SSL information for establishing a
|
15
|
+
# DRbSSLSocket connection, including generating the X509 / RSA pair.
|
16
|
+
#
|
17
|
+
# An instance of this config can be passed to DRbSSLSocket.new,
|
18
|
+
# DRbSSLSocket.open and DRbSSLSocket.open_server
|
19
|
+
#
|
20
|
+
# See DRb::DRbSSLSocket::SSLConfig.new for more details
|
10
21
|
class SSLConfig
|
11
22
|
|
23
|
+
# Default values for a SSLConfig instance.
|
24
|
+
#
|
25
|
+
# See DRb::DRbSSLSocket::SSLConfig.new for more details
|
12
26
|
DEFAULT = {
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
27
|
+
:SSLCertificate => nil,
|
28
|
+
:SSLPrivateKey => nil,
|
29
|
+
:SSLClientCA => nil,
|
30
|
+
:SSLCACertificatePath => nil,
|
31
|
+
:SSLCACertificateFile => nil,
|
32
|
+
:SSLTmpDhCallback => nil,
|
33
|
+
:SSLVerifyMode => ::OpenSSL::SSL::VERIFY_NONE,
|
34
|
+
:SSLVerifyDepth => nil,
|
35
|
+
:SSLVerifyCallback => nil, # custom verification
|
21
36
|
:SSLCertificateStore => nil,
|
22
|
-
|
23
|
-
|
24
|
-
|
37
|
+
# Must specify if you use auto generated certificate.
|
38
|
+
:SSLCertName => nil, # e.g. [["CN","fqdn.example.com"]]
|
39
|
+
:SSLCertComment => "Generated by Ruby/OpenSSL"
|
25
40
|
}
|
26
41
|
|
42
|
+
# Create a new DRb::DRbSSLSocket::SSLConfig instance
|
43
|
+
#
|
44
|
+
# The DRb::DRbSSLSocket will take either a +config+ Hash or an instance
|
45
|
+
# of SSLConfg, and will setup the certificate for its session for the
|
46
|
+
# configuration. If want it to generate a generic certificate, the bare
|
47
|
+
# minimum is to provide the :SSLCertName
|
48
|
+
#
|
49
|
+
# === Config options
|
50
|
+
#
|
51
|
+
# From +config+ Hash:
|
52
|
+
#
|
53
|
+
# :SSLCertificate ::
|
54
|
+
# An instance of OpenSSL::X509::Certificate. If this is not provided,
|
55
|
+
# then a generic X509 is generated, with a correspond :SSLPrivateKey
|
56
|
+
#
|
57
|
+
# :SSLPrivateKey ::
|
58
|
+
# A private key instance, like OpenSSL::PKey::RSA. This key must be
|
59
|
+
# the key that signed the :SSLCertificate
|
60
|
+
#
|
61
|
+
# :SSLClientCA ::
|
62
|
+
# An OpenSSL::X509::Certificate, or Array of certificates that will
|
63
|
+
# used as ClientCAs in the SSL Context
|
64
|
+
#
|
65
|
+
# :SSLCACertificatePath ::
|
66
|
+
# A path to the directory of CA certificates. The certificates must
|
67
|
+
# be in PEM format.
|
68
|
+
#
|
69
|
+
# :SSLCACertificateFile ::
|
70
|
+
# A path to a CA certificate file, in PEM format.
|
71
|
+
#
|
72
|
+
# :SSLTmpDhCallback ::
|
73
|
+
# A DH callback. See OpenSSL::SSL::SSLContext.tmp_dh_callback
|
74
|
+
#
|
75
|
+
# :SSLVerifyMode ::
|
76
|
+
# This is the SSL verification mode. See OpenSSL::SSL::VERIFY_* for
|
77
|
+
# available modes. The default is OpenSSL::SSL::VERIFY_NONE
|
78
|
+
#
|
79
|
+
# :SSLVerifyDepth ::
|
80
|
+
# Number of CA certificates to walk, when verifying a certificate
|
81
|
+
# chain.
|
82
|
+
#
|
83
|
+
# :SSLVerifyCallback ::
|
84
|
+
# A callback to be used for additional verification. See
|
85
|
+
# OpenSSL::SSL::SSLContext.verify_callback
|
86
|
+
#
|
87
|
+
# :SSLCertificateStore ::
|
88
|
+
# A OpenSSL::X509::Store used for verification of certificates
|
89
|
+
#
|
90
|
+
# :SSLCertName ::
|
91
|
+
# Issuer name for the certificate. This is required when generating
|
92
|
+
# the certificate (if :SSLCertificate and :SSLPrivateKey were not
|
93
|
+
# given). The value of this is to be an Array of pairs:
|
94
|
+
#
|
95
|
+
# [["C", "Raleigh"], ["ST","North Carolina"],
|
96
|
+
# ["CN","fqdn.example.com"]]
|
97
|
+
#
|
98
|
+
# See also OpenSSL::X509::Name
|
99
|
+
#
|
100
|
+
# :SSLCertComment ::
|
101
|
+
# A comment to be used for generating the certificate. The default is
|
102
|
+
# "Generated by Ruby/OpenSSL"
|
103
|
+
#
|
104
|
+
#
|
105
|
+
# === Example
|
106
|
+
#
|
107
|
+
# These values can be added after the fact, like a Hash.
|
108
|
+
#
|
109
|
+
# require 'drb/ssl'
|
110
|
+
# c = DRb::DRbSSLSocket::SSLConfig.new {}
|
111
|
+
# c[:SSLCertificate] =
|
112
|
+
# OpenSSL::X509::Certificate.new(File.read('mycert.crt'))
|
113
|
+
# c[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(File.read('mycert.key'))
|
114
|
+
# c[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
|
115
|
+
# c[:SSLCACertificatePath] = "/etc/ssl/certs/"
|
116
|
+
# c.setup_certificate
|
117
|
+
#
|
118
|
+
# or
|
119
|
+
#
|
120
|
+
# require 'drb/ssl'
|
121
|
+
# c = DRb::DRbSSLSocket::SSLConfig.new({
|
122
|
+
# :SSLCertName => [["CN" => DRb::DRbSSLSocket.getservername]]
|
123
|
+
# })
|
124
|
+
# c.setup_certificate
|
125
|
+
#
|
27
126
|
def initialize(config)
|
28
|
-
|
127
|
+
@config = config
|
29
128
|
@cert = config[:SSLCertificate]
|
30
129
|
@pkey = config[:SSLPrivateKey]
|
31
130
|
@ssl_ctx = nil
|
32
131
|
end
|
33
132
|
|
34
|
-
|
35
|
-
|
133
|
+
# A convenience method to access the values like a Hash
|
134
|
+
def [](key);
|
135
|
+
@config[key] || DEFAULT[key]
|
36
136
|
end
|
37
137
|
|
138
|
+
# Connect to IO +tcp+, with context of the current certificate
|
139
|
+
# configuration
|
38
140
|
def connect(tcp)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
141
|
+
ssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
|
142
|
+
ssl.sync = true
|
143
|
+
ssl.connect
|
144
|
+
ssl
|
43
145
|
end
|
44
|
-
|
146
|
+
|
147
|
+
# Accept connection to IO +tcp+, with context of the current certificate
|
148
|
+
# configuration
|
45
149
|
def accept(tcp)
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
150
|
+
ssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
|
151
|
+
ssl.sync = true
|
152
|
+
ssl.accept
|
153
|
+
ssl
|
50
154
|
end
|
51
|
-
|
155
|
+
|
156
|
+
# Ensures that :SSLCertificate and :SSLPrivateKey have been provided
|
157
|
+
# or that a new certificate is generated with the other parameters
|
158
|
+
# provided.
|
52
159
|
def setup_certificate
|
53
160
|
if @cert && @pkey
|
54
161
|
return
|
55
162
|
end
|
56
163
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
164
|
+
rsa = OpenSSL::PKey::RSA.new(1024){|p, n|
|
165
|
+
next unless self[:verbose]
|
166
|
+
case p
|
167
|
+
when 0; $stderr.putc "." # BN_generate_prime
|
168
|
+
when 1; $stderr.putc "+" # BN_generate_prime
|
169
|
+
when 2; $stderr.putc "*" # searching good prime,
|
170
|
+
# n = #of try,
|
171
|
+
# but also data from BN_generate_prime
|
172
|
+
when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
|
173
|
+
# but also data from BN_generate_prime
|
174
|
+
else; $stderr.putc "*" # BN_generate_prime
|
175
|
+
end
|
176
|
+
}
|
177
|
+
|
178
|
+
cert = OpenSSL::X509::Certificate.new
|
179
|
+
cert.version = 3
|
180
|
+
cert.serial = 0
|
181
|
+
name = OpenSSL::X509::Name.new(self[:SSLCertName])
|
182
|
+
cert.subject = name
|
183
|
+
cert.issuer = name
|
184
|
+
cert.not_before = Time.now
|
185
|
+
cert.not_after = Time.now + (365*24*60*60)
|
186
|
+
cert.public_key = rsa.public_key
|
187
|
+
|
188
|
+
ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
|
189
|
+
cert.extensions = [
|
190
|
+
ef.create_extension("basicConstraints","CA:FALSE"),
|
191
|
+
ef.create_extension("subjectKeyIdentifier", "hash") ]
|
192
|
+
ef.issuer_certificate = cert
|
193
|
+
cert.add_extension(ef.create_extension("authorityKeyIdentifier",
|
194
|
+
"keyid:always,issuer:always"))
|
195
|
+
if comment = self[:SSLCertComment]
|
196
|
+
cert.add_extension(ef.create_extension("nsComment", comment))
|
197
|
+
end
|
198
|
+
cert.sign(rsa, OpenSSL::Digest::SHA1.new)
|
199
|
+
|
200
|
+
@cert = cert
|
94
201
|
@pkey = rsa
|
95
202
|
end
|
96
203
|
|
204
|
+
# Establish the OpenSSL::SSL::SSLContext with the configuration
|
205
|
+
# parameters provided.
|
97
206
|
def setup_ssl_context
|
98
207
|
ctx = ::OpenSSL::SSL::SSLContext.new
|
99
208
|
ctx.cert = @cert
|
100
209
|
ctx.key = @pkey
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
210
|
+
ctx.client_ca = self[:SSLClientCA]
|
211
|
+
ctx.ca_path = self[:SSLCACertificatePath]
|
212
|
+
ctx.ca_file = self[:SSLCACertificateFile]
|
213
|
+
ctx.tmp_dh_callback = self[:SSLTmpDhCallback]
|
214
|
+
ctx.verify_mode = self[:SSLVerifyMode]
|
215
|
+
ctx.verify_depth = self[:SSLVerifyDepth]
|
216
|
+
ctx.verify_callback = self[:SSLVerifyCallback]
|
107
217
|
ctx.cert_store = self[:SSLCertificateStore]
|
108
218
|
@ssl_ctx = ctx
|
109
219
|
end
|
110
220
|
end
|
111
221
|
|
112
|
-
|
222
|
+
# Parse the dRuby +uri+ for an SSL connection.
|
223
|
+
#
|
224
|
+
# Expects drbssl://...
|
225
|
+
#
|
226
|
+
# Raises DRbBadScheme or DRbBadURI if +uri+ is not matching or malformed
|
227
|
+
def self.parse_uri(uri) # :nodoc:
|
113
228
|
if uri =~ /^drbssl:\/\/(.*?):(\d+)(\?(.*))?$/
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
229
|
+
host = $1
|
230
|
+
port = $2.to_i
|
231
|
+
option = $4
|
232
|
+
[host, port, option]
|
118
233
|
else
|
119
|
-
|
120
|
-
|
234
|
+
raise(DRbBadScheme, uri) unless uri =~ /^drbssl:/
|
235
|
+
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
121
236
|
end
|
122
237
|
end
|
123
238
|
|
239
|
+
# Return an DRb::DRbSSLSocket instance as a client-side connection,
|
240
|
+
# with the SSL connected. This is called from DRb::start_service or while
|
241
|
+
# connecting to a remote object:
|
242
|
+
#
|
243
|
+
# DRb.start_service 'drbssl://localhost:0', front, config
|
244
|
+
#
|
245
|
+
# +uri+ is the URI we are connected to,
|
246
|
+
# <code>'drbssl://localhost:0'</code> above, +config+ is our
|
247
|
+
# configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig
|
124
248
|
def self.open(uri, config)
|
125
|
-
host, port,
|
249
|
+
host, port, = parse_uri(uri)
|
126
250
|
host.untaint
|
127
251
|
port.untaint
|
128
252
|
soc = TCPSocket.open(host, port)
|
@@ -132,59 +256,88 @@ module DRb
|
|
132
256
|
self.new(uri, ssl, ssl_conf, true)
|
133
257
|
end
|
134
258
|
|
259
|
+
# Returns a DRb::DRbSSLSocket instance as a server-side connection, with
|
260
|
+
# the SSL connected. This is called from DRb::start_service or while
|
261
|
+
# connecting to a remote object:
|
262
|
+
#
|
263
|
+
# DRb.start_service 'drbssl://localhost:0', front, config
|
264
|
+
#
|
265
|
+
# +uri+ is the URI we are connected to,
|
266
|
+
# <code>'drbssl://localhost:0'</code> above, +config+ is our
|
267
|
+
# configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig
|
135
268
|
def self.open_server(uri, config)
|
136
269
|
uri = 'drbssl://:0' unless uri
|
137
|
-
host, port,
|
270
|
+
host, port, = parse_uri(uri)
|
138
271
|
if host.size == 0
|
139
272
|
host = getservername
|
140
273
|
soc = open_server_inaddr_any(host, port)
|
141
274
|
else
|
142
|
-
|
275
|
+
soc = TCPServer.open(host, port)
|
143
276
|
end
|
144
277
|
port = soc.addr[1] if port == 0
|
145
278
|
@uri = "drbssl://#{host}:#{port}"
|
146
|
-
|
279
|
+
|
147
280
|
ssl_conf = SSLConfig.new(config)
|
148
281
|
ssl_conf.setup_certificate
|
149
282
|
ssl_conf.setup_ssl_context
|
150
283
|
self.new(@uri, soc, ssl_conf, false)
|
151
284
|
end
|
152
285
|
|
153
|
-
|
286
|
+
# This is a convenience method to parse +uri+ and separate out any
|
287
|
+
# additional options appended in the +uri+.
|
288
|
+
#
|
289
|
+
# Returns an option-less uri and the option => [uri,option]
|
290
|
+
#
|
291
|
+
# The +config+ is completely unused, so passing nil is sufficient.
|
292
|
+
def self.uri_option(uri, config) # :nodoc:
|
154
293
|
host, port, option = parse_uri(uri)
|
155
294
|
return "drbssl://#{host}:#{port}", option
|
156
295
|
end
|
157
296
|
|
297
|
+
# Create a DRb::DRbSSLSocket instance.
|
298
|
+
#
|
299
|
+
# +uri+ is the URI we are connected to.
|
300
|
+
# +soc+ is the tcp socket we are bound to.
|
301
|
+
# +config+ is our configuration. Either a Hash or SSLConfig
|
302
|
+
# +is_established+ is a boolean of whether +soc+ is currenly established
|
303
|
+
#
|
304
|
+
# This is called automatically based on the DRb protocol.
|
158
305
|
def initialize(uri, soc, config, is_established)
|
159
306
|
@ssl = is_established ? soc : nil
|
160
307
|
super(uri, soc.to_io, config)
|
161
308
|
end
|
162
|
-
|
163
|
-
def stream; @ssl; end
|
164
309
|
|
165
|
-
|
310
|
+
# Returns the SSL stream
|
311
|
+
def stream; @ssl; end # :nodoc:
|
312
|
+
|
313
|
+
# Closes the SSL stream before closing the dRuby connection.
|
314
|
+
def close # :nodoc:
|
166
315
|
if @ssl
|
167
|
-
|
168
|
-
|
316
|
+
@ssl.close
|
317
|
+
@ssl = nil
|
169
318
|
end
|
170
319
|
super
|
171
320
|
end
|
172
|
-
|
173
|
-
def accept
|
321
|
+
|
322
|
+
def accept # :nodoc:
|
174
323
|
begin
|
175
324
|
while true
|
176
|
-
|
177
|
-
|
178
|
-
|
325
|
+
soc = @socket.accept
|
326
|
+
break if (@acl ? @acl.allow_socket?(soc) : true)
|
327
|
+
soc.close
|
328
|
+
end
|
329
|
+
begin
|
330
|
+
ssl = @config.accept(soc)
|
331
|
+
ensure
|
332
|
+
soc.close if $!
|
179
333
|
end
|
180
|
-
ssl = @config.accept(soc)
|
181
334
|
self.class.new(uri, ssl, @config, true)
|
182
335
|
rescue OpenSSL::SSL::SSLError
|
183
|
-
|
184
|
-
|
336
|
+
warn("#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})") if @config[:verbose]
|
337
|
+
retry
|
185
338
|
end
|
186
339
|
end
|
187
340
|
end
|
188
|
-
|
341
|
+
|
189
342
|
DRbProtocol.add_protocol(DRbSSLSocket)
|
190
343
|
end
|