connectors/PYRO/PSK_Adapter.py
changeset 2492 7dd551ac2fa0
parent 2325 71593d3f880b
child 2536 2747d6e72eb8
equal deleted inserted replaced
2491:362039519454 2492:7dd551ac2fa0
     5 import re
     5 import re
     6 import sslpsk
     6 import sslpsk
     7 import ssl
     7 import ssl
     8 import Pyro
     8 import Pyro
     9 from Pyro.core import PyroURI
     9 from Pyro.core import PyroURI
    10 from Pyro.protocol import _connect_socket,TCPConnection,PYROAdapter
    10 from Pyro.protocol import _connect_socket, TCPConnection, PYROAdapter
    11 from Pyro.errors import ConnectionDeniedError, ProtocolError
    11 from Pyro.errors import ConnectionDeniedError, ProtocolError
    12 from Pyro.util import Log
    12 from Pyro.util import Log
    13 
    13 
    14 #
    14 
    15 # The TLS-PSK adapter that handles SSL connections instead of regular sockets,
    15 # The TLS-PSK adapter that handles SSL connections instead of regular sockets,
    16 # but using Pre Shared Keys instead of Certificates
    16 # but using Pre Shared Keys instead of Certificates
    17 #
    17 #
    18 class PYROPSKAdapter(PYROAdapter):
    18 class PYROPSKAdapter(PYROAdapter):
    19     # This is essentialy the same as in Pyro/protocol.py
    19     # This is essentialy the same as in Pyro/protocol.py
    20     # only raw_sock wrapping into sock through sslpsk.wrap_socket was added
    20     # only raw_sock wrapping into sock through sslpsk.wrap_socket was added
    21     # Pyro unfortunately doesn't allow cleaner customization
    21     # Pyro unfortunately doesn't allow cleaner customization
    22     def bindToURI(self,URI):
    22     def bindToURI(self, URI):
    23         with self.lock:   # only 1 thread at a time can bind the URI
    23         with self.lock:   # only 1 thread at a time can bind the URI
    24             try:
    24             try:
    25                 self.URI=URI
    25                 self.URI = URI
    26 
    26 
    27                 # This are the statements that differ from Pyro/protocol.py
    27                 # This are the statements that differ from Pyro/protocol.py
    28                 raw_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    28                 raw_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    29                 _connect_socket(raw_sock, URI.address, URI.port, self.timeout)
    29                 _connect_socket(raw_sock, URI.address, URI.port, self.timeout)
    30                 sock = sslpsk.wrap_socket(
    30                 sock = sslpsk.wrap_socket(
    31                     raw_sock, psk=Pyro.config.PYROPSK, server_side=False,
    31                     raw_sock, psk=Pyro.config.PYROPSK, server_side=False,
    32                     ciphers="PSK-AES256-CBC-SHA", # available in openssl 1.0.2 
    32                     ciphers="PSK-AES256-CBC-SHA",  # available in openssl 1.0.2
    33                     ssl_version=ssl.PROTOCOL_TLSv1)
    33                     ssl_version=ssl.PROTOCOL_TLSv1)
    34                 # all the rest is the same as in Pyro/protocol.py 
    34                 # all the rest is the same as in Pyro/protocol.py
    35 
    35 
    36                 conn=TCPConnection(sock, sock.getpeername())
    36                 conn = TCPConnection(sock, sock.getpeername())
    37                 # receive the authentication challenge string, and use that to build the actual identification string.
    37                 # receive the authentication challenge string, and use that to build the actual identification string.
    38                 try:
    38                 try:
    39                     authChallenge=self.recvAuthChallenge(conn)
    39                     authChallenge = self.recvAuthChallenge(conn)
    40                 except ProtocolError,x:
    40                 except ProtocolError, x:
    41                     # check if we were denied
    41                     # check if we were denied
    42                     if hasattr(x,"partialMsg") and x.partialMsg[:len(self.denyMSG)]==self.denyMSG:
    42                     if hasattr(x, "partialMsg") and x.partialMsg[:len(self.denyMSG)] == self.denyMSG:
    43                         raise ConnectionDeniedError(Pyro.constants.deniedReasons[int(x.partialMsg[-1])])
    43                         raise ConnectionDeniedError(Pyro.constants.deniedReasons[int(x.partialMsg[-1])])
    44                     else:
    44                     else:
    45                         raise
    45                         raise
    46                 # reply with our ident token, generated from the ident passphrase and the challenge
    46                 # reply with our ident token, generated from the ident passphrase and the challenge
    47                 msg = self._sendConnect(sock,self.newConnValidator.createAuthToken(self.ident, authChallenge, conn.addr, self.URI, None) )
    47                 msg = self._sendConnect(sock, self.newConnValidator.createAuthToken(self.ident, authChallenge, conn.addr, self.URI, None))
    48                 if msg==self.acceptMSG:
    48                 if msg == self.acceptMSG:
    49                     self.conn=conn
    49                     self.conn = conn
    50                     self.conn.connected=1
    50                     self.conn.connected = 1
    51                     Log.msg('PYROAdapter','connected to',str(URI))
    51                     Log.msg('PYROAdapter', 'connected to', str(URI))
    52                     if URI.protocol=='PYROLOCPSK':
    52                     if URI.protocol == 'PYROLOCPSK':
    53                         self.resolvePYROLOC_URI("PYROPSK") # updates self.URI
    53                         self.resolvePYROLOC_URI("PYROPSK")  # updates self.URI
    54                 elif msg[:len(self.denyMSG)]==self.denyMSG:
    54                 elif msg[:len(self.denyMSG)] == self.denyMSG:
    55                     try:
    55                     try:
    56                         raise ConnectionDeniedError(Pyro.constants.deniedReasons[int(msg[-1])])
    56                         raise ConnectionDeniedError(Pyro.constants.deniedReasons[int(msg[-1])])
    57                     except (KeyError,ValueError):
    57                     except (KeyError, ValueError):
    58                         raise ConnectionDeniedError('invalid response')
    58                         raise ConnectionDeniedError('invalid response')
    59             except socket.error:
    59             except socket.error:
    60                 Log.msg('PYROAdapter','connection failed to URI',str(URI))
    60                 Log.msg('PYROAdapter', 'connection failed to URI', str(URI))
    61                 raise ProtocolError('connection failed')
    61                 raise ProtocolError('connection failed')
    62 
    62 
       
    63 
    63 _getProtocolAdapter = Pyro.protocol.getProtocolAdapter
    64 _getProtocolAdapter = Pyro.protocol.getProtocolAdapter
       
    65 
       
    66 
    64 def getProtocolAdapter(protocol):
    67 def getProtocolAdapter(protocol):
    65     if protocol in ('PYROPSK', 'PYROLOCPSK'):
    68     if protocol in ('PYROPSK', 'PYROLOCPSK'):
    66         return PYROPSKAdapter()
    69         return PYROPSKAdapter()
    67     return _getProtocolAdapter(protocol)
    70     return _getProtocolAdapter(protocol)
    68 
    71 
       
    72 
    69 Pyro.protocol.getProtocolAdapter = getProtocolAdapter
    73 Pyro.protocol.getProtocolAdapter = getProtocolAdapter
    70 
    74 
       
    75 
    71 _processStringURI = Pyro.core.processStringURI
    76 _processStringURI = Pyro.core.processStringURI
       
    77 
       
    78 
    72 def processStringURI(URI):
    79 def processStringURI(URI):
    73     x=re.match(r'(?P<protocol>PYROLOCPSK)://(?P<hostname>[^\s:]+):?(?P<port>\d+)?/(?P<name>\S*)',URI)
    80     x = re.match(r'(?P<protocol>PYROLOCPSK)://(?P<hostname>[^\s:]+):?(?P<port>\d+)?/(?P<name>\S*)', URI)
    74     if x:
    81     if x:
    75         protocol=x.group('protocol')
    82         protocol = x.group('protocol')
    76         hostname=x.group('hostname')
    83         hostname = x.group('hostname')
    77         port=x.group('port')
    84         port = x.group('port')
    78         if port:
    85         if port:
    79             port=int(port)
    86             port = int(port)
    80         else:
    87         else:
    81             port=0
    88             port = 0
    82         name=x.group('name')
    89         name = x.group('name')
    83         return PyroURI(hostname,name,port,protocol)
    90         return PyroURI(hostname, name, port, protocol)
    84     return _processStringURI(URI)
    91     return _processStringURI(URI)
       
    92 
       
    93 
    85 Pyro.core.processStringURI = processStringURI
    94 Pyro.core.processStringURI = processStringURI