From 245be4132fc87e9cfce5d4241198bfa8b2dfa84a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= <philipp@hoerist.com> Date: Fri, 8 Mar 2019 20:24:36 +0100 Subject: [PATCH] [omemo] Improve logging --- omemo/backend/devices.py | 17 ++++---- omemo/backend/liteaxolotlstore.py | 13 +++--- omemo/backend/state.py | 60 ++++++++++++--------------- omemo/backend/util.py | 2 +- omemo/modules/omemo.py | 68 +++++++++++++------------------ 5 files changed, 68 insertions(+), 92 deletions(-) diff --git a/omemo/backend/devices.py b/omemo/backend/devices.py index e2bcb359..335a354a 100644 --- a/omemo/backend/devices.py +++ b/omemo/backend/devices.py @@ -14,15 +14,12 @@ # 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/>. -import logging from collections import defaultdict from gajim.common import app from omemo.backend.util import UNACKNOWLEDGED_COUNT -log = logging.getLogger('gajim.plugin_system.omemo') - class DeviceManager: def __init__(self): @@ -34,10 +31,10 @@ class DeviceManager: raise ValueError('No own device found') self.__own_device = (reg_id % 2147483646) + 1 self.add_device(self._own_jid, self.__own_device) - log.info('Our device id: %s', self.__own_device) + self._log.info('Our device id: %s', self.__own_device) for jid, device in self._storage.getActiveDeviceTuples(): - log.info('Load device from storage: %s - %s', jid, device) + self._log.info('Load device from storage: %s - %s', jid, device) self.add_device(jid, device) def update_devicelist(self, jid, devicelist): @@ -46,20 +43,20 @@ class DeviceManager: continue count = self._storage.getUnacknowledgedCount(jid, device) if count > UNACKNOWLEDGED_COUNT: - log.warning('Ignore device because of %s unacknowledged' - ' messages: %s %s', count, jid, device) + self._log.warning('Ignore device because of %s unacknowledged' + ' messages: %s %s', count, jid, device) devicelist.remove(device) self.__device_store[jid] = set(devicelist) - log.info('Saved devices for %s', jid) + self._log.info('Saved devices for %s', jid) self._storage.setActiveState(jid, devicelist) def add_muc_member(self, room_jid, jid): - log.info('Saved MUC member %s %s', room_jid, jid) + self._log.info('Saved MUC member %s %s', room_jid, jid) self.__muc_member_store[room_jid].add(jid) def remove_muc_member(self, room_jid, jid): - log.info('Removed MUC member %s %s', room_jid, jid) + self._log.info('Removed MUC member %s %s', room_jid, jid) self.__muc_member_store[room_jid].discard(jid) def get_muc_members(self, room_jid, without_self=True): diff --git a/omemo/backend/liteaxolotlstore.py b/omemo/backend/liteaxolotlstore.py index a3b1f3a4..400ab26c 100644 --- a/omemo/backend/liteaxolotlstore.py +++ b/omemo/backend/liteaxolotlstore.py @@ -16,7 +16,6 @@ # along with OMEMO Gajim Plugin. If not, see <http://www.gnu.org/licenses/>. import time -import logging import sqlite3 from collections import namedtuple @@ -36,9 +35,6 @@ from omemo.backend.util import IdentityKeyExtended from omemo.backend.util import DEFAULT_PREKEY_AMOUNT -log = logging.getLogger('gajim.plugin_system.omemo') - - def _convert_to_string(text): return text.decode() @@ -59,7 +55,8 @@ sqlite3.register_converter('session_record', _convert_record) class LiteAxolotlStore(AxolotlStore): - def __init__(self, db_path): + def __init__(self, db_path, log): + self._log = log self._con = sqlite3.connect(db_path, detect_types=sqlite3.PARSE_COLNAMES) self._con.text_factory = bytes @@ -77,7 +74,7 @@ class LiteAxolotlStore(AxolotlStore): self._con.commit() if not self.getLocalRegistrationId(): - log.info("Generating OMEMO keys") + self._log.info("Generating OMEMO keys") self._generate_axolotl_keys() @staticmethod @@ -318,7 +315,7 @@ class LiteAxolotlStore(AxolotlStore): return result is not None def deleteSession(self, recipientId, deviceId): - log.info('Delete session for %s %s', recipientId, deviceId) + self._log.info('Delete session for %s %s', recipientId, deviceId) query = "DELETE FROM sessions WHERE recipient_id = ? AND device_id = ?" self._con.execute(query, (recipientId, deviceId)) self._con.commit() @@ -551,7 +548,7 @@ class LiteAxolotlStore(AxolotlStore): def setIdentityLastSeen(self, recipient_id, identity_key): timestamp = int(time.time()) identity_key = identity_key.getPublicKey().serialize() - log.info('Set last seen for %s %s', recipient_id, timestamp) + self._log.info('Set last seen for %s %s', recipient_id, timestamp) query = '''UPDATE identities SET timestamp = ? WHERE recipient_id = ? AND public_key = ?''' self._con.execute(query, (timestamp, recipient_id, identity_key)) diff --git a/omemo/backend/state.py b/omemo/backend/state.py index 3f0c1dfd..612d0c98 100644 --- a/omemo/backend/state.py +++ b/omemo/backend/state.py @@ -15,7 +15,6 @@ # 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/>. -import logging import time from collections import defaultdict @@ -48,23 +47,20 @@ from omemo.backend.util import SPK_ARCHIVE_TIME from omemo.backend.util import UNACKNOWLEDGED_COUNT -log = logging.getLogger('gajim.plugin_system.omemo') - - class OmemoState(DeviceManager): def __init__(self, own_jid, db_path, account, xmpp_con): self._account = account self._own_jid = own_jid + self._log = xmpp_con._log self._session_ciphers = defaultdict(dict) - self._storage = LiteAxolotlStore(db_path) + self._storage = LiteAxolotlStore(db_path, self._log) DeviceManager.__init__(self) self.xmpp_con = xmpp_con - log.info('%s => %s PreKeys available', - self._account, - self._storage.getPreKeyCount()) + self._log.info('%s PreKeys available', + self._storage.getPreKeyCount()) def build_session(self, jid, device_id, bundle): session = SessionBuilder(self._storage, self._storage, self._storage, @@ -122,13 +118,13 @@ class OmemoState(DeviceManager): def decrypt_message(self, omemo_message, jid): if omemo_message.sid == self.own_device: - log.info('Received previously sent message by us') + self._log.info('Received previously sent message by us') raise SelfMessage try: encrypted_key, prekey = omemo_message.keys[self.own_device] except KeyError: - log.info('Received message not for our device') + self._log.info('Received message not for our device') raise MessageNotForDevice try: @@ -140,23 +136,23 @@ class OmemoState(DeviceManager): jid, omemo_message.sid, encrypted_key) except SenderNotTrusted: - log.info('Sender not trusted, ignore message') + self._log.info('Sender not trusted, ignore message') raise except DuplicateMessageException: - log.info('Received duplicated message') + self._log.info('Received duplicated message') raise DuplicateMessage except Exception as error: - log.warning(error) + self._log.warning(error) raise DecryptionFailed if omemo_message.payload is None: - log.debug("Decrypted Key Exchange Message") + self._log.debug("Decrypted Key Exchange Message") raise KeyExchangeMessage result = aes_decrypt(key, omemo_message.iv, omemo_message.payload) - log.debug("Decrypted Message => %s", result) + self._log.debug("Decrypted Message => %s", result) return result, fingerprint def _get_whisper_message(self, jid, device, key): @@ -169,7 +165,7 @@ class OmemoState(DeviceManager): try: devices_for_encryption = self.get_devices_for_encryption(jid) except NoDevicesFound: - log.warning('No devices for encryption found for: %s', jid) + self._log.warning('No devices for encryption found for: %s', jid) return result = aes_encrypt(plaintext) @@ -178,29 +174,29 @@ class OmemoState(DeviceManager): for jid_, device in devices_for_encryption: count = self._storage.getUnacknowledgedCount(jid_, device) if count >= UNACKNOWLEDGED_COUNT: - log.warning('Set device inactive %s because of %s ' - 'unacknowledged messages', device, count) + self._log.warning('Set device inactive %s because of %s ' + 'unacknowledged messages', device, count) self.remove_device(jid_, device) try: whisper_messages[jid_][device] = self._get_whisper_message( jid_, device, result.key) except Exception: - log.exception('Failed to encrypt') + self._log.exception('Failed to encrypt') continue recipients = set(whisper_messages.keys()) if jid != self._own_jid: recipients -= set([self._own_jid]) if not recipients: - log.error('Encrypted keys empty') + self._log.error('Encrypted keys empty') return encrypted_keys = {} for jid_ in whisper_messages: encrypted_keys.update(whisper_messages[jid_]) - log.debug('Finished encrypting message') + self._log.debug('Finished encrypting message') return OMEMOMessage(sid=self.own_device, keys=encrypted_keys, iv=result.iv, @@ -213,14 +209,14 @@ class OmemoState(DeviceManager): whisper_messages[jid][device] = self._get_whisper_message( jid, device, get_new_key()) except Exception: - log.exception('Failed to encrypt') + self._log.exception('Failed to encrypt') continue if not whisper_messages[jid]: - log.error('Encrypted keys empty') + self._log.error('Encrypted keys empty') return - log.debug('Finished Key Transport message') + self._log.debug('Finished Key Transport message') return OMEMOMessage(sid=self.own_device, keys=whisper_messages[jid], iv=get_new_iv(), @@ -237,8 +233,8 @@ class OmemoState(DeviceManager): for dev in known_devices if not self._storage.containsSession(jid, dev)] if missing_devices: - log.info('%s => Missing device sessions for %s: %s', - self._account, jid, missing_devices) + self._log.info('Missing device sessions for %s: %s', + jid, missing_devices) return missing_devices def _get_session_cipher(self, jid, device_id): @@ -262,8 +258,7 @@ class OmemoState(DeviceManager): session_cipher = self._get_session_cipher(jid, device) - log.info('%s => Process pre key message from %s', - self._account, jid) + self._log.info('Process pre key message from %s', jid) key = session_cipher.decryptPkmsg(pre_key_message) fingerprint = get_fingerprint(identity_key) @@ -275,7 +270,7 @@ class OmemoState(DeviceManager): def _process_message(self, jid, device, key): message = WhisperMessage(serialized=key) - log.info('%s => Process message from %s', self._account, jid) + self._log.info('Process message from %s', jid) session_cipher = self._get_session_cipher(jid, device) key = session_cipher.decryptMsg(message, textMsg=False) @@ -299,7 +294,7 @@ class OmemoState(DeviceManager): if pre_key_count < MIN_PREKEY_AMOUNT: missing_count = DEFAULT_PREKEY_AMOUNT - pre_key_count self._storage.generateNewPreKeys(missing_count) - log.info('%s => %s PreKeys created', self._account, missing_count) + self._log.info('%s PreKeys created', missing_count) def _cycle_signed_pre_key(self, ik_pair): # Publish every SPK_CYCLE_TIME a new SignedPreKey @@ -311,8 +306,7 @@ class OmemoState(DeviceManager): spk = KeyHelper.generateSignedPreKey( ik_pair, self._storage.getNextSignedPreKeyId()) self._storage.storeSignedPreKey(spk.getId(), spk) - log.debug('%s => New SignedPreKey created, because none existed', - self._account) + self._log.debug('New SignedPreKey created, because none existed') # if SPK_CYCLE_TIME is reached, generate a new SignedPreKey now = int(time.time()) @@ -323,7 +317,7 @@ class OmemoState(DeviceManager): spk = KeyHelper.generateSignedPreKey( ik_pair, self._storage.getNextSignedPreKeyId()) self._storage.storeSignedPreKey(spk.getId(), spk) - log.debug('%s => Cycled SignedPreKey', self._account) + self._log.debug('Cycled SignedPreKey') # Delete all SignedPreKeys that are older than SPK_ARCHIVE_TIME timestamp = now - SPK_ARCHIVE_TIME diff --git a/omemo/backend/util.py b/omemo/backend/util.py index 1a440a53..8fd008b6 100644 --- a/omemo/backend/util.py +++ b/omemo/backend/util.py @@ -16,6 +16,7 @@ import binascii import textwrap +from logging import LoggerAdapter from enum import IntEnum from axolotl.identitykey import IdentityKey @@ -53,4 +54,3 @@ class IdentityKeyExtended(IdentityKey): def get_fingerprint(self, formatted=False): return get_fingerprint(self, formatted=formatted) - \ No newline at end of file diff --git a/omemo/modules/omemo.py b/omemo/modules/omemo.py index 1f4fa035..75ca1147 100644 --- a/omemo/modules/omemo.py +++ b/omemo/modules/omemo.py @@ -87,7 +87,7 @@ class OMEMO(BaseModule): ] def __init__(self, con): - BaseModule.__init__(self, con) + BaseModule.__init__(self, con, log) self.handlers = [ StanzaHandler(name='message', @@ -131,7 +131,7 @@ class OMEMO(BaseModule): return room_jid in self._omemo_groupchats def on_signed_in(self): - log.info('%s => Announce Support after Sign In', self._account) + self._log.info('Announce Support after Sign In') self._query_for_bundles = [] self.set_bundle() self.request_devicelist() @@ -144,8 +144,7 @@ class OMEMO(BaseModule): helpers.update_optional_features(self._account) if app.account_is_connected(self._account): - log.info('%s => Announce Support after Plugin Activation', - self._account) + self._log.info('Announce Support after Plugin Activation') self._query_for_bundles = [] self.set_bundle() self.request_devicelist() @@ -197,11 +196,12 @@ class OMEMO(BaseModule): def _send_key_transport_message(self, typ, jid, devices): omemo_message = self.backend.encrypt_key_transport(jid, devices) if omemo_message is None: - log.warning('Key transport message to %s (%s) failed', jid, devices) + self._log.warning('Key transport message to %s (%s) failed', + jid, devices) return transport_message = get_key_transport_message(typ, jid, omemo_message) - log.info('Send key transport message %s (%s)', jid, devices) + self._log.info('Send key transport message %s (%s)', jid, devices) self._con.connection.send(transport_message) def _message_received(self, _con, stanza, properties): @@ -218,7 +218,7 @@ class OMEMO(BaseModule): if from_jid is None: return - log.info('%s => Message received from: %s', self._account, from_jid) + self._log.info('Message received from: %s', from_jid) try: plaintext, fingerprint = self.backend.decrypt_message( @@ -233,8 +233,7 @@ class OMEMO(BaseModule): fingerprint = self.backend.own_fingerprint del self._muc_temp_store[properties.omemo.payload] else: - log.warning("%s => Can't decrypt own GroupChat Message", - self._account) + self._log.warning("Can't decrypt own GroupChat Message") return else: raise NodeProcessed @@ -258,23 +257,20 @@ class OMEMO(BaseModule): if contact is not None: return JID(contact.jid).getBare() - log.info('%s => Groupchat: Last resort trying to ' - 'find SID in DB', self._account) + self._log.info('Groupchat: Last resort trying to find SID in DB') from_jid = self.backend.storage.getJidFromDevice(properties.omemo.sid) if not from_jid: - log.error("%s => Can't decrypt GroupChat Message " - "from %s", self._account, resource) + self._log.error("Can't decrypt GroupChat Message from %s", resource) return return from_jid def _process_mam_message(self, properties): - log.info('%s => Message received, archive: %s', - self._account, properties.mam.archive) + self._log.info('Message received, archive: %s', properties.mam.archive) from_jid = properties.jid.getBare() if properties.from_muc: - log.info('%s => MUC MAM Message received', self._account) + self._log.info('MUC MAM Message received') if properties.muc_user.jid is None: - log.info('%s => No real jid found', self._account) + self._log.info('No real jid found') return from_jid = properties.muc_user.jid.getBare() return from_jid @@ -304,7 +300,7 @@ class OMEMO(BaseModule): if room in self._omemo_groupchats: if not self.is_contact_in_roster(jid): # Query Devicelists from JIDs not in our Roster - log.info('%s not in Roster, query devicelist...', jid) + self._log.info('%s not in Roster, query devicelist...', jid) self.request_devicelist(jid) if properties.is_muc_self_presence: @@ -312,7 +308,7 @@ class OMEMO(BaseModule): # non-anonymous Room (Full JID) self._omemo_groupchats.add(room) - log.info('OMEMO capable Room found: %s', room) + self._log.info('OMEMO capable Room found: %s', room) self.get_affiliation_list(room) def get_affiliation_list(self, room_jid): @@ -325,21 +321,21 @@ class OMEMO(BaseModule): def _on_affiliations_received(self, result, room_jid): if is_error_result(result): - log.info('Affiliation request failed: %s', result) + self._log.info('Affiliation request failed: %s', result) return for user_jid in result.users: try: jid = helpers.parse_jid(user_jid) except helpers.InvalidFormat: - log.warning('Invalid JID: %s, ignoring it', user_jid) + self._log.warning('Invalid JID: %s, ignoring it', user_jid) continue self.backend.add_muc_member(room_jid, jid) if not self.is_contact_in_roster(jid): # Query Devicelists from JIDs not in our Roster - log.info('%s not in Roster, query devicelist...', jid) + self._log.info('%s not in Roster, query devicelist...', jid) self.request_devicelist(jid) def is_contact_in_roster(self, jid): @@ -355,7 +351,7 @@ class OMEMO(BaseModule): status_codes = event.status_codes or [] if StatusCode.CONFIG_NON_ANONYMOUS in status_codes: self._omemo_groupchats.add(room) - log.info('Room config change: non-anonymous') + self._log.info('Room config change: non-anonymous') def _check_for_missing_sessions(self, jid): devices_without_session = self.backend.devices_without_sessions(jid) @@ -413,8 +409,7 @@ class OMEMO(BaseModule): self.backend.own_device) def request_bundle(self, jid, device_id): - log.info('%s => Fetch device bundle %s %s', - self._account, device_id, jid) + self._log.info('Fetch device bundle %s %s', device_id, jid) self._nbxmpp('OMEMO').request_bundle( jid, @@ -425,13 +420,12 @@ class OMEMO(BaseModule): def _bundle_received(self, bundle, user_data): jid, device_id = user_data if is_error_result(bundle): - log.info('%s => Bundle request failed: %s %s: %s', - self._account, jid, device_id, bundle) + self._log.info('Bundle request failed: %s %s: %s', + jid, device_id, bundle) return self.backend.build_session(jid, device_id, bundle) - log.info('%s => session created for: %s', - self._account, jid) + self._log.info('Session created for: %s', jid) # TODO: In MUC we should send a groupchat message self._send_key_transport_message('chat', jid, [device_id]) @@ -447,8 +441,7 @@ class OMEMO(BaseModule): devicelist_ = set([self.backend.own_device]) if devicelist is not None: devicelist_.add(devicelist) - log.info('%s => Publishing own devicelist: %s', - self._account, devicelist_) + self._log.info('Publishing own devicelist: %s', devicelist_) self._nbxmpp('OMEMO').set_devicelist(devicelist_) def clear_devicelist(self): @@ -470,8 +463,7 @@ class OMEMO(BaseModule): def _devicelist_received(self, devicelist, jid): if is_error_result(devicelist): - log.info('%s => Devicelist request failed: %s %s', - self._account, jid, devicelist) + self._log.info('Devicelist request failed: %s %s', jid, devicelist) devicelist = [] self._process_devicelist_update(jid, devicelist) @@ -489,8 +481,7 @@ class OMEMO(BaseModule): if own_devices: jid = self._own_jid - log.info('%s => Received device list for %s: %s', - self._account, jid, devicelist) + self._log.info('Received device list for %s: %s', jid, devicelist) # Pass a copy, we need the full list for potential set_devicelist() self.backend.update_devicelist(jid, list(devicelist)) @@ -505,13 +496,10 @@ class OMEMO(BaseModule): self._check_for_missing_sessions(jid) - @staticmethod - def _debug_print_stanza(stanza): - log.debug('-'*15) + def _debug_print_stanza(self, stanza): stanzastr = '\n' + stanza.__str__(fancy=True) stanzastr = stanzastr[0:-1] - log.debug(stanzastr) - log.debug('-'*15) + self._log.debug(stanzastr) def get_instance(*args, **kwargs): -- GitLab