diff -r d8fb90a2e11f -r 523559fe6352 connectors/PYRO/PSK_Adapter.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/connectors/PYRO/PSK_Adapter.py Thu Oct 18 18:37:01 2018 +0200 @@ -0,0 +1,83 @@ +from __future__ import absolute_import +from __future__ import print_function + +import socket +import re +import sslpsk +import Pyro +from Pyro.core import PyroURI +from Pyro.protocol import _connect_socket,TCPConnection,PYROAdapter +from Pyro.errors import ConnectionDeniedError, ProtocolError +from Pyro.util import Log + +# +# The TLS-PSK adapter that handles SSL connections instead of regular sockets, +# but using Pre Shared Keys instead of Certificates +# +class PYROPSKAdapter(PYROAdapter): + # This is essentialy the same as in Pyro/protocol.py + # only raw_sock wrapping into sock through sslpsk.wrap_socket was added + # Pyro unfortunately doesn't allow cleaner customization + def bindToURI(self,URI): + with self.lock: # only 1 thread at a time can bind the URI + try: + self.URI=URI + + # This are the statements that differ from Pyro/protocol.py + raw_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + _connect_socket(raw_sock, URI.address, URI.port, self.timeout) + sock = sslpsk.wrap_socket( + raw_sock, psk=Pyro.config.PYROPSK, server_side=False, + ciphers="PSK-AES256-GCM-SHA384:PSK-AES256-CBC-SHA") + # all the rest is the same as in Pyro/protocol.py + + conn=TCPConnection(sock, sock.getpeername()) + # receive the authentication challenge string, and use that to build the actual identification string. + try: + authChallenge=self.recvAuthChallenge(conn) + except ProtocolError,x: + # check if we were denied + if hasattr(x,"partialMsg") and x.partialMsg[:len(self.denyMSG)]==self.denyMSG: + raise ConnectionDeniedError(Pyro.constants.deniedReasons[int(x.partialMsg[-1])]) + else: + raise + # reply with our ident token, generated from the ident passphrase and the challenge + msg = self._sendConnect(sock,self.newConnValidator.createAuthToken(self.ident, authChallenge, conn.addr, self.URI, None) ) + if msg==self.acceptMSG: + self.conn=conn + self.conn.connected=1 + Log.msg('PYROAdapter','connected to',str(URI)) + if URI.protocol=='PYROLOCPSK': + self.resolvePYROLOC_URI("PYROPSK") # updates self.URI + elif msg[:len(self.denyMSG)]==self.denyMSG: + try: + raise ConnectionDeniedError(Pyro.constants.deniedReasons[int(msg[-1])]) + except (KeyError,ValueError): + raise ConnectionDeniedError('invalid response') + except socket.error: + Log.msg('PYROAdapter','connection failed to URI',str(URI)) + raise ProtocolError('connection failed') + +_getProtocolAdapter = Pyro.protocol.getProtocolAdapter +def getProtocolAdapter(protocol): + if protocol in ('PYROPSK', 'PYROLOCPSK'): + return PYROPSKAdapter() + _getProtocolAdapter(protocol) + +Pyro.protocol.getProtocolAdapter = getProtocolAdapter + +_processStringURI = Pyro.core.processStringURI +def processStringURI(URI): + x=re.match(r'(?PPYROLOCPSK)://(?P[^\s:]+):?(?P\d+)?/(?P\S*)',URI) + if x: + protocol=x.group('protocol') + hostname=x.group('hostname') + port=x.group('port') + if port: + port=int(port) + else: + port=0 + name=x.group('name') + return PyroURI(hostname,name,port,protocol) + return _processStringURI(URI) +Pyro.core.processStringURI = processStringURI