processwanker 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +34 -0
- data/README +11 -0
- data/Rakefile +13 -0
- data/bin/pw +5 -0
- data/lib/config/config.rb +96 -0
- data/lib/config/config_auth.rb +208 -0
- data/lib/config/config_client.rb +75 -0
- data/lib/config/config_client_cluster.rb +66 -0
- data/lib/config/config_client_clusters.rb +62 -0
- data/lib/config/config_client_host.rb +152 -0
- data/lib/config/config_daemon.rb +94 -0
- data/lib/config/config_daemon_service.rb +84 -0
- data/lib/config/config_daemon_service_dependency.rb +59 -0
- data/lib/config/config_daemon_services.rb +89 -0
- data/lib/config/config_hook.rb +40 -0
- data/lib/config/config_node.rb +160 -0
- data/lib/config/config_smtp.rb +103 -0
- data/lib/events.rb +224 -0
- data/lib/log.rb +88 -0
- data/lib/net/net_api.rb +189 -0
- data/lib/net/net_client.rb +107 -0
- data/lib/net/net_connection.rb +167 -0
- data/lib/net/net_server.rb +232 -0
- data/lib/net/net_server_client.rb +84 -0
- data/lib/net/net_util.rb +205 -0
- data/lib/process_util.rb +216 -0
- data/lib/pw_app.rb +557 -0
- data/lib/service.rb +512 -0
- data/lib/service_classes/dummy_service.rb +88 -0
- data/lib/service_classes/pid_service.rb +126 -0
- data/lib/service_classes/process_service.rb +218 -0
- data/lib/service_classes/upstart_service.rb +103 -0
- data/lib/service_mgr.rb +226 -0
- data/lib/util.rb +31 -0
- data/processwanker.gemspec +36 -0
- data.tar.gz.sig +0 -0
- metadata +157 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,167 @@
|
|
1
|
+
############################################################################
|
2
|
+
#
|
3
|
+
# net_connection.rb
|
4
|
+
#
|
5
|
+
# handles the physical TCP/SSL connection between client(s) and daemon(s)
|
6
|
+
#
|
7
|
+
############################################################################
|
8
|
+
|
9
|
+
require 'openssl'
|
10
|
+
require 'config'
|
11
|
+
require 'thread'
|
12
|
+
require 'util'
|
13
|
+
|
14
|
+
module ProcessWanker
|
15
|
+
|
16
|
+
############################################################################
|
17
|
+
#
|
18
|
+
#
|
19
|
+
#
|
20
|
+
############################################################################
|
21
|
+
|
22
|
+
class NetConnection
|
23
|
+
include Log
|
24
|
+
|
25
|
+
attr_accessor :ssl_connection
|
26
|
+
attr_accessor :user
|
27
|
+
|
28
|
+
############################################################################
|
29
|
+
#
|
30
|
+
#
|
31
|
+
#
|
32
|
+
############################################################################
|
33
|
+
|
34
|
+
def initialize(ssl_connection)
|
35
|
+
@write_mutex=Mutex.new
|
36
|
+
@ssl_connection=ssl_connection
|
37
|
+
@read_thread = Thread.new { read_proc }
|
38
|
+
@user = ssl_connection.peer_cert.subject.to_a.select { |x| x[0]=="CN" }.map { |x| x[1] }[0]
|
39
|
+
end
|
40
|
+
|
41
|
+
############################################################################
|
42
|
+
#
|
43
|
+
#
|
44
|
+
#
|
45
|
+
############################################################################
|
46
|
+
|
47
|
+
def wait
|
48
|
+
@read_thread.join
|
49
|
+
end
|
50
|
+
|
51
|
+
############################################################################
|
52
|
+
#
|
53
|
+
#
|
54
|
+
#
|
55
|
+
############################################################################
|
56
|
+
|
57
|
+
def send_msg(msg)
|
58
|
+
|
59
|
+
@write_mutex.synchronize do
|
60
|
+
debug("sending message #{msg.inspect}")
|
61
|
+
begin
|
62
|
+
data=Marshal.dump(msg)
|
63
|
+
length=[data.length].pack("N")
|
64
|
+
@ssl_connection.write(length + data)
|
65
|
+
rescue Exception => e
|
66
|
+
on_close()
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
############################################################################
|
73
|
+
#
|
74
|
+
#
|
75
|
+
#
|
76
|
+
############################################################################
|
77
|
+
|
78
|
+
def close_rudely()
|
79
|
+
ProcessWanker::with_logged_rescue("close_rudely",Log::DEBUG) do
|
80
|
+
@ssl_connection.io.close()
|
81
|
+
end
|
82
|
+
disconnect()
|
83
|
+
end
|
84
|
+
|
85
|
+
############################################################################
|
86
|
+
#
|
87
|
+
#
|
88
|
+
#
|
89
|
+
############################################################################
|
90
|
+
|
91
|
+
def disconnect()
|
92
|
+
on_close()
|
93
|
+
if(Thread.current != @read_thread)
|
94
|
+
@read_thread.join
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
############################################################################
|
99
|
+
#
|
100
|
+
#
|
101
|
+
#
|
102
|
+
############################################################################
|
103
|
+
|
104
|
+
def read_proc
|
105
|
+
while(@ssl_connection)
|
106
|
+
read_connection()
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
############################################################################
|
111
|
+
#
|
112
|
+
#
|
113
|
+
#
|
114
|
+
############################################################################
|
115
|
+
|
116
|
+
def read_connection()
|
117
|
+
begin
|
118
|
+
length=@ssl_connection.read(4)
|
119
|
+
raise "closed" if(length.length != 4)
|
120
|
+
length=length.unpack("N")[0]
|
121
|
+
data=@ssl_connection.read(length)
|
122
|
+
raise "closed" if(data.length != length)
|
123
|
+
msg=Marshal.load(data)
|
124
|
+
on_msg(msg)
|
125
|
+
rescue Exception => e
|
126
|
+
on_close()
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
############################################################################
|
131
|
+
#
|
132
|
+
#
|
133
|
+
#
|
134
|
+
############################################################################
|
135
|
+
|
136
|
+
def on_close()
|
137
|
+
ProcessWanker::with_logged_rescue("on_close",Log::DEBUG) do
|
138
|
+
@ssl_connection.close if(@ssl_connection)
|
139
|
+
end
|
140
|
+
@ssl_connection=nil
|
141
|
+
end
|
142
|
+
|
143
|
+
############################################################################
|
144
|
+
#
|
145
|
+
#
|
146
|
+
#
|
147
|
+
############################################################################
|
148
|
+
|
149
|
+
def on_msg(msg)
|
150
|
+
# puts msg.inspect
|
151
|
+
end
|
152
|
+
|
153
|
+
############################################################################
|
154
|
+
#
|
155
|
+
#
|
156
|
+
#
|
157
|
+
############################################################################
|
158
|
+
|
159
|
+
############################################################################
|
160
|
+
#
|
161
|
+
#
|
162
|
+
#
|
163
|
+
############################################################################
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
############################################################################
|
2
|
+
#
|
3
|
+
# net_server.rb
|
4
|
+
#
|
5
|
+
# accept incoming TLS connections, parse and dispatch requests
|
6
|
+
#
|
7
|
+
############################################################################
|
8
|
+
|
9
|
+
require 'openssl'
|
10
|
+
require 'config'
|
11
|
+
require 'net_util'
|
12
|
+
require 'socket'
|
13
|
+
require 'net_server_client'
|
14
|
+
require 'thread'
|
15
|
+
require 'config_daemon'
|
16
|
+
|
17
|
+
module ProcessWanker
|
18
|
+
|
19
|
+
############################################################################
|
20
|
+
#
|
21
|
+
#
|
22
|
+
#
|
23
|
+
############################################################################
|
24
|
+
|
25
|
+
class TCPFilteredServer < TCPServer
|
26
|
+
|
27
|
+
include Log
|
28
|
+
|
29
|
+
def initialize(hostname,port,auth)
|
30
|
+
@auth=auth
|
31
|
+
super(hostname,port)
|
32
|
+
end
|
33
|
+
|
34
|
+
def accept()
|
35
|
+
while(true)
|
36
|
+
con=super()
|
37
|
+
debug("got TCP connection from #{con.peeraddr.inspect}")
|
38
|
+
return(con) if(validate_auth(con))
|
39
|
+
ProcessWanker::with_logged_rescue("accept - reject remote addr") do
|
40
|
+
con.close()
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def validate_auth(con)
|
46
|
+
|
47
|
+
remote_addr=con.peeraddr[3]
|
48
|
+
remote_addr=IPAddr.new(remote_addr)
|
49
|
+
|
50
|
+
if(!@auth.allow_ip(remote_addr))
|
51
|
+
info("reject ip #{remote_addr.inspect}")
|
52
|
+
return(false)
|
53
|
+
end
|
54
|
+
|
55
|
+
true
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
############################################################################
|
61
|
+
#
|
62
|
+
#
|
63
|
+
#
|
64
|
+
############################################################################
|
65
|
+
|
66
|
+
class NetServer
|
67
|
+
|
68
|
+
include Log
|
69
|
+
|
70
|
+
@@instance=nil
|
71
|
+
|
72
|
+
############################################################################
|
73
|
+
#
|
74
|
+
#
|
75
|
+
#
|
76
|
+
############################################################################
|
77
|
+
|
78
|
+
def initialize(cfg)
|
79
|
+
|
80
|
+
@@instance=self
|
81
|
+
@mutex=Mutex.new
|
82
|
+
@clients=[]
|
83
|
+
|
84
|
+
daemon=cfg.daemon
|
85
|
+
auth=daemon.get_auth
|
86
|
+
@auth=auth
|
87
|
+
|
88
|
+
# check that we're not using default certs and listening anything other than
|
89
|
+
# localhost.
|
90
|
+
if(@auth.is_default)
|
91
|
+
if(daemon.listen_hostname != ConfigDaemon::DEFAULT_LISTEN_HOSTNAME)
|
92
|
+
|
93
|
+
error "***"
|
94
|
+
error "*** For security reasons, I will only listen on #{ConfigDaemon::DEFAULT_LISTEN_HOSTNAME} while using"
|
95
|
+
error "*** the default built-in SSL certificates. You must generate real"
|
96
|
+
error "*** certificates if you wish to control this daemon remotely."
|
97
|
+
error "***"
|
98
|
+
|
99
|
+
daemon.listen_hostname=ConfigDaemon::DEFAULT_LISTEN_HOSTNAME
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
@ca_cert=auth.ca_cert
|
105
|
+
@context=OpenSSL::SSL::SSLContext.new
|
106
|
+
@context.cert=auth.my_cert
|
107
|
+
@context.key=auth.my_key
|
108
|
+
@context.verify_mode=OpenSSL::SSL::VERIFY_PEER
|
109
|
+
@context.verify_callback=proc do |preverify_ok,ssl_context|
|
110
|
+
verify_peer(preverify_ok,ssl_context)
|
111
|
+
end
|
112
|
+
|
113
|
+
# @tcp_server=TCPServer.new(daemon.listen_hostname,daemon.listen_port)
|
114
|
+
@tcp_server=TCPFilteredServer.new(daemon.listen_hostname,daemon.listen_port,auth)
|
115
|
+
@ssl_server=OpenSSL::SSL::SSLServer.new(@tcp_server,@context)
|
116
|
+
|
117
|
+
@server_thread=Thread.new { server_proc }
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
############################################################################
|
122
|
+
#
|
123
|
+
#
|
124
|
+
#
|
125
|
+
############################################################################
|
126
|
+
|
127
|
+
def stop_server()
|
128
|
+
@ssl_server.close
|
129
|
+
@server_thread.join
|
130
|
+
c=@clients.clone
|
131
|
+
c.each do |c|
|
132
|
+
c.disconnect()
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
############################################################################
|
137
|
+
#
|
138
|
+
#
|
139
|
+
#
|
140
|
+
############################################################################
|
141
|
+
|
142
|
+
def verify_peer(preverify_ok,ssl_context)
|
143
|
+
if(!ssl_context.current_cert.verify(@ca_cert.public_key))
|
144
|
+
info("client certificate rejected")
|
145
|
+
return(false)
|
146
|
+
end
|
147
|
+
peer_name=ssl_context.current_cert.subject.to_a.select { |x| x[0]=="CN" }.map { |x| x[1] }[0]
|
148
|
+
info("verified identity of #{peer_name}")
|
149
|
+
|
150
|
+
if(@auth.accept_peers && !@auth.accept_peers[peer_name])
|
151
|
+
info("failed to accept peer #{peer_name}")
|
152
|
+
return(false)
|
153
|
+
end
|
154
|
+
if(@auth.reject_peers && @auth.reject_peers[peer_name])
|
155
|
+
info("rejected peer #{peer_name}")
|
156
|
+
return(false)
|
157
|
+
end
|
158
|
+
|
159
|
+
true
|
160
|
+
end
|
161
|
+
|
162
|
+
############################################################################
|
163
|
+
#
|
164
|
+
#
|
165
|
+
#
|
166
|
+
############################################################################
|
167
|
+
|
168
|
+
def server_proc
|
169
|
+
|
170
|
+
while(true)
|
171
|
+
begin
|
172
|
+
ssl_connection=@ssl_server.accept
|
173
|
+
rescue OpenSSL::SSL::SSLError => e
|
174
|
+
next
|
175
|
+
rescue Errno::EBADF
|
176
|
+
break
|
177
|
+
end
|
178
|
+
|
179
|
+
@mutex.synchronize do
|
180
|
+
nc=NetServerClient.new(ssl_connection,self)
|
181
|
+
info("new connection from #{nc.user}")
|
182
|
+
@clients << nc
|
183
|
+
end
|
184
|
+
end
|
185
|
+
info("server stopped")
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
############################################################################
|
190
|
+
#
|
191
|
+
#
|
192
|
+
#
|
193
|
+
############################################################################
|
194
|
+
|
195
|
+
def client_closed(client)
|
196
|
+
@mutex.synchronize do
|
197
|
+
@clients.delete(client)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
############################################################################
|
202
|
+
#
|
203
|
+
#
|
204
|
+
#
|
205
|
+
############################################################################
|
206
|
+
|
207
|
+
def post_fork()
|
208
|
+
c=nil
|
209
|
+
@mutex.synchronize do
|
210
|
+
c=@clients.clone
|
211
|
+
end
|
212
|
+
c.each do |client|
|
213
|
+
client.close_rudely()
|
214
|
+
end
|
215
|
+
ProcessWanker::with_logged_rescue("post_fork - stop_server") do
|
216
|
+
stop_server()
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
############################################################################
|
221
|
+
#
|
222
|
+
#
|
223
|
+
#
|
224
|
+
############################################################################
|
225
|
+
|
226
|
+
def self.instance
|
227
|
+
@@instance
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
############################################################################
|
2
|
+
#
|
3
|
+
# net_server_client.rb
|
4
|
+
#
|
5
|
+
# server's view of a client connection
|
6
|
+
#
|
7
|
+
############################################################################
|
8
|
+
|
9
|
+
require 'openssl'
|
10
|
+
require 'config'
|
11
|
+
require 'net_util'
|
12
|
+
require 'socket'
|
13
|
+
require 'net_connection'
|
14
|
+
require 'thread'
|
15
|
+
|
16
|
+
module ProcessWanker
|
17
|
+
|
18
|
+
############################################################################
|
19
|
+
#
|
20
|
+
#
|
21
|
+
#
|
22
|
+
############################################################################
|
23
|
+
|
24
|
+
class NetServerClient < NetConnection
|
25
|
+
|
26
|
+
############################################################################
|
27
|
+
#
|
28
|
+
#
|
29
|
+
#
|
30
|
+
############################################################################
|
31
|
+
|
32
|
+
def initialize(ssl_connection,server)
|
33
|
+
@server=server
|
34
|
+
super(ssl_connection)
|
35
|
+
end
|
36
|
+
|
37
|
+
############################################################################
|
38
|
+
#
|
39
|
+
#
|
40
|
+
#
|
41
|
+
############################################################################
|
42
|
+
|
43
|
+
def on_msg(msg)
|
44
|
+
super(msg)
|
45
|
+
ProcessWanker::with_logged_rescue("NetServerClient::on_msg") do
|
46
|
+
resp=NetApi::execute(msg,self)
|
47
|
+
if(resp)
|
48
|
+
debug("send resp #{resp.inspect}")
|
49
|
+
resp[:done]=true
|
50
|
+
send_msg(resp)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
############################################################################
|
56
|
+
#
|
57
|
+
#
|
58
|
+
#
|
59
|
+
############################################################################
|
60
|
+
|
61
|
+
def inform(msg)
|
62
|
+
send_msg( { :info => msg } )
|
63
|
+
end
|
64
|
+
|
65
|
+
############################################################################
|
66
|
+
#
|
67
|
+
#
|
68
|
+
#
|
69
|
+
############################################################################
|
70
|
+
|
71
|
+
def on_close()
|
72
|
+
super()
|
73
|
+
@server.client_closed(self)
|
74
|
+
end
|
75
|
+
|
76
|
+
############################################################################
|
77
|
+
#
|
78
|
+
#
|
79
|
+
#
|
80
|
+
############################################################################
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
data/lib/net/net_util.rb
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
############################################################################
|
2
|
+
#
|
3
|
+
# net_util.rb
|
4
|
+
#
|
5
|
+
# handles the physical TCP/SSL connection between client(s) and daemon(s)
|
6
|
+
#
|
7
|
+
############################################################################
|
8
|
+
|
9
|
+
require 'openssl'
|
10
|
+
require 'fileutils'
|
11
|
+
|
12
|
+
module ProcessWanker
|
13
|
+
|
14
|
+
############################################################################
|
15
|
+
#
|
16
|
+
#
|
17
|
+
#
|
18
|
+
############################################################################
|
19
|
+
|
20
|
+
module NetUtil
|
21
|
+
|
22
|
+
DEFAULT_PORT = 45231
|
23
|
+
|
24
|
+
############################################################################
|
25
|
+
#
|
26
|
+
#
|
27
|
+
#
|
28
|
+
############################################################################
|
29
|
+
|
30
|
+
def make_filename(prefix,type)
|
31
|
+
ext={ :key => "key", :cert => "crt" }[type]
|
32
|
+
"#{prefix}.#{ext}"
|
33
|
+
end
|
34
|
+
module_function :make_filename
|
35
|
+
|
36
|
+
############################################################################
|
37
|
+
#
|
38
|
+
# generate_ca
|
39
|
+
#
|
40
|
+
# create a new CA certificate and private key
|
41
|
+
#
|
42
|
+
############################################################################
|
43
|
+
|
44
|
+
def generate_ca(prefix,passphrase=nil)
|
45
|
+
|
46
|
+
outdir=File.expand_path(File.dirname("#{prefix}a.b"))
|
47
|
+
FileUtils.mkdir_p(outdir)
|
48
|
+
|
49
|
+
#
|
50
|
+
# write key file
|
51
|
+
#
|
52
|
+
|
53
|
+
puts "generating CA key..."
|
54
|
+
key = OpenSSL::PKey::RSA.new(2048)
|
55
|
+
cipher = OpenSSL::Cipher::Cipher.new('AES-128-CBC')
|
56
|
+
exp = passphrase ? key.export(cipher,passphrase) : key.export
|
57
|
+
puts "saving CA key..."
|
58
|
+
File.open(make_filename(prefix,:key),"w") do |f|
|
59
|
+
f.write(exp)
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# generate certificate
|
64
|
+
#
|
65
|
+
|
66
|
+
puts "generating CA cert..."
|
67
|
+
ca_name = OpenSSL::X509::Name.parse('CN=ca')
|
68
|
+
ca_cert = OpenSSL::X509::Certificate.new
|
69
|
+
ca_cert.serial = 0
|
70
|
+
ca_cert.version = 2
|
71
|
+
ca_cert.not_before = Time.at(0)
|
72
|
+
ca_cert.not_after = Time.at(0x7fffffff)
|
73
|
+
ca_cert.public_key = key.public_key
|
74
|
+
ca_cert.subject = ca_name
|
75
|
+
ca_cert.issuer = ca_name
|
76
|
+
|
77
|
+
extension_factory = OpenSSL::X509::ExtensionFactory.new
|
78
|
+
extension_factory.subject_certificate = ca_cert
|
79
|
+
extension_factory.issuer_certificate = ca_cert
|
80
|
+
|
81
|
+
extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
|
82
|
+
extension_factory.create_extension 'basicConstraints', 'CA:TRUE', true
|
83
|
+
extension_factory.create_extension 'keyUsage', 'cRLSign,keyCertSign', true
|
84
|
+
|
85
|
+
puts "signing CA cert..."
|
86
|
+
ca_cert.sign(key, OpenSSL::Digest::SHA1.new)
|
87
|
+
|
88
|
+
puts "saving CA cert..."
|
89
|
+
File.open(make_filename(prefix,:cert),"w") do |f|
|
90
|
+
f.write(ca_cert.to_pem)
|
91
|
+
end
|
92
|
+
|
93
|
+
puts "wrote #{make_filename(prefix,:key)} and #{make_filename(prefix,:cert)}"
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
module_function :generate_ca
|
98
|
+
|
99
|
+
############################################################################
|
100
|
+
#
|
101
|
+
#
|
102
|
+
#
|
103
|
+
############################################################################
|
104
|
+
|
105
|
+
def generate_cert(ca_prefix,cert_prefix,name,passphrase=nil)
|
106
|
+
|
107
|
+
outdir=File.expand_path(File.dirname("#{cert_prefix}a.b"))
|
108
|
+
FileUtils.mkdir_p(outdir)
|
109
|
+
|
110
|
+
#
|
111
|
+
# load ca key and cert
|
112
|
+
#
|
113
|
+
|
114
|
+
puts "loading CA key and cert..."
|
115
|
+
ca_key=OpenSSL::PKey::RSA.new( File.read(make_filename(ca_prefix,:key)) )
|
116
|
+
ca_cert=OpenSSL::X509::Certificate.new( File.read(make_filename(ca_prefix,:cert)) )
|
117
|
+
|
118
|
+
#
|
119
|
+
# write key file
|
120
|
+
#
|
121
|
+
|
122
|
+
puts "generating key for #{name}..."
|
123
|
+
key = OpenSSL::PKey::RSA.new(2048)
|
124
|
+
cipher = OpenSSL::Cipher::Cipher.new('AES-128-CBC')
|
125
|
+
exp = passphrase ? key.export(cipher,passphrase) : key.export
|
126
|
+
puts "saving key for #{name}..."
|
127
|
+
File.open(make_filename(cert_prefix,:key),"w") do |f|
|
128
|
+
f.write(exp)
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# generate CSR
|
133
|
+
#
|
134
|
+
|
135
|
+
puts "generating CSR for #{name}..."
|
136
|
+
csr = OpenSSL::X509::Request.new
|
137
|
+
csr.version = 0
|
138
|
+
csr.subject = OpenSSL::X509::Name.parse("CN=#{name}")
|
139
|
+
csr.public_key = key.public_key
|
140
|
+
csr.sign(key,OpenSSL::Digest::SHA1.new)
|
141
|
+
|
142
|
+
#
|
143
|
+
# create certificate
|
144
|
+
#
|
145
|
+
|
146
|
+
puts "creating cert for #{name}..."
|
147
|
+
csr_cert = OpenSSL::X509::Certificate.new
|
148
|
+
csr_cert.serial = 0
|
149
|
+
csr_cert.version = 2
|
150
|
+
csr_cert.not_before = Time.at(0)
|
151
|
+
csr_cert.not_after = Time.at(0x7fffffff)
|
152
|
+
|
153
|
+
csr_cert.subject = csr.subject
|
154
|
+
csr_cert.public_key = csr.public_key
|
155
|
+
csr_cert.issuer = ca_cert.subject
|
156
|
+
|
157
|
+
extension_factory = OpenSSL::X509::ExtensionFactory.new
|
158
|
+
extension_factory.subject_certificate = csr_cert
|
159
|
+
extension_factory.issuer_certificate = ca_cert
|
160
|
+
|
161
|
+
extension_factory.create_extension 'basicConstraints', 'CA:FALSE'
|
162
|
+
extension_factory.create_extension 'keyUsage','keyEncipherment,dataEncipherment,digitalSignature'
|
163
|
+
extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
|
164
|
+
|
165
|
+
puts "signing cert for #{name}..."
|
166
|
+
csr_cert.sign(ca_key,OpenSSL::Digest::SHA1.new)
|
167
|
+
|
168
|
+
#
|
169
|
+
# save it
|
170
|
+
#
|
171
|
+
|
172
|
+
puts "saving cert for #{name}..."
|
173
|
+
File.open(make_filename(cert_prefix,:cert),"w") do |f|
|
174
|
+
f.write(csr_cert.to_pem)
|
175
|
+
end
|
176
|
+
|
177
|
+
puts "wrote #{make_filename(cert_prefix,:key)} and #{make_filename(cert_prefix,:cert)}"
|
178
|
+
|
179
|
+
end
|
180
|
+
module_function :generate_cert
|
181
|
+
|
182
|
+
############################################################################
|
183
|
+
#
|
184
|
+
#
|
185
|
+
#
|
186
|
+
############################################################################
|
187
|
+
|
188
|
+
def post_fork()
|
189
|
+
|
190
|
+
if(NetServer.instance())
|
191
|
+
NetServer.instance().post_fork()
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
module_function :post_fork
|
196
|
+
|
197
|
+
############################################################################
|
198
|
+
#
|
199
|
+
#
|
200
|
+
#
|
201
|
+
############################################################################
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|