1require "socket"
2require "thread"
3require "openssl"
4require File.join(File.dirname(__FILE__), "utils.rb")
5
6def get_pem(io=$stdin)
7  buf = ""
8  while line = io.gets
9    if /^-----BEGIN / =~ line
10      buf << line
11      break
12    end
13  end
14  while line = io.gets
15    buf << line
16    if /^-----END / =~ line
17      break
18    end
19  end
20  return buf
21end
22
23def make_key(pem)
24  begin
25    return OpenSSL::PKey::RSA.new(pem)
26  rescue
27    return OpenSSL::PKey::DSA.new(pem)
28  end
29end
30
31ca_cert  = OpenSSL::X509::Certificate.new(get_pem)
32ssl_cert = OpenSSL::X509::Certificate.new(get_pem)
33ssl_key  = make_key(get_pem)
34port = Integer(ARGV.shift)
35verify_mode = Integer(ARGV.shift)
36start_immediately = (/yes/ =~ ARGV.shift)
37
38store = OpenSSL::X509::Store.new
39store.add_cert(ca_cert)
40store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
41ctx = OpenSSL::SSL::SSLContext.new
42ctx.cert_store = store
43#ctx.extra_chain_cert = [ ca_cert ]
44ctx.cert = ssl_cert
45ctx.key = ssl_key
46ctx.verify_mode = verify_mode
47
48Socket.do_not_reverse_lookup = true
49tcps = nil
50100.times{|i|
51  begin
52    tcps = TCPServer.new("0.0.0.0", port+i)
53    port = port + i
54    break
55  rescue Errno::EADDRINUSE
56    next
57  end
58}
59ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
60ssls.start_immediately = start_immediately
61
62$stdout.sync = true
63$stdout.puts Process.pid
64$stdout.puts port
65
66loop do
67  ssl = ssls.accept rescue next
68  Thread.start{
69    q = Queue.new
70    th = Thread.start{ ssl.write(q.shift) while true }
71    while line = ssl.gets
72      if line =~ /^STARTTLS$/
73        ssl.accept
74        next
75      end
76      q.push(line)
77    end
78    th.kill if q.empty?
79    ssl.close
80  }
81end
82