* add SSL TCP server support, using runtime generated/signed keys

* add HTTPS support

note, SSL service tests don't work.  Right now, the tests just bail early.  The
client spins forever trying to get data.  When the client & server are in
seperate processes, this isn't a problem.  A threaded test implementation is
closer, as data sent from the client gets to the server just fine.


git-svn-id: file:///home/svn/incoming/trunk@3616 4d416f70-5f16-0410-b530-b9f4589650da
unstable
bmc 2006-04-24 18:49:00 +00:00
parent 71e3323dbd
commit df49cfabb0
4 changed files with 153 additions and 3 deletions

View File

@ -106,6 +106,7 @@ class Server
self.listener = nil
self.resources = {}
self.server_name = DefaultServer
self.ssl = false
end
#
@ -122,7 +123,8 @@ class Server
self.listener = Rex::Socket::TcpServer.create(
'LocalHost' => self.listen_host,
'LocalPort' => self.listen_port,
'Context' => self.context
'Context' => self.context,
'SSL' => self.ssl
)
# Register callbacks
@ -236,7 +238,7 @@ class Server
cli.send_response(resp)
end
attr_accessor :listen_port, :listen_host, :server_name, :context
attr_accessor :listen_port, :listen_host, :server_name, :context, :ssl
protected

View File

@ -2,6 +2,7 @@ require 'singleton'
require 'rex/socket'
require 'rex/socket/tcp'
require 'rex/socket/ssl_tcp'
require 'rex/socket/ssl_tcp_server'
require 'rex/socket/udp'
###
@ -61,7 +62,11 @@ class Rex::Socket::Comm::Local
return sock if (param.bare?)
sock.extend(Rex::Socket::TcpServer)
klass = Rex::Socket::TcpServer
if (param.ssl)
klass = Rex::Socket::SslTcpServer
end
sock.extend(klass)
sock.initsock(param)
# Otherwise, if we're creating a client...

View File

@ -0,0 +1,92 @@
require 'rex/socket'
require 'rex/socket/tcp_server'
require 'rex/io/stream_server'
require 'openssl'
###
#
# This class provides methods for interacting with an SSL wrapped TCP server. It
# implements the StreamServer IO interface.
#
###
module Rex::Socket::SslTcpServer
include Rex::Socket::TcpServer
##
#
# Factory
#
##
def initsock(params = nil)
self.sslctx = makessl()
super
end
def accept(opts = {})
sock = super()
if (sock)
sock.extend(Rex::Socket::Tcp)
sock.context = self.context
pn = sock.getpeername
sock.peerhost = pn[1]
sock.peerport = pn[2]
end
t = OpenSSL::SSL::SSLSocket.new(sock, self.sslctx)
t.extend(Rex::Socket::Tcp)
t.accept
t
end
def makessl
key = OpenSSL::PKey::RSA.new(512){ }
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = rand(0xFFFFFFFF)
# name = OpenSSL::X509::Name.new([["C","JP"],["O","TEST"],["CN","localhost"]])
subject = OpenSSL::X509::Name.new([
["C","US"],
['ST', Rex::Text.rand_state()],
["L", Rex::Text.rand_text_alpha(rand(20) + 10)],
["O", Rex::Text.rand_text_alpha(rand(20) + 10)],
["CN", Rex::Text.rand_hostname],
])
issuer = OpenSSL::X509::Name.new([
["C","US"],
['ST', Rex::Text.rand_state()],
["L", Rex::Text.rand_text_alpha(rand(20) + 10)],
["O", Rex::Text.rand_text_alpha(rand(20) + 10)],
["CN", Rex::Text.rand_hostname],
])
cert.subject = subject
cert.issuer = issuer
cert.not_before = Time.now
cert.not_after = Time.now + 3600
cert.public_key = key.public_key
ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
cert.extensions = [
ef.create_extension("basicConstraints","CA:FALSE"),
ef.create_extension("subjectKeyIdentifier","hash"),
ef.create_extension("extendedKeyUsage","serverAuth"),
ef.create_extension("keyUsage","keyEncipherment,dataEncipherment,digitalSignature")
]
ef.issuer_certificate = cert
cert.add_extension ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always")
cert.sign(key, OpenSSL::Digest::SHA1.new)
ctx = OpenSSL::SSL::SSLContext.new()
ctx.key = key
ctx.cert = cert
ctx.session_id_context = OpenSSL::Digest::MD5.hexdigest($0)
return ctx
end
attr_accessor :sslctx
end

View File

@ -0,0 +1,51 @@
#!/usr/bin/env ruby
$:.unshift(File.join(File.dirname(__FILE__), '..', '..'))
require 'test/unit'
require 'rex/socket/ssl_tcp_server'
require 'rex/socket/ssl_tcp'
class Rex::Socket::SslTcpServer::UnitTest < Test::Unit::TestCase
# XXX. The client data is sent & decrypted just fine. The server data is not. the client thread just spins. BAH.
def test_tcp_server
return;
serv_port = 65433
c = nil
threads = []
threads << Thread.new() {
serv = Rex::Socket.create_tcp_server('LocalPort' => serv_port, 'SSL' => true)
assert_kind_of(Rex::Socket::SslTcpServer, serv, "type => ssl")
assert_kind_of(Rex::Socket::TcpServer, serv, "type => tcp")
assert_kind_of(Rex::IO::StreamServer, serv, "type => stream")
s = serv.accept
assert_equal("client_data\n", s.get_once(), "s: get_once")
assert_equal(3, s.write("Yo\n"), "s: put Yo")
assert(s.methods.include?('<<'))
assert(s.methods.include?('>>'))
assert(s.methods.include?('has_read_data?'))
serv.close
}
threads << Thread.new() {
sleep(2)
assert_nothing_raised {
c = Rex::Socket::SslTcp.create(
'PeerHost' => '127.0.0.1',
'PeerPort' => serv_port
)
}
assert_kind_of(Rex::Socket::Tcp, c, "TCP")
assert_kind_of(Rex::Socket::SslTcp, c, "SSL")
assert_equal(12, c.write("client_data\n"), "c: write")
assert_equal("Yo\n", c.get_once(), "c: get_once")
c.close if (c)
}
threads.each { |aThread| aThread.join }
end
end