2010-09-16 10 views
10

Je souhaite envoyer des données d'un client au serveur dans un socket TCP TLS à partir de plusieurs sous-processus clients afin que je partage le même socket ssl avec tous les sous-processus. La communication fonctionne avec un sous-processus, mais si j'utilise plus d'un sous-processus, le serveur TLS se bloque avec un ssl.SSLError (SSL3_GET_RECORD: décryptage échoué ou mauvais enregistrement mac).Problème ssl Python avec multitraitement

Plus spécifique: Il ne dépend pas du processus qui appelle d'abord la méthode SSLSocket.write(), mais ce processus est le seul à ce jour sur lequel il peut s'appeler. Si un autre processus appelle write(), le serveur entraînera l'exception décrite ci-dessus.

J'ai utilisé ce code de base:

tlsserver.py

import socket, ssl 

def deal_with_client(connstream): 
    data = connstream.read() 
    while data: 
     print data 
     data = connstream.read() 
    connstream.close() 

bindsocket = socket.socket() 
bindsocket.bind(('127.0.0.1', 9998)) 
bindsocket.listen(5) 

while True: 
    newsocket, fromaddr = bindsocket.accept() 
    connstream = ssl.wrap_socket(newsocket, 
           server_side=True, 
           certfile="srv.crt", 
           keyfile="srv.key", 
           ssl_version=ssl.PROTOCOL_TLSv1) 
    deal_with_client(connstream) 

tlsclient.py

import socket, ssl 
import multiprocessing 

class SubProc: 
    def __init__(self, sock): 
     self.sock = sock 

    def do(self): 
     self.sock.write("Test") 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

ssl_sock = ssl.wrap_socket(s) 
ssl_sock.connect(('127.0.0.1', 9998)) 

print "Connected to", repr(ssl_sock.getpeername()) 

for x in (1,2): 
    subproc = SubProc(ssl_sock) 
    proc = multiprocessing.Process(target=subproc.do) 

Et c'est le backtrace:

Traceback (most recent call last): 
    File "tlsserver.py", line 21, in <module> 
    deal_with_client(connstream) 
    File "tlsserver.py", line 7, in deal_with_client 
    data = connstream.read() 
    File "/usr/lib64/python2.6/ssl.py", line 136, in read 
    return self._sslobj.read(len) 
ssl.SSLError: [Errno 1] _ssl.c:1325: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac 

Répondre

17

Le problème est que vous réutilisez la même connexion pour les deux processus. La façon dont le chiffrement SSL des données fait échouer ce processus - les deux processus doivent communiquer entre eux sur l'état de la connexion SSL partagée. Même si vous le faites fonctionner, ou si vous n'utilisez pas le protocole SSL, les données arriveront au serveur toutes mélangées; vous n'auriez pas de véritable moyen de distinguer les octets de quel processus.

Ce que vous devez faire est de donner à chaque processus sa propre connexion SSL, en établissant la connexion au subproc.do. Sinon, les sous-processus ne communiquent pas du tout avec le serveur, mais communiquent plutôt avec le processus principal, et le processus principal le relaie via la connexion SSL.

+0

Merci pour l'information! J'avais peur que ce soit le problème. Je pense que je le ferai pour un processus qui ne fait que la communication SSL et tous les autres processus vont communiquer avec celui-ci via des tuyaux. Est-ce que cela semble raisonnable? –

+1

Seriez-vous si gentil et pouvez-vous expliquer pourquoi même un verrou ne résout pas ce problème? –

+1

J'avais des problèmes similaires avec l'utilisation de SSL et multiprocessing.Process. J'ai trouvé que passer à l'aide de multithreading.Thread suffisamment travaillé autour de ce problème. Je ne peux pas trouver exactement ce que j'ai lu qui m'a conduit à suivre ce chemin, mais je crois que c'est à cause de la façon dont la bibliothèque openssl utilise les informations de processus pour faire quelque chose avec le/décryptage sur le socket raw. Et quand ce socket est créé sur un processus, puis passé à un autre processus, quelque chose ne va pas. Créer dans un fil et passer à un autre fil semble être très bien – danielpops