Compare commits

..

4 commits
main ... main

Author SHA1 Message Date
59df4bb2e7 errors corrected 2024-11-05 15:18:27 +01:00
a5e90f40c9 Merge pull request 'Update' (#1) from Disroot/gpg-lacre:main into main
Reviewed-on: EmanuelLoos/gpg-lacre#1
2024-11-05 13:25:09 +01:00
e5e653483f revert ec6c43afcb
revert improved formatting

Just some small Markdown syntax corrections.
2024-11-05 13:23:57 +01:00
ec6c43afcb improved formatting
Just some small Markdown syntax corrections.
2022-10-24 23:59:01 +00:00
6 changed files with 34 additions and 29 deletions

View file

@ -35,22 +35,27 @@ python -m pip install -r requirements.txt
2. Set the home directory for the user `nobody` (sadly this workaround is needed as there is no better solution at this point). If you get an error that the user is currently used by a process, you might need to kill the process manually.
```
usermod -d /var/gpgmailgate nobody
usermod -d /var/lacre nobody
```
3. Create dedicated directories for storing PGP keys and S/MIME certificates and make the user `nobody` owner of these:
```
install -u nobody -g nobody -d /var/gpgmailgate/ /var/gpgmailgate/.gnupg /var/gpgmailgate/smime
install --owner=nobody --group=nogroup -d /var/lacre/ /var/lacre/.gnupg /var/lacre/smime
```
4. Place the `lacre.py` in `/usr/local/bin/`, make the user `nobody` owner of the file and make it executable:
```
install -u nobody -g nobody -mode u=rx lacre.py /usr/local/bin/
install --owner=nobody --group=nogroup --mode=u=rx lacre.py /usr/local/bin/
```
5. Place `GnuPG` and `lacre` directories in `/usr/local/lib/python3.x/dist-packages` (replace 3.x with your Python version). Make sure they're available for Python `import`s by executing `python -m lacre.admin -h` command.
5. Place `GnuPG` and `lacre` directories in `/usr/local/lib/python3.x/` (replace 3.x with your Python version). Make sure they're available for Python `import`s by executing `python -m lacre.admin -h` command.
```
cp -r lacre /usr/local/lib/python3.9/
cp -r GnuPG/ /usr/local/lib/python3.9/
```
6. Configure `/etc/lacre.conf` based on the provided `lacre.conf.sample`. Change the settings according to your configuration. If you follow this guide and have a standard configuration for postfix, you don't need to change much.

View file

@ -52,15 +52,15 @@ def main():
to_addrs = sys.argv[1:]
# Read e-mail from stdin, parse it
raw = sys.stdin.buffer.read()
raw_message = email.message_from_bytes(raw, policy=SMTPUTF8)
raw = sys.stdin.read()
raw_message = email.message_from_string(raw, policy=SMTPUTF8)
from_addr = raw_message['From']
lmessage = LazyMessage(to_addrs, lambda: raw)
lmessage = LazyMessage(to_addrs, lambda: raw_message)
try:
# Let's start
core.deliver_message(lmessage, from_addr, to_addrs)
core.deliver_message(raw_message, from_addr, to_addrs)
delivered = True
except:
LOG.exception('Could not handle message')
@ -71,7 +71,7 @@ def main():
# message, we just try recoding the message body and delivering it.
try:
from_addr = raw_message['From']
core.failover_delivery(lmessage, to_addrs, from_addr)
core.failover_delivery(raw_message, to_addrs, from_addr)
except:
LOG.exception('Failover delivery failed too')

View file

@ -11,7 +11,7 @@ class KeyCache:
With keyring_dir given, set location of the directory from which keys should be loaded.
"""
self._keys = { fpr: eml.upper() for (fpr, eml) in keys.items() }
self._keys = keys
def __getitem__(self, fingerpring):
"""Look up email assigned to the given fingerprint."""
@ -29,7 +29,7 @@ class KeyCache:
def has_email(self, email):
"""Check if cache contains a key assigned to the given email."""
return email.upper() in self._keys.values()
return email in self._keys.values()
def __repr__(self):
"""Return text representation of this object."""

View file

@ -323,14 +323,25 @@ def _recode(m: EmailMessage):
m.set_content(payload)
def failover_delivery(lmessage: LazyMessage, recipients, from_address):
def failover_delivery(message: EmailMessage, recipients, from_address):
"""Try delivering message just one last time."""
LOG.debug('Failover delivery')
send = SendFrom(from_address)
orig = lmessage.get_original_content()
send(orig, recipients)
if message.get_content_maintype() == 'text':
LOG.debug('Flat text message, adjusting coding')
_recode(message)
b = message.as_bytes(policy=SMTPUTF8)
send(b, recipients)
elif message.get_content_maintype() == 'multipart':
LOG.debug('Multipart message, adjusting coding of text entities')
for part in message.iter_parts():
if part.get_content_maintype() == 'text':
_recode(part)
b = message.as_bytes(policy=SMTPUTF8)
send(b, recipients)
else:
LOG.warning('No failover strategy, giving up')
def _is_encrypted(raw_message: EmailMessage, lmessage: LazyMessage = None):
@ -372,13 +383,11 @@ def delivery_plan(recipients, message: EmailMessage, key_cache: kcache.KeyCache,
return plan
def deliver_message(message: LazyMessage, from_address, to_addrs):
def deliver_message(raw_message: EmailMessage, from_address, to_addrs):
"""Send RAW_MESSAGE to all TO_ADDRS using the best encryption method available."""
# Ugly workaround to keep the code working without too many changes.
register_sender(from_address)
raw_message = message.get_message()
sanitize = text.choose_sanitizer(conf.get_item('default', 'mail_case_insensitive'))
recipients_left = [sanitize(recipient) for recipient in to_addrs]
@ -404,5 +413,5 @@ def deliver_message(message: LazyMessage, from_address, to_addrs):
return
# Send out mail to recipients which are left
LOG.debug("Sending the rest as cleartext")
LOG.debug("Sending the rest as text/plain")
send(raw_message.as_bytes(policy=SMTPUTF8), recipients_left)

View file

@ -110,7 +110,7 @@ class AdvancedMailFilterE2ETest(unittest.TestCase):
self._execute_case(self.config, case_name=case_name)
def _execute_case(self, config, case_name):
logging.info("Executing case %s", case_name)
logging.info(f"Executing case {case_name}")
python = os.getenv("PYTHON", "python")
relay_mock = _spawn([python, "test/utils/relay.py", "2500"])

View file

@ -18,12 +18,3 @@ class LacreKeyCacheTest(unittest.TestCase):
self.assertTrue(kc.has_email('bob@example.com'))
self.assertFalse(kc.has_email('dave@example.com'))
def test_case_insensitivity(self):
kc = KeyCache({
'FINGERPRINT': 'alice@example.com',
'OTHERPRINT': 'bob@example.com',
})
self.assertTrue(kc.has_email('Alice@example.com'))
self.assertTrue(kc.has_email('BOB@EXAMPLE.COM'))