Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dev.gajim.org/gajim/python-nbxmpp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Hörist <philipp@hoerist.com>2023-11-07 00:19:58 +0300
committerPhilipp Hörist <philipp@hoerist.com>2023-11-07 00:19:58 +0300
commit24d5889a333503e02bf4a0614ea9d823c25bc129 (patch)
tree9fa6b5ade1dc97205828c545aa79bdbc314cdca3
parentb679ed792d9b3df7bc68521953104fffa08e7d06 (diff)
new: Websocket: Implement channel binding
-rw-r--r--nbxmpp/connection.py16
-rw-r--r--nbxmpp/tcp.py39
-rw-r--r--nbxmpp/websocket.py12
3 files changed, 35 insertions, 32 deletions
diff --git a/nbxmpp/connection.py b/nbxmpp/connection.py
index e4f1d82..5a72c22 100644
--- a/nbxmpp/connection.py
+++ b/nbxmpp/connection.py
@@ -59,6 +59,7 @@ class Connection(Observable):
self._state = None
self._state = TCPState.DISCONNECTED
+ self._tls_con: Optional[Gio.TlsConnection] = None
self._peer_certificate = None
self._peer_certificate_errors = None
@@ -71,14 +72,24 @@ class Connection(Observable):
return None
@property
- def ciphersuite(self) -> Optional[int]:
+ def ciphersuite(self) -> Optional[str]:
return None
def get_channel_binding_data(
self,
type_: Gio.TlsChannelBindingType # pylint: disable=unused-argument
) -> Optional[bytes]:
- return None
+ assert self._tls_con is not None
+
+ try:
+ success, data = self._tls_con.get_channel_binding_data(type_)
+ except Exception as error:
+ self._log.warning('Unable to get channel binding data: %s', error)
+ return None
+
+ if not success:
+ return None
+ return data
@property
def local_address(self):
@@ -160,3 +171,4 @@ class Connection(Observable):
self._peer_certificate = None
self._client_cert = None
self._address = None
+ self._tls_con = None
diff --git a/nbxmpp/tcp.py b/nbxmpp/tcp.py
index 4913a32..d44c071 100644
--- a/nbxmpp/tcp.py
+++ b/nbxmpp/tcp.py
@@ -66,44 +66,23 @@ class TCPConnection(Connection):
@property
def tls_version(self) -> Optional[int]:
- if self._con is None:
+ if self._tls_con is None:
return None
if not min_version('GLib', '2.69.0'):
return None
- tls_con = self._con.get_base_io_stream()
- return tls_con.get_protocol_version()
+ return self._tls_con.get_protocol_version()
@property
def ciphersuite(self) -> Optional[str]:
- if self._con is None:
+ if self._tls_con is None:
return None
if not min_version('GLib', '2.69.0'):
return None
- tls_con = self._con.get_base_io_stream()
- return tls_con.get_ciphersuite_name()
-
- def get_channel_binding_data(
- self,
- type_: Gio.TlsChannelBindingType
- ) -> Optional[bytes]:
- if self._con is None:
- return None
-
- tls_con = self._con.get_base_io_stream()
-
- try:
- success, data = tls_con.get_channel_binding_data(type_)
- except Exception as error:
- self._log.warning('Unable to get channel binding data: %s', error)
- return None
-
- if not success:
- return None
- return data
+ return self._tls_con.get_ciphersuite_name()
def connect(self):
self.state = TCPState.CONNECTING
@@ -216,16 +195,16 @@ class TCPConnection(Connection):
identity = Gio.NetworkAddress.new(self._address.domain,
remote_address.props.port)
- tls_client = Gio.TlsClientConnection.new(self._con, identity)
+ self._tls_con = Gio.TlsClientConnection.new(self._con, identity)
if self._address.type == ConnectionType.DIRECT_TLS:
- tls_client.set_advertised_protocols(['xmpp-client'])
- tls_client.connect('accept-certificate', self._check_certificate)
- tls_client.connect('notify::peer-certificate', self._on_certificate_set)
+ self._tls_con.set_advertised_protocols(['xmpp-client'])
+ self._tls_con.connect('accept-certificate', self._check_certificate)
+ self._tls_con.connect('notify::peer-certificate', self._on_certificate_set)
# This Wraps the Gio.TlsClientConnection and the Gio.Socket together
# so we get back a Gio.SocketConnection
- self._con = Gio.TcpWrapperConnection.new(tls_client,
+ self._con = Gio.TcpWrapperConnection.new(self._tls_con,
self._con.get_socket())
def _read_async(self):
diff --git a/nbxmpp/websocket.py b/nbxmpp/websocket.py
index a3f8d82..a8e7f62 100644
--- a/nbxmpp/websocket.py
+++ b/nbxmpp/websocket.py
@@ -51,9 +51,11 @@ class WebsocketConnection(Connection):
self.state = TCPState.CONNECTING
message = Soup.Message.new('GET', self._address.uri)
+ assert message is not None
message.connect('accept-certificate', self._check_certificate)
message.connect('notify::tls-peer-certificate',
self._on_certificate_set)
+ message.connect('network-event', self._on_network_event)
message.set_flags(Soup.MessageFlags.NO_REDIRECT)
self._session.websocket_connect_async(message,
None,
@@ -107,6 +109,16 @@ class WebsocketConnection(Connection):
self._cancellable.cancel()
return False
+ def _on_network_event(
+ self,
+ message: Soup.Message,
+ event: Gio.SocketClientEvent,
+ connection: Gio.TlsConnection
+ ) -> None:
+
+ if event == Gio.SocketClientEvent.TLS_HANDSHAKED:
+ self._tls_con = connection
+
def _on_certificate_set(self, message, _param):
if self._peer_certificate is not None:
return