cq: Format with black and isort
This commit is contained in:
@@ -20,8 +20,8 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with PGP Gajim Plugin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import logging
|
||||
import os
|
||||
from functools import lru_cache
|
||||
|
||||
import gnupg
|
||||
@@ -30,56 +30,51 @@ from gajim.common.util.classes import Singleton
|
||||
|
||||
from pgp.exceptions import SignError
|
||||
|
||||
|
||||
logger = logging.getLogger('gajim.p.pgplegacy')
|
||||
logger = logging.getLogger("gajim.p.pgplegacy")
|
||||
if logger.getEffectiveLevel() == logging.DEBUG:
|
||||
logger = logging.getLogger('gnupg')
|
||||
logger = logging.getLogger("gnupg")
|
||||
logger.addHandler(logging.StreamHandler())
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
class PGP(gnupg.GPG, metaclass=Singleton):
|
||||
def __init__(self, binary, encoding=None):
|
||||
super().__init__(gpgbinary=binary,
|
||||
use_agent=True)
|
||||
super().__init__(gpgbinary=binary, use_agent=True)
|
||||
|
||||
if encoding is not None:
|
||||
self.encoding = encoding
|
||||
self.decode_errors = 'replace'
|
||||
self.decode_errors = "replace"
|
||||
|
||||
def encrypt(self, payload, recipients, always_trust=False):
|
||||
if not always_trust:
|
||||
# check that we'll be able to encrypt
|
||||
result = self.get_key(recipients[0])
|
||||
for key in result:
|
||||
if key['trust'] not in ('f', 'u'):
|
||||
return '', 'NOT_TRUSTED ' + key['keyid'][-8:]
|
||||
if key["trust"] not in ("f", "u"):
|
||||
return "", "NOT_TRUSTED " + key["keyid"][-8:]
|
||||
|
||||
result = super().encrypt(
|
||||
payload.encode('utf8'),
|
||||
recipients,
|
||||
always_trust=always_trust)
|
||||
payload.encode("utf8"), recipients, always_trust=always_trust
|
||||
)
|
||||
|
||||
if result.ok:
|
||||
error = ''
|
||||
error = ""
|
||||
else:
|
||||
error = result.status
|
||||
|
||||
return self._strip_header_footer(str(result)), error
|
||||
|
||||
def decrypt(self, payload):
|
||||
data = self._add_header_footer(payload, 'MESSAGE')
|
||||
result = super().decrypt(data.encode('utf8'))
|
||||
data = self._add_header_footer(payload, "MESSAGE")
|
||||
result = super().decrypt(data.encode("utf8"))
|
||||
|
||||
return result.data.decode('utf8')
|
||||
return result.data.decode("utf8")
|
||||
|
||||
@lru_cache(maxsize=8)
|
||||
def sign(self, payload, key_id):
|
||||
if payload is None:
|
||||
payload = ''
|
||||
result = super().sign(payload.encode('utf8'),
|
||||
keyid=key_id,
|
||||
detach=True)
|
||||
payload = ""
|
||||
result = super().sign(payload.encode("utf8"), keyid=key_id, detach=True)
|
||||
|
||||
if result.fingerprint:
|
||||
return self._strip_header_footer(str(result))
|
||||
@@ -91,19 +86,20 @@ class PGP(gnupg.GPG, metaclass=Singleton):
|
||||
# Text name for hash algorithms from RFC 4880 - section 9.4
|
||||
|
||||
if payload is None:
|
||||
payload = ''
|
||||
payload = ""
|
||||
|
||||
hash_algorithms = ['SHA512', 'SHA384', 'SHA256',
|
||||
'SHA224', 'SHA1', 'RIPEMD160']
|
||||
hash_algorithms = ["SHA512", "SHA384", "SHA256", "SHA224", "SHA1", "RIPEMD160"]
|
||||
for algo in hash_algorithms:
|
||||
data = os.linesep.join(
|
||||
['-----BEGIN PGP SIGNED MESSAGE-----',
|
||||
'Hash: ' + algo,
|
||||
'',
|
||||
payload,
|
||||
self._add_header_footer(signed, 'SIGNATURE')]
|
||||
)
|
||||
result = super().verify(data.encode('utf8'))
|
||||
[
|
||||
"-----BEGIN PGP SIGNED MESSAGE-----",
|
||||
"Hash: " + algo,
|
||||
"",
|
||||
payload,
|
||||
self._add_header_footer(signed, "SIGNATURE"),
|
||||
]
|
||||
)
|
||||
result = super().verify(data.encode("utf8"))
|
||||
if result.valid:
|
||||
return result.fingerprint
|
||||
|
||||
@@ -116,7 +112,7 @@ class PGP(gnupg.GPG, metaclass=Singleton):
|
||||
|
||||
for key in result:
|
||||
# Take first not empty uid
|
||||
keys[key['fingerprint']] = next(uid for uid in key['uids'] if uid)
|
||||
keys[key["fingerprint"]] = next(uid for uid in key["uids"] if uid)
|
||||
return keys
|
||||
|
||||
@staticmethod
|
||||
@@ -125,19 +121,19 @@ class PGP(gnupg.GPG, metaclass=Singleton):
|
||||
Remove header and footer from data
|
||||
"""
|
||||
if not data:
|
||||
return ''
|
||||
return ""
|
||||
lines = data.splitlines()
|
||||
while lines[0] != '':
|
||||
while lines[0] != "":
|
||||
lines.remove(lines[0])
|
||||
while lines[0] == '':
|
||||
while lines[0] == "":
|
||||
lines.remove(lines[0])
|
||||
i = 0
|
||||
for line in lines:
|
||||
if line:
|
||||
if line[0] == '-':
|
||||
if line[0] == "-":
|
||||
break
|
||||
i = i+1
|
||||
line = '\n'.join(lines[0:i])
|
||||
i = i + 1
|
||||
line = "\n".join(lines[0:i])
|
||||
return line
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -34,31 +34,30 @@ class KeyStore:
|
||||
self._account = account
|
||||
|
||||
own_bare_jid = own_jid.bare
|
||||
path = Path(configpaths.get('PLUGINS_DATA')) / 'pgplegacy' / own_bare_jid
|
||||
path = Path(configpaths.get("PLUGINS_DATA")) / "pgplegacy" / own_bare_jid
|
||||
if not path.exists():
|
||||
path.mkdir(parents=True)
|
||||
|
||||
self._store_path = path / 'store'
|
||||
self._store_path = path / "store"
|
||||
if self._store_path.exists():
|
||||
# having store v2 or higher
|
||||
with self._store_path.open('r') as file:
|
||||
with self._store_path.open("r") as file:
|
||||
try:
|
||||
self._store = json.load(file)
|
||||
except Exception:
|
||||
log.exception('Could not load config')
|
||||
log.exception("Could not load config")
|
||||
self._store = self._empty_store()
|
||||
|
||||
ver = self._store.get('_version', 2)
|
||||
ver = self._store.get("_version", 2)
|
||||
if ver > CURRENT_STORE_VERSION:
|
||||
raise Exception('Unknown store version! '
|
||||
'Please upgrade pgp plugin.')
|
||||
raise Exception("Unknown store version! " "Please upgrade pgp plugin.")
|
||||
elif ver == 2:
|
||||
self._migrate_v2_store()
|
||||
self._save_store()
|
||||
elif ver != CURRENT_STORE_VERSION:
|
||||
# garbled version
|
||||
self._store = self._empty_store()
|
||||
log.warning('Bad pgp key store version. Initializing new.')
|
||||
log.warning("Bad pgp key store version. Initializing new.")
|
||||
else:
|
||||
# having store v1 or fresh install
|
||||
self._store = self._empty_store()
|
||||
@@ -69,15 +68,16 @@ class KeyStore:
|
||||
@staticmethod
|
||||
def _empty_store():
|
||||
return {
|
||||
'_version': CURRENT_STORE_VERSION,
|
||||
'own_key_data': None,
|
||||
'contact_key_data': {},
|
||||
"_version": CURRENT_STORE_VERSION,
|
||||
"own_key_data": None,
|
||||
"contact_key_data": {},
|
||||
}
|
||||
|
||||
def _migrate_v1_store(self):
|
||||
keys = {}
|
||||
attached_keys = app.settings.get_account_setting(
|
||||
self._account, 'attached_gpg_keys')
|
||||
self._account, "attached_gpg_keys"
|
||||
)
|
||||
if not attached_keys:
|
||||
return
|
||||
attached_keys = attached_keys.split()
|
||||
@@ -86,23 +86,25 @@ class KeyStore:
|
||||
keys[attached_keys[2 * i]] = attached_keys[2 * i + 1]
|
||||
|
||||
for jid, key_id in keys.items():
|
||||
self._set_contact_key_data_nosync(jid, (key_id, ''))
|
||||
self._set_contact_key_data_nosync(jid, (key_id, ""))
|
||||
|
||||
own_key_id = app.settings.get_account_setting(self._account, 'keyid')
|
||||
own_key_user = app.settings.get_account_setting(
|
||||
self._account, 'keyname')
|
||||
own_key_id = app.settings.get_account_setting(self._account, "keyid")
|
||||
own_key_user = app.settings.get_account_setting(self._account, "keyname")
|
||||
if own_key_id:
|
||||
self._set_own_key_data_nosync((own_key_id, own_key_user))
|
||||
|
||||
attached_keys = app.settings.set_account_setting(
|
||||
self._account, 'attached_gpg_keys', '')
|
||||
self._log.info('Migration from store v1 was successful')
|
||||
self._account, "attached_gpg_keys", ""
|
||||
)
|
||||
self._log.info("Migration from store v1 was successful")
|
||||
|
||||
def _migrate_v2_store(self):
|
||||
own_key_data = self.get_own_key_data()
|
||||
if own_key_data is not None:
|
||||
own_key_id, own_key_user = (own_key_data['key_id'],
|
||||
own_key_data['key_user'])
|
||||
own_key_id, own_key_user = (
|
||||
own_key_data["key_id"],
|
||||
own_key_data["key_user"],
|
||||
)
|
||||
try:
|
||||
own_key_fp = self._resolve_short_id(own_key_id, has_secret=True)
|
||||
self._set_own_key_data_nosync((own_key_fp, own_key_user))
|
||||
@@ -111,38 +113,41 @@ class KeyStore:
|
||||
|
||||
prune_list = []
|
||||
|
||||
for dict_key, key_data in self._store['contact_key_data'].items():
|
||||
for dict_key, key_data in self._store["contact_key_data"].items():
|
||||
try:
|
||||
key_data['key_id'] = self._resolve_short_id(key_data['key_id'])
|
||||
key_data["key_id"] = self._resolve_short_id(key_data["key_id"])
|
||||
except KeyResolveError:
|
||||
prune_list.append(dict_key)
|
||||
|
||||
for dict_key in prune_list:
|
||||
del self._store['contact_key_data'][dict_key]
|
||||
del self._store["contact_key_data"][dict_key]
|
||||
|
||||
self._store['_version'] = CURRENT_STORE_VERSION
|
||||
self._log.info('Migration from store v2 was successful')
|
||||
self._store["_version"] = CURRENT_STORE_VERSION
|
||||
self._log.info("Migration from store v2 was successful")
|
||||
|
||||
def _save_store(self):
|
||||
with self._store_path.open('w') as file:
|
||||
with self._store_path.open("w") as file:
|
||||
json.dump(self._store, file)
|
||||
|
||||
def _get_dict_key(self, jid):
|
||||
return '%s-%s' % (self._account, jid)
|
||||
return "%s-%s" % (self._account, jid)
|
||||
|
||||
def _resolve_short_id(self, short_id, has_secret=False):
|
||||
candidates = self._list_keys_func(
|
||||
secret=has_secret, keys=(short_id,)).fingerprints
|
||||
secret=has_secret, keys=(short_id,)
|
||||
).fingerprints
|
||||
if len(candidates) == 1:
|
||||
return candidates[0]
|
||||
elif len(candidates) > 1:
|
||||
self._log.critical('Key collision during migration. '
|
||||
'Key ID is %s. Removing binding...',
|
||||
repr(short_id))
|
||||
self._log.critical(
|
||||
"Key collision during migration. " "Key ID is %s. Removing binding...",
|
||||
repr(short_id),
|
||||
)
|
||||
else:
|
||||
self._log.warning('Key %s was not found during migration. '
|
||||
'Removing binding...',
|
||||
repr(short_id))
|
||||
self._log.warning(
|
||||
"Key %s was not found during migration. " "Removing binding...",
|
||||
repr(short_id),
|
||||
)
|
||||
raise KeyResolveError
|
||||
|
||||
def set_own_key_data(self, key_data):
|
||||
@@ -151,18 +156,18 @@ class KeyStore:
|
||||
|
||||
def _set_own_key_data_nosync(self, key_data):
|
||||
if key_data is None:
|
||||
self._store['own_key_data'] = None
|
||||
self._store["own_key_data"] = None
|
||||
else:
|
||||
self._store['own_key_data'] = {
|
||||
'key_id': key_data[0],
|
||||
'key_user': key_data[1]
|
||||
self._store["own_key_data"] = {
|
||||
"key_id": key_data[0],
|
||||
"key_user": key_data[1],
|
||||
}
|
||||
|
||||
def get_own_key_data(self):
|
||||
return self._store['own_key_data']
|
||||
return self._store["own_key_data"]
|
||||
|
||||
def get_contact_key_data(self, jid):
|
||||
key_ids = self._store['contact_key_data']
|
||||
key_ids = self._store["contact_key_data"]
|
||||
dict_key = self._get_dict_key(jid)
|
||||
return key_ids.get(dict_key)
|
||||
|
||||
@@ -171,12 +176,9 @@ class KeyStore:
|
||||
self._save_store()
|
||||
|
||||
def _set_contact_key_data_nosync(self, jid, key_data):
|
||||
key_ids = self._store['contact_key_data']
|
||||
key_ids = self._store["contact_key_data"]
|
||||
dict_key = self._get_dict_key(jid)
|
||||
if key_data is None:
|
||||
key_ids[dict_key] = None
|
||||
else:
|
||||
key_ids[dict_key] = {
|
||||
'key_id': key_data[0],
|
||||
'key_user': key_data[1]
|
||||
}
|
||||
key_ids[dict_key] = {"key_id": key_data[0], "key_user": key_data[1]}
|
||||
|
||||
@@ -14,11 +14,14 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with PGP Gajim Plugin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
class SignError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class KeyMismatch(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class NoKeyIdFound(Exception):
|
||||
pass
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Gdk
|
||||
from gi.repository import GLib
|
||||
from gi.repository import Gtk
|
||||
|
||||
from gajim.common import app
|
||||
|
||||
from gajim.plugins.helpers import get_builder
|
||||
from gajim.plugins.plugins_i18n import _
|
||||
|
||||
@@ -33,14 +32,14 @@ class PGPConfigDialog(Gtk.ApplicationWindow):
|
||||
Gtk.ApplicationWindow.__init__(self)
|
||||
self.set_application(app.app)
|
||||
self.set_show_menubar(False)
|
||||
self.set_title(_('PGP Configuration'))
|
||||
self.set_title(_("PGP Configuration"))
|
||||
self.set_transient_for(parent)
|
||||
self.set_resizable(True)
|
||||
self.set_type_hint(Gdk.WindowTypeHint.DIALOG)
|
||||
self.set_destroy_with_parent(True)
|
||||
|
||||
ui_path = Path(__file__).parent
|
||||
self._ui = get_builder(ui_path.resolve() / 'config.ui')
|
||||
self._ui = get_builder(ui_path.resolve() / "config.ui")
|
||||
|
||||
self.add(self._ui.config_box)
|
||||
|
||||
@@ -50,9 +49,7 @@ class PGPConfigDialog(Gtk.ApplicationWindow):
|
||||
|
||||
for account in app.settings.get_active_accounts():
|
||||
page = Page(plugin, account)
|
||||
self._ui.stack.add_titled(page,
|
||||
account,
|
||||
app.get_account_label(account))
|
||||
self._ui.stack.add_titled(page, account, app.get_account_label(account))
|
||||
|
||||
self.show_all()
|
||||
|
||||
@@ -64,11 +61,11 @@ class Page(Gtk.Box):
|
||||
self._client = app.get_client(account)
|
||||
self._plugin = plugin
|
||||
self._label = Gtk.Label()
|
||||
self._button = Gtk.Button(label=_('Assign Key'))
|
||||
self._button.get_style_context().add_class('suggested-action')
|
||||
self._button = Gtk.Button(label=_("Assign Key"))
|
||||
self._button.get_style_context().add_class("suggested-action")
|
||||
self._button.set_halign(Gtk.Align.CENTER)
|
||||
self._button.set_margin_top(18)
|
||||
self._button.connect('clicked', self._on_assign)
|
||||
self._button.connect("clicked", self._on_assign)
|
||||
|
||||
self._load_key()
|
||||
self.add(self._label)
|
||||
@@ -76,34 +73,34 @@ class Page(Gtk.Box):
|
||||
self.show_all()
|
||||
|
||||
def _on_assign(self, _button):
|
||||
backend = self._client.get_module('PGPLegacy').pgp_backend
|
||||
backend = self._client.get_module("PGPLegacy").pgp_backend
|
||||
secret_keys = backend.get_keys(secret=True)
|
||||
dialog = ChooseGPGKeyDialog(secret_keys, self.get_toplevel())
|
||||
dialog.connect('response', self._on_response)
|
||||
dialog.connect("response", self._on_response)
|
||||
|
||||
def _load_key(self):
|
||||
key_data = self._client.get_module('PGPLegacy').get_own_key_data()
|
||||
key_data = self._client.get_module("PGPLegacy").get_own_key_data()
|
||||
if key_data is None:
|
||||
self._set_key(None)
|
||||
else:
|
||||
self._set_key((key_data['key_id'], key_data['key_user']))
|
||||
self._set_key((key_data["key_id"], key_data["key_user"]))
|
||||
|
||||
def _on_response(self, dialog, response):
|
||||
if response != Gtk.ResponseType.OK:
|
||||
return
|
||||
|
||||
if dialog.selected_key is None:
|
||||
self._client.get_module('PGPLegacy').set_own_key_data(None)
|
||||
self._client.get_module("PGPLegacy").set_own_key_data(None)
|
||||
self._set_key(None)
|
||||
else:
|
||||
self._client.get_module('PGPLegacy').set_own_key_data(
|
||||
dialog.selected_key)
|
||||
self._client.get_module("PGPLegacy").set_own_key_data(dialog.selected_key)
|
||||
self._set_key(dialog.selected_key)
|
||||
|
||||
def _set_key(self, key_data):
|
||||
if key_data is None:
|
||||
self._label.set_text(_('No key assigned'))
|
||||
self._label.set_text(_("No key assigned"))
|
||||
else:
|
||||
key_id, key_user = key_data
|
||||
self._label.set_markup('<b><tt>%s</tt> %s</b>' % \
|
||||
(key_id, GLib.markup_escape_text(key_user)))
|
||||
self._label.set_markup(
|
||||
"<b><tt>%s</tt> %s</b>" % (key_id, GLib.markup_escape_text(key_user))
|
||||
)
|
||||
|
||||
@@ -16,18 +16,17 @@
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import GLib
|
||||
from gi.repository import Gtk
|
||||
|
||||
from gajim.common import app
|
||||
from gajim.plugins.plugins_i18n import _
|
||||
from gajim.plugins.helpers import get_builder
|
||||
from gajim.plugins.plugins_i18n import _
|
||||
|
||||
|
||||
class KeyDialog(Gtk.Dialog):
|
||||
def __init__(self, plugin, account, jid, transient):
|
||||
super().__init__(title=_('Assign key for %s') % jid,
|
||||
destroy_with_parent=True)
|
||||
super().__init__(title=_("Assign key for %s") % jid, destroy_with_parent=True)
|
||||
|
||||
self.set_transient_for(transient)
|
||||
self.set_resizable(True)
|
||||
@@ -39,11 +38,11 @@ class KeyDialog(Gtk.Dialog):
|
||||
|
||||
self._label = Gtk.Label()
|
||||
|
||||
self._assign_button = Gtk.Button(label=_('Assign Key'))
|
||||
self._assign_button.get_style_context().add_class('suggested-action')
|
||||
self._assign_button = Gtk.Button(label=_("Assign Key"))
|
||||
self._assign_button.get_style_context().add_class("suggested-action")
|
||||
self._assign_button.set_halign(Gtk.Align.CENTER)
|
||||
self._assign_button.set_margin_top(18)
|
||||
self._assign_button.connect('clicked', self._choose_key)
|
||||
self._assign_button.connect("clicked", self._choose_key)
|
||||
|
||||
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
box.set_border_width(18)
|
||||
@@ -57,13 +56,12 @@ class KeyDialog(Gtk.Dialog):
|
||||
self.show_all()
|
||||
|
||||
def _choose_key(self, *args):
|
||||
backend = self._client.get_module('PGPLegacy').pgp_backend
|
||||
backend = self._client.get_module("PGPLegacy").pgp_backend
|
||||
dialog = ChooseGPGKeyDialog(backend.get_keys(), self)
|
||||
dialog.connect('response', self._on_response)
|
||||
dialog.connect("response", self._on_response)
|
||||
|
||||
def _load_key(self):
|
||||
key_data = self._client.get_module('PGPLegacy').get_contact_key_data(
|
||||
self._jid)
|
||||
key_data = self._client.get_module("PGPLegacy").get_contact_key_data(self._jid)
|
||||
if key_data is None:
|
||||
self._set_key(None)
|
||||
else:
|
||||
@@ -74,42 +72,43 @@ class KeyDialog(Gtk.Dialog):
|
||||
return
|
||||
|
||||
if dialog.selected_key is None:
|
||||
self._client.get_module('PGPLegacy').set_contact_key_data(
|
||||
self._jid, None)
|
||||
self._client.get_module("PGPLegacy").set_contact_key_data(self._jid, None)
|
||||
self._set_key(None)
|
||||
else:
|
||||
self._client.get_module('PGPLegacy').set_contact_key_data(
|
||||
self._jid, dialog.selected_key)
|
||||
self._client.get_module("PGPLegacy").set_contact_key_data(
|
||||
self._jid, dialog.selected_key
|
||||
)
|
||||
self._set_key(dialog.selected_key)
|
||||
|
||||
def _set_key(self, key_data):
|
||||
if key_data is None:
|
||||
self._label.set_text(_('No key assigned'))
|
||||
self._label.set_text(_("No key assigned"))
|
||||
else:
|
||||
key_id, key_user = key_data
|
||||
self._label.set_markup('<b><tt>%s</tt> %s</b>' % \
|
||||
(key_id, GLib.markup_escape_text(key_user)))
|
||||
self._label.set_markup(
|
||||
"<b><tt>%s</tt> %s</b>" % (key_id, GLib.markup_escape_text(key_user))
|
||||
)
|
||||
|
||||
|
||||
class ChooseGPGKeyDialog(Gtk.Dialog):
|
||||
def __init__(self, secret_keys, transient_for):
|
||||
Gtk.Dialog.__init__(self,
|
||||
title=_('Assign PGP Key'),
|
||||
transient_for=transient_for)
|
||||
Gtk.Dialog.__init__(
|
||||
self, title=_("Assign PGP Key"), transient_for=transient_for
|
||||
)
|
||||
|
||||
secret_keys[_('None')] = _('None')
|
||||
secret_keys[_("None")] = _("None")
|
||||
|
||||
self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
|
||||
self.set_resizable(True)
|
||||
self.set_default_size(500, 300)
|
||||
|
||||
self.add_button(_('Cancel'), Gtk.ResponseType.CANCEL)
|
||||
self.add_button(_('OK'), Gtk.ResponseType.OK)
|
||||
self.add_button(_("Cancel"), Gtk.ResponseType.CANCEL)
|
||||
self.add_button(_("OK"), Gtk.ResponseType.OK)
|
||||
|
||||
self._selected_key = None
|
||||
|
||||
ui_path = Path(__file__).parent
|
||||
self._ui = get_builder(ui_path.resolve() / 'choose_key.ui')
|
||||
self._ui = get_builder(ui_path.resolve() / "choose_key.ui")
|
||||
|
||||
self._ui.keys_treeview = self._ui.keys_treeview
|
||||
|
||||
@@ -124,7 +123,7 @@ class ChooseGPGKeyDialog(Gtk.Dialog):
|
||||
|
||||
self._ui.connect_signals(self)
|
||||
|
||||
self.connect_after('response', self._on_response)
|
||||
self.connect_after("response", self._on_response)
|
||||
|
||||
self.show_all()
|
||||
|
||||
@@ -136,9 +135,9 @@ class ChooseGPGKeyDialog(Gtk.Dialog):
|
||||
def _sort(model, iter1, iter2, _data):
|
||||
value1 = model[iter1][1]
|
||||
value2 = model[iter2][1]
|
||||
if value1 == _('None'):
|
||||
if value1 == _("None"):
|
||||
return -1
|
||||
if value2 == _('None'):
|
||||
if value2 == _("None"):
|
||||
return 1
|
||||
if value1 < value2:
|
||||
return -1
|
||||
@@ -154,7 +153,7 @@ class ChooseGPGKeyDialog(Gtk.Dialog):
|
||||
self._selected_key = None
|
||||
else:
|
||||
key_id, key_user = model[iter_][0], model[iter_][1]
|
||||
if key_id == _('None'):
|
||||
if key_id == _("None"):
|
||||
self._selected_key = None
|
||||
else:
|
||||
self._selected_key = key_id, key_user
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with OMEMO Gajim Plugin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Callable
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import field
|
||||
@@ -24,12 +25,12 @@ from gajim.common.events import ApplicationEvent
|
||||
|
||||
@dataclass
|
||||
class PGPNotTrusted(ApplicationEvent):
|
||||
name: str = field(init=False, default='pgp-not-trusted')
|
||||
name: str = field(init=False, default="pgp-not-trusted")
|
||||
on_yes: Callable[..., Any]
|
||||
on_no: Callable[..., Any]
|
||||
|
||||
|
||||
@dataclass
|
||||
class PGPFileEncryptionError(ApplicationEvent):
|
||||
name: str = field(init=False, default='pgp-file-encryption-error')
|
||||
name: str = field(init=False, default="pgp-file-encryption-error")
|
||||
error: str
|
||||
|
||||
@@ -15,57 +15,55 @@
|
||||
# along with PGP Gajim Plugin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import time
|
||||
import threading
|
||||
import time
|
||||
|
||||
import nbxmpp
|
||||
from gi.repository import GLib
|
||||
from nbxmpp.namespaces import Namespace
|
||||
from nbxmpp.protocol import Message
|
||||
from nbxmpp.structs import EncryptionData
|
||||
from nbxmpp.structs import StanzaHandler
|
||||
from gi.repository import GLib
|
||||
|
||||
from gajim.common import app
|
||||
from gajim.common.const import Trust
|
||||
from gajim.common.events import MessageNotSent
|
||||
from gajim.common.structs import OutgoingMessage
|
||||
from gajim.common.modules.base import BaseModule
|
||||
|
||||
from gajim.common.structs import OutgoingMessage
|
||||
from gajim.plugins.plugins_i18n import _
|
||||
|
||||
from pgp.backend.python_gnupg import PGP
|
||||
from pgp.backend.store import KeyStore
|
||||
from pgp.exceptions import KeyMismatch
|
||||
from pgp.exceptions import NoKeyIdFound
|
||||
from pgp.exceptions import SignError
|
||||
from pgp.modules.events import PGPFileEncryptionError
|
||||
from pgp.modules.events import PGPNotTrusted
|
||||
from pgp.modules.util import prepare_stanza
|
||||
from pgp.backend.store import KeyStore
|
||||
from pgp.exceptions import SignError
|
||||
from pgp.exceptions import KeyMismatch
|
||||
from pgp.exceptions import NoKeyIdFound
|
||||
|
||||
|
||||
# Module name
|
||||
name = 'PGPLegacy'
|
||||
name = "PGPLegacy"
|
||||
zeroconf = True
|
||||
ENCRYPTION_NAME = 'PGP'
|
||||
ENCRYPTION_NAME = "PGP"
|
||||
|
||||
ALLOWED_TAGS = [
|
||||
('request', Namespace.RECEIPTS),
|
||||
('active', Namespace.CHATSTATES),
|
||||
('gone', Namespace.CHATSTATES),
|
||||
('inactive', Namespace.CHATSTATES),
|
||||
('paused', Namespace.CHATSTATES),
|
||||
('composing', Namespace.CHATSTATES),
|
||||
('markable', Namespace.CHATMARKERS),
|
||||
('no-store', Namespace.HINTS),
|
||||
('store', Namespace.HINTS),
|
||||
('no-copy', Namespace.HINTS),
|
||||
('no-permanent-store', Namespace.HINTS),
|
||||
('replace', Namespace.CORRECT),
|
||||
('thread', None),
|
||||
('reply', Namespace.REPLY),
|
||||
('fallback', Namespace.FALLBACK),
|
||||
('origin-id', Namespace.SID),
|
||||
('reactions', Namespace.REACTIONS),
|
||||
("request", Namespace.RECEIPTS),
|
||||
("active", Namespace.CHATSTATES),
|
||||
("gone", Namespace.CHATSTATES),
|
||||
("inactive", Namespace.CHATSTATES),
|
||||
("paused", Namespace.CHATSTATES),
|
||||
("composing", Namespace.CHATSTATES),
|
||||
("markable", Namespace.CHATMARKERS),
|
||||
("no-store", Namespace.HINTS),
|
||||
("store", Namespace.HINTS),
|
||||
("no-copy", Namespace.HINTS),
|
||||
("no-permanent-store", Namespace.HINTS),
|
||||
("replace", Namespace.CORRECT),
|
||||
("thread", None),
|
||||
("reply", Namespace.REPLY),
|
||||
("fallback", Namespace.FALLBACK),
|
||||
("origin-id", Namespace.SID),
|
||||
("reactions", Namespace.REACTIONS),
|
||||
]
|
||||
|
||||
|
||||
@@ -74,21 +72,26 @@ class PGPLegacy(BaseModule):
|
||||
BaseModule.__init__(self, client, plugin=True)
|
||||
|
||||
self.handlers = [
|
||||
StanzaHandler(name='message',
|
||||
callback=self._message_received,
|
||||
ns=Namespace.ENCRYPTED,
|
||||
priority=9),
|
||||
StanzaHandler(name='presence',
|
||||
callback=self._on_presence_received,
|
||||
ns=Namespace.SIGNED,
|
||||
priority=48),
|
||||
StanzaHandler(
|
||||
name="message",
|
||||
callback=self._message_received,
|
||||
ns=Namespace.ENCRYPTED,
|
||||
priority=9,
|
||||
),
|
||||
StanzaHandler(
|
||||
name="presence",
|
||||
callback=self._on_presence_received,
|
||||
ns=Namespace.SIGNED,
|
||||
priority=48,
|
||||
),
|
||||
]
|
||||
|
||||
self.own_jid = self._client.get_own_jid()
|
||||
|
||||
self._pgp = PGP()
|
||||
self._store = KeyStore(self._account, self.own_jid, self._log,
|
||||
self._pgp.list_keys)
|
||||
self._store = KeyStore(
|
||||
self._account, self.own_jid, self._log, self._pgp.list_keys
|
||||
)
|
||||
self._always_trust = []
|
||||
self._presence_fingerprint_store = {}
|
||||
|
||||
@@ -112,7 +115,7 @@ class PGPLegacy(BaseModule):
|
||||
key_data = self.get_contact_key_data(jid)
|
||||
if key_data is None:
|
||||
return False
|
||||
key_id = key_data['key_id']
|
||||
key_id = key_data["key_id"]
|
||||
|
||||
announced_fingerprint = self._presence_fingerprint_store.get(jid)
|
||||
if announced_fingerprint is None:
|
||||
@@ -130,24 +133,31 @@ class PGPLegacy(BaseModule):
|
||||
|
||||
fingerprint = self._pgp.verify(properties.status, properties.signed)
|
||||
if fingerprint is None:
|
||||
self._log.info('Presence from %s was signed but no corresponding '
|
||||
'key was found', jid)
|
||||
self._log.info(
|
||||
"Presence from %s was signed but no corresponding " "key was found", jid
|
||||
)
|
||||
return
|
||||
|
||||
self._presence_fingerprint_store[jid] = fingerprint
|
||||
self._log.info('Presence from %s was verified successfully, '
|
||||
'fingerprint: %s', jid, fingerprint)
|
||||
self._log.info(
|
||||
"Presence from %s was verified successfully, " "fingerprint: %s",
|
||||
jid,
|
||||
fingerprint,
|
||||
)
|
||||
|
||||
key_data = self.get_contact_key_data(jid)
|
||||
if key_data is None:
|
||||
self._log.info('No key assigned for contact: %s', jid)
|
||||
self._log.info("No key assigned for contact: %s", jid)
|
||||
return
|
||||
|
||||
if key_data['key_id'] != fingerprint:
|
||||
self._log.warning('Fingerprint mismatch, '
|
||||
'Presence was signed with fingerprint: %s, '
|
||||
'Assigned key fingerprint: %s',
|
||||
fingerprint, key_data['key_id'])
|
||||
if key_data["key_id"] != fingerprint:
|
||||
self._log.warning(
|
||||
"Fingerprint mismatch, "
|
||||
"Presence was signed with fingerprint: %s, "
|
||||
"Assigned key fingerprint: %s",
|
||||
fingerprint,
|
||||
key_data["key_id"],
|
||||
)
|
||||
return
|
||||
|
||||
def _message_received(self, _con, stanza, properties):
|
||||
@@ -155,15 +165,13 @@ class PGPLegacy(BaseModule):
|
||||
return
|
||||
|
||||
remote_jid = properties.remote_jid
|
||||
self._log.info('Message received from: %s', remote_jid)
|
||||
self._log.info("Message received from: %s", remote_jid)
|
||||
|
||||
payload = self._pgp.decrypt(properties.pgp_legacy)
|
||||
prepare_stanza(stanza, payload)
|
||||
|
||||
properties.encrypted = EncryptionData(
|
||||
protocol=ENCRYPTION_NAME,
|
||||
key='Unknown',
|
||||
trust=Trust.UNDECIDED
|
||||
protocol=ENCRYPTION_NAME, key="Unknown", trust=Trust.UNDECIDED
|
||||
)
|
||||
|
||||
def encrypt_message(self, con, message: OutgoingMessage, callback):
|
||||
@@ -181,7 +189,9 @@ class PGPLegacy(BaseModule):
|
||||
always_trust = key_id in self._always_trust
|
||||
self._encrypt(con, message, [key_id, own_key_id], callback, always_trust)
|
||||
|
||||
def _encrypt(self, con, message: OutgoingMessage, keys, callback, always_trust: bool):
|
||||
def _encrypt(
|
||||
self, con, message: OutgoingMessage, keys, callback, always_trust: bool
|
||||
):
|
||||
result = self._pgp.encrypt(message.get_text(), keys, always_trust)
|
||||
encrypted_payload, error = result
|
||||
if error:
|
||||
@@ -194,15 +204,18 @@ class PGPLegacy(BaseModule):
|
||||
message.set_encryption(
|
||||
EncryptionData(
|
||||
protocol=ENCRYPTION_NAME,
|
||||
key='Unknown',
|
||||
key="Unknown",
|
||||
trust=Trust.VERIFIED,
|
||||
)
|
||||
)
|
||||
|
||||
callback(message)
|
||||
|
||||
def _handle_encrypt_error(self, con, error: str, message: OutgoingMessage, keys, callback):
|
||||
if error.startswith('NOT_TRUSTED'):
|
||||
def _handle_encrypt_error(
|
||||
self, con, error: str, message: OutgoingMessage, keys, callback
|
||||
):
|
||||
if error.startswith("NOT_TRUSTED"):
|
||||
|
||||
def on_yes(checked):
|
||||
if checked:
|
||||
self._always_trust.append(keys[0])
|
||||
@@ -219,64 +232,67 @@ class PGPLegacy(BaseModule):
|
||||
@staticmethod
|
||||
def _raise_message_not_sent(con, message: OutgoingMessage, error: str):
|
||||
app.ged.raise_event(
|
||||
MessageNotSent(client=con,
|
||||
jid=str(message.contact.jid),
|
||||
message=message.get_text(),
|
||||
error=_('Encryption error: %s') % error,
|
||||
time=time.time()))
|
||||
MessageNotSent(
|
||||
client=con,
|
||||
jid=str(message.contact.jid),
|
||||
message=message.get_text(),
|
||||
error=_("Encryption error: %s") % error,
|
||||
time=time.time(),
|
||||
)
|
||||
)
|
||||
|
||||
def _create_pgp_legacy_message(self, stanza: Message, payload: str) -> None:
|
||||
stanza.setBody(self._get_info_message())
|
||||
stanza.setTag('x', namespace=Namespace.ENCRYPTED).setData(payload)
|
||||
eme_node = nbxmpp.Node('encryption',
|
||||
attrs={'xmlns': Namespace.EME,
|
||||
'namespace': Namespace.ENCRYPTED})
|
||||
stanza.setTag("x", namespace=Namespace.ENCRYPTED).setData(payload)
|
||||
eme_node = nbxmpp.Node(
|
||||
"encryption",
|
||||
attrs={"xmlns": Namespace.EME, "namespace": Namespace.ENCRYPTED},
|
||||
)
|
||||
stanza.addChild(node=eme_node)
|
||||
|
||||
def sign_presence(self, presence, status):
|
||||
key_data = self.get_own_key_data()
|
||||
if key_data is None:
|
||||
self._log.warning('No own key id found, can’t sign presence')
|
||||
self._log.warning("No own key id found, can’t sign presence")
|
||||
return
|
||||
|
||||
try:
|
||||
result = self._pgp.sign(status, key_data['key_id'])
|
||||
result = self._pgp.sign(status, key_data["key_id"])
|
||||
except SignError as error:
|
||||
self._log.warning('Sign Error: %s', error)
|
||||
self._log.warning("Sign Error: %s", error)
|
||||
return
|
||||
# self._log.debug(self._pgp.sign.cache_info())
|
||||
self._log.info('Presence signed')
|
||||
presence.setTag(Namespace.SIGNED + ' x').setData(result)
|
||||
self._log.info("Presence signed")
|
||||
presence.setTag(Namespace.SIGNED + " x").setData(result)
|
||||
|
||||
@staticmethod
|
||||
def _get_info_message():
|
||||
msg = '[This message is *encrypted* (See :XEP:`27`)]'
|
||||
lang = os.getenv('LANG')
|
||||
if lang is not None and not lang.startswith('en'):
|
||||
msg = "[This message is *encrypted* (See :XEP:`27`)]"
|
||||
lang = os.getenv("LANG")
|
||||
if lang is not None and not lang.startswith("en"):
|
||||
# we're not english: one in locale and one en
|
||||
msg = _('[This message is *encrypted* (See :XEP:`27`)]') + \
|
||||
' (' + msg + ')'
|
||||
msg = _("[This message is *encrypted* (See :XEP:`27`)]") + " (" + msg + ")"
|
||||
return msg
|
||||
|
||||
def _get_key_ids(self, jid):
|
||||
key_data = self.get_contact_key_data(jid)
|
||||
if key_data is None:
|
||||
raise NoKeyIdFound('No key id found for %s' % jid)
|
||||
key_id = key_data['key_id']
|
||||
raise NoKeyIdFound("No key id found for %s" % jid)
|
||||
key_id = key_data["key_id"]
|
||||
|
||||
own_key_data = self.get_own_key_data()
|
||||
if own_key_data is None:
|
||||
raise NoKeyIdFound('Own key id not found')
|
||||
own_key_id = own_key_data['key_id']
|
||||
raise NoKeyIdFound("Own key id not found")
|
||||
own_key_id = own_key_data["key_id"]
|
||||
return key_id, own_key_id
|
||||
|
||||
@staticmethod
|
||||
def _cleanup_stanza(message: OutgoingMessage) -> None:
|
||||
''' We make sure only allowed tags are in the stanza '''
|
||||
"""We make sure only allowed tags are in the stanza"""
|
||||
original_stanza = message.get_stanza()
|
||||
stanza = nbxmpp.Message(
|
||||
to=original_stanza.getTo(),
|
||||
typ=original_stanza.getType())
|
||||
to=original_stanza.getTo(), typ=original_stanza.getType()
|
||||
)
|
||||
stanza.setID(original_stanza.getID())
|
||||
stanza.setThread(original_stanza.getThread())
|
||||
for tag, ns in ALLOWED_TAGS:
|
||||
@@ -286,8 +302,9 @@ class PGPLegacy(BaseModule):
|
||||
message.set_stanza(stanza)
|
||||
|
||||
def encrypt_file(self, file, callback):
|
||||
thread = threading.Thread(target=self._encrypt_file_thread,
|
||||
args=(file, callback))
|
||||
thread = threading.Thread(
|
||||
target=self._encrypt_file_thread, args=(file, callback)
|
||||
)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
@@ -299,8 +316,7 @@ class PGPLegacy(BaseModule):
|
||||
return
|
||||
|
||||
stream = open(file.path, "rb")
|
||||
encrypted = self._pgp.encrypt_file(stream,
|
||||
[key_id, own_key_id])
|
||||
encrypted = self._pgp.encrypt_file(stream, [key_id, own_key_id])
|
||||
stream.close()
|
||||
|
||||
if not encrypted:
|
||||
@@ -308,7 +324,7 @@ class PGPLegacy(BaseModule):
|
||||
return
|
||||
|
||||
file.size = len(encrypted.data)
|
||||
file.set_uri_transform_func(lambda uri: '%s.pgp' % uri)
|
||||
file.set_uri_transform_func(lambda uri: "%s.pgp" % uri)
|
||||
file.set_encrypted_data(encrypted.data)
|
||||
GLib.idle_add(callback, file)
|
||||
|
||||
@@ -316,5 +332,6 @@ class PGPLegacy(BaseModule):
|
||||
def _on_file_encryption_error(error):
|
||||
app.ged.raise_event(PGPFileEncryptionError(error=error))
|
||||
|
||||
|
||||
def get_instance(*args, **kwargs):
|
||||
return PGPLegacy(*args, **kwargs), 'PGPLegacy'
|
||||
return PGPLegacy(*args, **kwargs), "PGPLegacy"
|
||||
|
||||
@@ -21,8 +21,8 @@ from nbxmpp.namespaces import Namespace
|
||||
|
||||
|
||||
def prepare_stanza(stanza, plaintext):
|
||||
delete_nodes(stanza, 'encrypted', Namespace.ENCRYPTED)
|
||||
delete_nodes(stanza, 'body')
|
||||
delete_nodes(stanza, "encrypted", Namespace.ENCRYPTED)
|
||||
delete_nodes(stanza, "body")
|
||||
stanza.setBody(plaintext)
|
||||
|
||||
|
||||
@@ -34,16 +34,16 @@ def delete_nodes(stanza, name, namespace=None):
|
||||
|
||||
def find_gpg():
|
||||
def _search(binary):
|
||||
if os.name == 'nt':
|
||||
gpg_cmd = binary + ' -h >nul 2>&1'
|
||||
if os.name == "nt":
|
||||
gpg_cmd = binary + " -h >nul 2>&1"
|
||||
else:
|
||||
gpg_cmd = binary + ' -h >/dev/null 2>&1'
|
||||
gpg_cmd = binary + " -h >/dev/null 2>&1"
|
||||
if subprocess.call(gpg_cmd, shell=True):
|
||||
return False
|
||||
return True
|
||||
|
||||
if _search('gpg2'):
|
||||
return 'gpg2'
|
||||
if _search("gpg2"):
|
||||
return "gpg2"
|
||||
|
||||
if _search('gpg'):
|
||||
return 'gpg'
|
||||
if _search("gpg"):
|
||||
return "gpg"
|
||||
|
||||
111
pgp/plugin.py
111
pgp/plugin.py
@@ -14,29 +14,29 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with PGP Gajim Plugin. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
from functools import partial
|
||||
|
||||
from packaging.version import Version as V
|
||||
|
||||
from gajim.common import app
|
||||
from gajim.common import ged
|
||||
from gajim.gtk.dialogs import ConfirmationCheckDialog
|
||||
from gajim.gtk.dialogs import DialogButton
|
||||
from gajim.gtk.dialogs import SimpleDialog
|
||||
from gajim.plugins import GajimPlugin
|
||||
from gajim.plugins.plugins_i18n import _
|
||||
|
||||
from gajim.gtk.dialogs import SimpleDialog
|
||||
from gajim.gtk.dialogs import DialogButton
|
||||
from gajim.gtk.dialogs import ConfirmationCheckDialog
|
||||
|
||||
from pgp.gtk.key import KeyDialog
|
||||
from pgp.gtk.config import PGPConfigDialog
|
||||
from pgp.exceptions import KeyMismatch
|
||||
from pgp.gtk.config import PGPConfigDialog
|
||||
from pgp.gtk.key import KeyDialog
|
||||
from pgp.modules.util import find_gpg
|
||||
|
||||
ENCRYPTION_NAME = 'PGP'
|
||||
ENCRYPTION_NAME = "PGP"
|
||||
|
||||
log = logging.getLogger('gajim.p.pgplegacy')
|
||||
log = logging.getLogger("gajim.p.pgplegacy")
|
||||
|
||||
ERROR = False
|
||||
try:
|
||||
@@ -51,29 +51,29 @@ else:
|
||||
# on a much lower version number than gnupg
|
||||
# Also we need at least python-gnupg 0.3.8
|
||||
v_gnupg = gnupg.__version__
|
||||
if V(v_gnupg) < V('0.3.8') or V(v_gnupg) > V('1.0.0'):
|
||||
log.error('We need python-gnupg >= 0.3.8')
|
||||
if V(v_gnupg) < V("0.3.8") or V(v_gnupg) > V("1.0.0"):
|
||||
log.error("We need python-gnupg >= 0.3.8")
|
||||
ERROR = True
|
||||
|
||||
ERROR_MSG = None
|
||||
BINARY = find_gpg()
|
||||
log.info('Found GPG executable: %s', BINARY)
|
||||
log.info("Found GPG executable: %s", BINARY)
|
||||
|
||||
if BINARY is None or ERROR:
|
||||
if os.name == 'nt':
|
||||
ERROR_MSG = _('Please install GnuPG / Gpg4win')
|
||||
if os.name == "nt":
|
||||
ERROR_MSG = _("Please install GnuPG / Gpg4win")
|
||||
else:
|
||||
ERROR_MSG = _('Please install python-gnupg and gnupg')
|
||||
ERROR_MSG = _("Please install python-gnupg and gnupg")
|
||||
else:
|
||||
from pgp.modules import pgp_legacy
|
||||
from pgp.backend.python_gnupg import PGP
|
||||
from pgp.modules import pgp_legacy
|
||||
|
||||
|
||||
class PGPPlugin(GajimPlugin):
|
||||
|
||||
def init(self):
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
self.description = _('PGP encryption as per XEP-0027')
|
||||
self.description = _("PGP encryption as per XEP-0027")
|
||||
if ERROR_MSG:
|
||||
self.activatable = False
|
||||
self.config_dialog = None
|
||||
@@ -84,30 +84,26 @@ class PGPPlugin(GajimPlugin):
|
||||
self.encryption_name = ENCRYPTION_NAME
|
||||
self.allow_zeroconf = True
|
||||
self.gui_extension_points = {
|
||||
'encrypt' + ENCRYPTION_NAME: (self._encrypt_message, None),
|
||||
'send_message' + ENCRYPTION_NAME: (
|
||||
self._before_sendmessage, None),
|
||||
'encryption_dialog' + ENCRYPTION_NAME: (
|
||||
self._on_encryption_dialog, None),
|
||||
'encryption_state' + ENCRYPTION_NAME: (
|
||||
self._encryption_state, None),
|
||||
'send-presence': (self._on_send_presence, None),
|
||||
"encrypt" + ENCRYPTION_NAME: (self._encrypt_message, None),
|
||||
"send_message" + ENCRYPTION_NAME: (self._before_sendmessage, None),
|
||||
"encryption_dialog" + ENCRYPTION_NAME: (self._on_encryption_dialog, None),
|
||||
"encryption_state" + ENCRYPTION_NAME: (self._encryption_state, None),
|
||||
"send-presence": (self._on_send_presence, None),
|
||||
}
|
||||
|
||||
self.modules = [pgp_legacy]
|
||||
|
||||
self.events_handlers = {
|
||||
'pgp-not-trusted': (ged.PRECORE, self._on_not_trusted),
|
||||
'pgp-file-encryption-error': (ged.PRECORE,
|
||||
self._on_file_encryption_error),
|
||||
"pgp-not-trusted": (ged.PRECORE, self._on_not_trusted),
|
||||
"pgp-file-encryption-error": (ged.PRECORE, self._on_file_encryption_error),
|
||||
}
|
||||
|
||||
encoding = 'utf8' if sys.platform == 'linux' else None
|
||||
encoding = "utf8" if sys.platform == "linux" else None
|
||||
self._pgp = PGP(BINARY, encoding=encoding)
|
||||
|
||||
@staticmethod
|
||||
def get_pgp_module(account):
|
||||
return app.get_client(account).get_module('PGPLegacy')
|
||||
return app.get_client(account).get_module("PGPLegacy")
|
||||
|
||||
def activate(self):
|
||||
pass
|
||||
@@ -121,8 +117,8 @@ class PGPPlugin(GajimPlugin):
|
||||
|
||||
@staticmethod
|
||||
def _encryption_state(_chat_control, state):
|
||||
state['visible'] = True
|
||||
state['authenticated'] = True
|
||||
state["visible"] = True
|
||||
state["authenticated"] = True
|
||||
|
||||
def _on_encryption_dialog(self, chat_control):
|
||||
account = chat_control.account
|
||||
@@ -137,17 +133,20 @@ class PGPPlugin(GajimPlugin):
|
||||
@staticmethod
|
||||
def _on_not_trusted(event):
|
||||
ConfirmationCheckDialog(
|
||||
_('Untrusted PGP key'),
|
||||
_('The PGP key used to encrypt this chat is not '
|
||||
'trusted. Do you really want to encrypt this '
|
||||
'message?'),
|
||||
_('_Do not ask me again'),
|
||||
[DialogButton.make('Cancel',
|
||||
text=_('_No'),
|
||||
callback=event.on_no),
|
||||
DialogButton.make('OK',
|
||||
text=_('_Encrypt Anyway'),
|
||||
callback=event.on_yes)]).show()
|
||||
_("Untrusted PGP key"),
|
||||
_(
|
||||
"The PGP key used to encrypt this chat is not "
|
||||
"trusted. Do you really want to encrypt this "
|
||||
"message?"
|
||||
),
|
||||
_("_Do not ask me again"),
|
||||
[
|
||||
DialogButton.make("Cancel", text=_("_No"), callback=event.on_no),
|
||||
DialogButton.make(
|
||||
"OK", text=_("_Encrypt Anyway"), callback=event.on_yes
|
||||
),
|
||||
],
|
||||
).show()
|
||||
|
||||
@staticmethod
|
||||
def _before_sendmessage(chat_control):
|
||||
@@ -156,24 +155,30 @@ class PGPPlugin(GajimPlugin):
|
||||
|
||||
client = app.get_client(account)
|
||||
try:
|
||||
valid = client.get_module('PGPLegacy').has_valid_key_assigned(jid)
|
||||
valid = client.get_module("PGPLegacy").has_valid_key_assigned(jid)
|
||||
except KeyMismatch as announced_key_id:
|
||||
SimpleDialog(
|
||||
_('PGP Key mismatch'),
|
||||
_('The contact\'s key (%s) <b>does not match</b> the key '
|
||||
'assigned in Gajim.') % announced_key_id)
|
||||
_("PGP Key mismatch"),
|
||||
_(
|
||||
"The contact's key (%s) <b>does not match</b> the key "
|
||||
"assigned in Gajim."
|
||||
)
|
||||
% announced_key_id,
|
||||
)
|
||||
chat_control.sendmessage = False
|
||||
return
|
||||
|
||||
if not valid:
|
||||
SimpleDialog(
|
||||
_('No OpenPGP key assigned'),
|
||||
_('No OpenPGP key is assigned to this contact.'))
|
||||
_("No OpenPGP key assigned"),
|
||||
_("No OpenPGP key is assigned to this contact."),
|
||||
)
|
||||
chat_control.sendmessage = False
|
||||
elif client.get_module('PGPLegacy').get_own_key_data() is None:
|
||||
elif client.get_module("PGPLegacy").get_own_key_data() is None:
|
||||
SimpleDialog(
|
||||
_('No OpenPGP key assigned'),
|
||||
_('No OpenPGP key is assigned to your account.'))
|
||||
_("No OpenPGP key assigned"),
|
||||
_("No OpenPGP key is assigned to your account."),
|
||||
)
|
||||
chat_control.sendmessage = False
|
||||
|
||||
def _encrypt_message(self, conn, event, callback):
|
||||
@@ -185,4 +190,4 @@ class PGPPlugin(GajimPlugin):
|
||||
|
||||
@staticmethod
|
||||
def _on_file_encryption_error(event):
|
||||
SimpleDialog(_('Error'), event.error)
|
||||
SimpleDialog(_("Error"), event.error)
|
||||
|
||||
Reference in New Issue
Block a user