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 |