Добавление поддержки SSL в SocketServer - PullRequest
4 голосов
/ 21 декабря 2011

У меня есть сервер на основе ThreadingTCPServer.Теперь я хочу добавить поддержку SSL на этот сервер.Без SSL он работает нормально, но с SSLv3 я не могу подключить клиента к серверу, он всегда выдает исключение: Error 111 Connection Refused.Ошибка в том, что на этом порту нет SSL-сервера.

Я добавил поддержку SSL на основе примера, найденного здесь, в Stackoverflow.Вот мой код:

Сервер:

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

Клиент:

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

Файл ключа и сертификата создается с использованием открытого SSL.Я надеюсь, что кто-то может сказать мне, в чем проблема.

спасибо за вашу помощь

С наилучшими пожеланиями, Патрик

Ответы [ 3 ]

10 голосов
/ 06 ноября 2013

Используйте только стандартную библиотеку

На стороне сервера:

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()

На стороне клиента:

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()

хорошо работает

3 голосов
/ 06 июля 2013

На самом деле ssl из стандартной библиотеки работает нормально, возможно, проблема с исходным кодом заключалась в том, что вы не просили базовый класс не связывать и не активировать.Ниже приведен рабочий пример на основе TCPServer.Ожидается, что файлы сертификатов и ключей находятся в одном каталоге.

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()
1 голос
/ 21 апреля 2012

установить openssl

sudo aptitude установить 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()

теперь тестовый сервер

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()
...