diff --git a/extension.js b/extension.js index 75aad1d..e8815f2 100644 --- a/extension.js +++ b/extension.js @@ -47,7 +47,7 @@ function disable() { torButton = null; } if (torControlClient !== null) { - torControlClient.close(); + torControlClient.closeConnection(); torControlClient = null; } } diff --git a/tor_control_client.js b/tor_control_client.js index 2ec67d8..28f4688 100644 --- a/tor_control_client.js +++ b/tor_control_client.js @@ -23,40 +23,54 @@ const Gio = imports.gi.Gio; const Lang = imports.lang; const Signals = imports.signals; +const TorProtocolError = new Lang.Class({ + Name: 'TorProtocolError', + Extends: Error, + + _init: function(message, statusCode) { + this.parent(message); + this.statusCode = statusCode; + } +}); + const TorControlClient = new Lang.Class({ Name: 'TorControlClient', + _init: function() { + this._fail_reason = null; + }, + openConnection: function() { - this._connect(); - this._updateProtocolInfo(); - this._ensureProtocolCompatibility(); - this._authenticate(); - this.emit('changed-connection-state', 'connected'); + try { + this._connect(); + this._updateProtocolInfo(); + this._ensureProtocolCompatibility(); + this._authenticate(); + this.emit('changed-connection-state', 'connected'); + } catch (e if (e instanceof Gio.IOErrorEnum || e instanceof TorProtocolError)) { + this.emit('changed-connection-state', 'disconnected', e.message); + } }, closeConnection: function() { - if (this._connection.is_connected()) { + if (this._connection && this._connection.is_connected()) { this._outputStream.close(null); this._inputStream.close(null); this.emit('changed-connection-state', 'disconnected'); } }, - _authenticate: function() { - var cookie = this._readAuthCookie(); - var reply = this._runCommand('AUTHENTICATE ' + cookie); - - if (reply.statusCode != 250) { - throw 'Could not authenticate, reason: ' + reply.replyLines.join('\n'); - } - }, - switchIdentity: function() { var reply = this._runCommand('SIGNAL NEWNYM'); if (reply.statusCode != 250) { - this.emit('changed-connection-state', 'failed'); - throw 'Could not change Tor identity, reason: ' + reply.replyLines.join('\n'); + this.emit( + 'protocol-error', + 'Could not switch Tor identity: ' + reply.replyLines.join('\n'), + reply.statusCode + ); + } else { + this.emit('switched-tor-identity'); } }, @@ -71,7 +85,9 @@ const TorControlClient = new Lang.Class({ var reply = this._runCommand('PROTOCOLINFO'); if (reply.statusCode != 250) { - throw "Could not read protocol info"; + throw new TorProtocolError( + 'Could not read protocol info, reason: ' + reply.replyLines.join('\n'), + reply.statusCode); } var protocolInfoVersion; @@ -106,7 +122,19 @@ const TorControlClient = new Lang.Class({ _ensureProtocolCompatibility: function() { if (this._protocolInfo.protocolInfoVersion != 1) { - throw 'Cannot handle tor protocol version ' + this._protocolInfo.protocolInfoVersion; + throw new TorProtocolError('Cannot handle tor protocol version ' + this._protocolInfo.protocolInfoVersion); + } + }, + + _authenticate: function() { + var cookie = this._readAuthCookie(); + var reply = this._runCommand('AUTHENTICATE ' + cookie); + + if (reply.statusCode != 250) { + throw new TorProtocolError( + 'Could not authenticate, reason: ' + reply.replyLines.join('\n'), + statusCode + ); } }, diff --git a/ui/tor_button.js b/ui/tor_button.js index f550dd8..4764355 100644 --- a/ui/tor_button.js +++ b/ui/tor_button.js @@ -22,9 +22,11 @@ along with gnome-shell-extension-tor. If not, see . + +This file is part of gnome-shell-extension-tor. + +gnome-shell-extension-tor is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +gnome-shell-extension-tor is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with gnome-shell-extension-tor. If not, see ./ +*/ +'use strict'; + +const Lang = imports.lang; +const PopupMenu = imports.ui.popupMenu; +const St = imports.gi.St; + +const TorDisconnectedMenu = new Lang.Class({ + Name: 'TorDisconnectedMenu', + Extends: PopupMenu.PopupMenu, + + _init: function(actor, torControlClient) { + this._torControlClient = torControlClient; + this.parent(actor, 0.25, St.Side.TOP); + + this._addActions(); + }, + + destroy: function() { + this.parent(arguments); + }, + + _addActions: function() { + var errorMessageMenuItem = new PopupMenu.PopupBaseMenuItem({reactive: false}); + errorMessageMenuItem.setSensitive(false); + errorMessageMenuItem.actor.add_actor(new St.Label({ + text: 'ERROR running' + })); + this.addMenuItem(errorMessageMenuItem); + + this.addAction('Reconnect', Lang.bind(this, this._reconnect)); + }, + + _reconnect: function() { + this._torControlClient.connect('changed-connection-state', function() {}) + this._torControlClient.openConnection(); + } +}); diff --git a/ui/tor_popup_menu.js b/ui/tor_popup_menu.js index 0f931ab..f0b648c 100644 --- a/ui/tor_popup_menu.js +++ b/ui/tor_popup_menu.js @@ -20,7 +20,6 @@ along with gnome-shell-extension-tor. If not, see