I have a Server based on ThreadingTCPServer
. Now Ii want to add SSL Support to that Server.
Without SSL it works fine but with SSLv3 I cant connect a Client to the Server, it always throws an exception: Error 111 Connection Refused
. The error mens there's no SSL Server on that port.
I added the SSL Support based on an example I found here at Stackoverflow. Here's my code:
Server:
class BeastServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
SocketServer.BaseServer.__init__(self, server_address,
RequestHandlerClass)
ctx = SSL.Context(SSL.SSLv3_METHOD)
cert = 'server.pem'
key = 'key.pem'
ctx.use_privatekey_file(key)
ctx.use_certificate_file(cert)
self.socket = SSL.Connection(ctx, socket.socket(self.address_family,
self.socket_type))
if bind_and_activate:
#self.server_bind()
#self.server_a
Client:
class Client(object) :
def verbinden (self, ip_) :
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED,
ssl_version=ssl.PROTOCOL_SSLv3, ca_certs='server.pem')
ssl_sock.connect((ip_, 10012))
return ssl_sock
The key and certificate file is created using open SSL. I hope somebody can tell me what the problem is.
thanks for your help
best regards patrick
Only use the standard library
Server side :
from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandler
import ssl
class MySSL_TCPServer(TCPServer):
def __init__(self,
server_address,
RequestHandlerClass,
certfile,
keyfile,
ssl_version=ssl.PROTOCOL_TLSv1,
bind_and_activate=True):
TCPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate)
self.certfile = certfile
self.keyfile = keyfile
self.ssl_version = ssl_version
def get_request(self):
newsocket, fromaddr = self.socket.accept()
connstream = ssl.wrap_socket(newsocket,
server_side=True,
certfile = self.certfile,
keyfile = self.keyfile,
ssl_version = self.ssl_version)
return connstream, fromaddr
class MySSL_ThreadingTCPServer(ThreadingMixIn, MySSL_TCPServer): pass
class testHandler(StreamRequestHandler):
def handle(self):
data = self.connection.recv(4096)
self.wfile.write(data)
#test code
MySSL_ThreadingTCPServer(('127.0.0.1',5151),testHandler,"cert.pem","key.pem").serve_forever()
Client side :
import os
import socket, ssl
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket(s,
ca_certs="cert.pem",
cert_reqs=ssl.CERT_REQUIRED,
ssl_version=ssl.PROTOCOL_TLSv1)
ssl_sock.connect(('127.0.0.1',5151))
ssl_sock.send('hello ~MySSL !')
print ssl_sock.recv(4096)
ssl_sock.close()
works well
In fact ssl from the standard library works ok, maybe the problem with the initial code was that you were not asking the base class not to bind and activate. See below working example based on TCPServer. Certificate and Key files are expected to be in the same directory.
import os
import SocketServer
class SSLTCPServer(SocketServer.TCPServer):
def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
"""Constructor. May be extended, do not override."""
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass, False)
dir = os.path.dirname(__file__)
key_file = os.path.join(dir, 'server.key')
cert_file = os.path.join(dir, 'server.crt')
import ssl
self.socket = ssl.wrap_socket(self.socket, keyfile=key_file, certfile=cert_file, cert_reqs=ssl.CERT_NONE)
if bind_and_activate:
self.server_bind()
self.server_activate()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With