Adding SSL Support to SocketServer

后端 未结 3 2100
臣服心动
臣服心动 2020-12-16 06:58

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

相关标签:
3条回答
  • 2020-12-16 07:24

    install openssl

    sudo aptitude install python-openssl

    from OpenSSL import SSL
    import socket, SocketServer
    
    class SSlSocketServer(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 = 'cert.pem'
            key = 'private_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_activate()
        def shutdown_request(self,request):
            request.shutdown()
    
    class Decoder(SocketServer.StreamRequestHandler):
        def setup(self):
            self.connection = self.request
            self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
            self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
    
        def handle(self):
            try:
                socket1 = self.connection
                str1 = socket1.recv(4096)
                print str1
            except Exception, e:
                print 'socket error',e
    def main():
        server = SSlSocketServer(('127.0.0.1', 9999), Decoder)
        server.serve_forever()
    if __name__ == '__main__':
        main()
    

    now test server

    import socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('localhost', 9999))
    sslSocket = socket.ssl(s)
    print repr(sslSocket.server())
    print repr(sslSocket.issuer())
    sslSocket.write('Hello secure socket\n')
    s.close()
    
    0 讨论(0)
  • 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()
    
    0 讨论(0)
  • 2020-12-16 07:34

    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

    0 讨论(0)
提交回复
热议问题