From 0667ac8c5f441facf2c94a1fe9ad339c8d840bea Mon Sep 17 00:00:00 2001 From: jesopo Date: Thu, 20 Feb 2020 14:56:04 +0000 Subject: [PATCH] add option to encrypt channel_log log files line-by-line --- docs/bot.conf.example | 3 +++ modules/channel_log.py | 14 ++++++++++---- src/utils/security.py | 27 ++++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/docs/bot.conf.example b/docs/bot.conf.example index 6c7808dc..7b1ad465 100644 --- a/docs/bot.conf.example +++ b/docs/bot.conf.example @@ -33,6 +33,9 @@ module-whitelist = # path to an external directory for modules to be found in external-modules = +# optional PEM public key used to encrypt channel_log log lines +log-key = + # https://openweathermap.org/api openweathermap-api-key = diff --git a/modules/channel_log.py b/modules/channel_log.py index 8344e9cd..a15d51f7 100644 --- a/modules/channel_log.py +++ b/modules/channel_log.py @@ -26,10 +26,16 @@ class Module(ModuleManager.BaseModule): return self.data_directory("%s/%s.log" % (server_name, sanitised_name)) def _log(self, server, channel, line): if self._enabled(server, channel): - with open(self._file(str(server), str(channel)), "a") as log: - timestamp = utils.datetime.format.datetime_human( - datetime.datetime.now()) - log.write("%s %s\n" % (timestamp, line)) + timestamp = utils.datetime.format.datetime_human( + datetime.datetime.now()) + log_line = "%s %s" % (timestamp, line) + + if "log-key" in self.bot.config: + log_line = "\x02%s" % utils.security.a_encrypt( + self.bot.config["log-key"], log_line) + + with open(self._file(str(server), str(channel)), "a") as log_file: + log_file.write("%s\n" % log_line) @utils.hook("formatted.message.channel") @utils.hook("formatted.notice.channel") diff --git a/src/utils/security.py b/src/utils/security.py index 78a54b5c..bb21a523 100644 --- a/src/utils/security.py +++ b/src/utils/security.py @@ -1,4 +1,4 @@ -import hmac, socket, ssl, typing +import base64, hmac, socket, ssl, typing def ssl_context(cert: str=None, key: str=None, verify: bool=True ) -> ssl.SSLContext: @@ -24,3 +24,28 @@ def ssl_wrap(sock: socket.socket, cert: str=None, key: str=None, def constant_time_compare(a: typing.AnyStr, b: typing.AnyStr) -> bool: return hmac.compare_digest(a, b) + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import padding + +def a_encrypt(key_filename: str, data: str): + with open(key_filename, "rb") as key_file: + key_content = key_file.read() + key = serialization.load_pem_public_key( + key_content, backend=default_backend()) + out = key.encrypt(data.encode("utf8"), padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA256()), + algorithm=hashes.SHA256(), label=None)) + return base64.b64encode(out).decode("iso-8859-1") + +def a_decrypt(key_filename: str, data: str): + with open(key_filename, "rb") as key_file: + key_content = key_file.read() + key = serialization.load_pem_private_key( + key_content, password=None, backend=default_backend()) + out = key.decrypt(base64.b64decode(data), padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA256()), + algorithm=hashes.SHA256(), label=None)) + return out.decode("utf8")