Philipp Hörist pushed to branch master at gajim / gajim
Commits: b9d17352 by lovetox at 2020-08-11T17:39:14+02:00 Remove ability to ignore tls errors
It’s complicated, error prone and people will shoot themself in the foot
Because the current error dialog lets us only show one error, the only allowed tls error where a connect is still possible is EXPIRED.
For UNKNOWN_CA there is still the possibility to mark the certificate as trusted, so it’s not considered a tls error on next connect.
- - - - - 00d5b852 by lovetox at 2020-08-11T18:05:42+02:00 Client: Don’t try to resume the stream after stream error
- - - - -
5 changed files:
- gajim/common/client.py - gajim/common/config.py - gajim/common/helpers.py - gajim/data/gui/ssl_error_dialog.ui - gajim/gtk/ssl_error_dialog.py
Changes:
===================================== gajim/common/client.py ===================================== @@ -33,7 +33,6 @@ from gajim.common.helpers import get_custom_host from gajim.common.helpers import get_user_proxy from gajim.common.helpers import warn_about_plain_connection from gajim.common.helpers import get_resource -from gajim.common.helpers import get_ignored_tls_errors from gajim.common.helpers import get_idle_status_message from gajim.common.idle import Monitor from gajim.common.i18n import _ @@ -79,8 +78,6 @@ class Client(ConnectionHandlers): self._destroy_client = False self._remove_account = False
- self._tls_errors = set() - self._destroyed = False
self.available_transports = {} @@ -177,9 +174,6 @@ class Client(ConnectionHandlers): self._client.set_accepted_certificates( app.cert_store.get_certificates())
- self._client.set_ignored_tls_errors( - get_ignored_tls_errors(self._account)) - if app.config.get_per('accounts', self._account, 'use_plain_connection'): self._client.set_connection_types([ConnectionType.PLAIN]) @@ -200,17 +194,6 @@ class Client(ConnectionHandlers): for handler in modules.get_handlers(self): self._client.register_handler(handler)
- def process_tls_errors(self): - if not self._tls_errors: - self.connect(ignore_all_errors=True) - return - - open_window('SSLErrorDialog', - account=self._account, - connection=self, - cert=self._client.peer_certificate[0], - error_num=self._tls_errors.pop()) - def _on_resume_failed(self, _client, _signal_name): log.info('Resume failed') app.nec.push_incoming_event(NetworkEvent( @@ -261,13 +244,16 @@ class Client(ConnectionHandlers): self._reconnect = False
elif domain == StreamError.BAD_CERTIFICATE: - self._tls_errors = self._client.peer_certificate[1] - self.get_module('Chatstate').enabled = False self._reconnect = False - self._after_disconnect() - app.nec.push_incoming_event(NetworkEvent( - 'our-show', account=self._account, show='offline')) - self.process_tls_errors() + self._destroy_client = True + + cert, errors = self._client.peer_certificate + + open_window('SSLErrorDialog', + account=self._account, + client=self, + cert=cert, + error=errors.pop())
elif domain in (StreamError.STREAM, StreamError.BIND): if error == 'conflict': @@ -277,6 +263,7 @@ class Client(ConnectionHandlers):
elif domain == StreamError.SASL: self._reconnect = False + self._destroy_client = True
if error in ('not-authorized', 'no-password'): def _on_password(password): @@ -511,29 +498,29 @@ class Client(ConnectionHandlers): message.stanza = stanza self._send_message(message)
- def connect(self, ignore_all_errors=False): + def connect(self, ignored_tls_errors=None): if self._state not in (ClientState.DISCONNECTED, ClientState.RECONNECT_SCHEDULED): # Do not try to reco while we are already trying return
log.info('Connect') + + self._client.set_ignored_tls_errors(ignored_tls_errors) self._reconnect = True self._disable_reconnect_timer() self._set_state(ClientState.CONNECTING) - if ignore_all_errors: - self._client.set_ignore_tls_errors(True) - self._client.connect() - else: - if warn_about_plain_connection(self._account, - self._client.connection_types): - app.nec.push_incoming_event(NetworkEvent( - 'plain-connection', - account=self._account, - connect=self._client.connect, - abort=self._abort_reconnect)) - return - self._client.connect() + + if warn_about_plain_connection(self._account, + self._client.connection_types): + app.nec.push_incoming_event(NetworkEvent( + 'plain-connection', + account=self._account, + connect=self._client.connect, + abort=self._abort_reconnect)) + return + + self._client.connect()
def _schedule_reconnect(self): self._set_state(ClientState.RECONNECT_SCHEDULED)
===================================== gajim/common/config.py ===================================== @@ -278,7 +278,6 @@ class Config: 'keyname': [opt_str, '', '', True], 'use_plain_connection': [opt_bool, False, _('Use an unencrypted connection to the server')], 'action_when_plain_connection': [opt_str, 'warn', _('Show a warning dialog before sending password on an plaintext connection. Can be 'warn', or 'none'.')], - 'ignore_ssl_errors': [opt_str, '', _('List of SSL errors to ignore (space separated).')], 'use_custom_host': [opt_bool, False, '', True], 'custom_port': [opt_int, 5222, '', True], 'custom_host': [opt_str, '', '', True],
===================================== gajim/common/helpers.py ===================================== @@ -1402,12 +1402,6 @@ def warn_about_plain_connection(account, connection_types): return False
-def get_ignored_tls_errors(account): - ignore_ssl_errors = app.config.get_per( - 'accounts', account, 'ignore_ssl_errors').split() - return {Gio.TlsCertificateFlags(int(err)) for err in ignore_ssl_errors} - - def get_idle_status_message(state, status_message): message = app.config.get(f'auto{state}_message') if not message:
===================================== gajim/data/gui/ssl_error_dialog.ui ===================================== @@ -80,6 +80,7 @@ <property name="margin_right">15</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> + <signal name="toggled" handler="_on_add_certificate_toggled" swapped="no"/> </object> <packing> <property name="expand">False</property> @@ -88,22 +89,7 @@ </packing> </child> <child> - <object class="GtkCheckButton" id="ignore_error_checkbutton"> - <property name="label" translatable="yes">_Ignore this error for this certificate</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="margin_left">15</property> - <property name="margin_right">15</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">5</property> - </packing> + <placeholder/> </child> <child> <object class="GtkBox"> @@ -133,6 +119,7 @@ <object class="GtkButton" id="connect_button"> <property name="label" translatable="yes">_Connect</property> <property name="visible">True</property> + <property name="sensitive">False</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="halign">end</property>
===================================== gajim/gtk/ssl_error_dialog.py ===================================== @@ -26,7 +26,7 @@ from gajim.gtk.util import open_window
class SSLErrorDialog(Gtk.ApplicationWindow): - def __init__(self, account, connection, cert, error_num): + def __init__(self, account, client, cert, error): Gtk.ApplicationWindow.__init__(self) self.set_name('SSLErrorDialog') self.set_application(app.app) @@ -39,8 +39,8 @@ class SSLErrorDialog(Gtk.ApplicationWindow): self.add(self._ui.ssl_error_box)
self.account = account - self._error_num = error_num - self._con = connection + self._error = error + self._client = client self._cert = cert self._server = app.config.get_per('accounts', self.account, 'hostname')
@@ -54,30 +54,36 @@ class SSLErrorDialog(Gtk.ApplicationWindow): _('There was an error while attempting to verify the SSL ' 'certificate of your XMPP server (%s).') % self._server)
- unknown_error = _('Unknown SSL error '%s'') % self._error_num - ssl_error = GIO_TLS_ERRORS.get(self._error_num, unknown_error) + unknown_error = _('Unknown SSL error '%s'') % self._error + ssl_error = GIO_TLS_ERRORS.get(self._error, unknown_error) self._ui.ssl_error.set_text(ssl_error)
- if self._error_num == Gio.TlsCertificateFlags.UNKNOWN_CA: + if self._error == Gio.TlsCertificateFlags.UNKNOWN_CA: self._ui.add_certificate_checkbutton.show()
+ elif self._error == Gio.TlsCertificateFlags.EXPIRED: + self._ui.connect_button.set_sensitive(True) + + else: + self._ui.connect_button.set_no_show_all(True) + self._ui.connect_button.hide() + def _on_view_cert_clicked(self, _button): open_window('CertificateDialog', account=self.account, transient_for=self, cert=self._cert)
- def _on_connect_clicked(self, _button): - # Ignore this error - if self._ui.ignore_error_checkbutton.get_active(): - ignore_ssl_errors = app.config.get_per( - 'accounts', self.account, 'ignore_ssl_errors').split() - ignore_ssl_errors.append(str(int(self._error_num))) - app.config.set_per('accounts', self.account, 'ignore_ssl_errors', - ' '.join(ignore_ssl_errors)) + def _on_add_certificate_toggled(self, checkbutton): + self._ui.connect_button.set_sensitive(checkbutton.get_active())
+ def _on_connect_clicked(self, _button): if self._ui.add_certificate_checkbutton.get_active(): app.cert_store.add_certificate(self._cert)
+ ignored_tls_errors = None + if self._error == Gio.TlsCertificateFlags.EXPIRED: + ignored_tls_errors = set([Gio.TlsCertificateFlags.EXPIRED]) + self.destroy() - self._con.process_tls_errors() + self._client.connect(ignored_tls_errors=ignored_tls_errors)
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/029dfc0ee978c884f31bf3ac65fedcab...