remail: Allow optional transport based security

Add an "encryption" option 'use_transport' which does not bother with
encryption and just relies on transport security.

For admins this makes sense as none of the admin messages is really
confidential.

This is also a valid option for a subscriber and makes some sense in
scenarios where the mail provider manages the subscriber key (sic!)
and does server side decryption. Think twice before using this.

Requested-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Reviewed-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
This commit is contained in:
Thomas Gleixner 2020-10-29 19:26:56 +01:00
parent 1e490249a7
commit 46f6145ac5
6 changed files with 49 additions and 14 deletions

View file

@ -10,7 +10,9 @@ subscribers:
# name: Real name of the subscriber # name: Real name of the subscriber
# enabled: Subscriber is enabled (if omitted defaults to False) # enabled: Subscriber is enabled (if omitted defaults to False)
# use_smime: True/False (Use S/MIME for encryption. If omitted defaults to False) # use_smime: True/False (Use S/MIME for encryption. If omitted defaults to False)
# fingerprint: GPG fingerprint (Not required when use_smime == True) # use_transport: True/False (SMTP transport layer encryption only. If omitted defaults to False.
# Conflicts with use_smime == True)
# fingerprint: GPG fingerprint (Not required when use_smime == True or use_transport == True)
# gpg_plain: Plain text inline GPG encryption (If omitted defaults to False) # gpg_plain: Plain text inline GPG encryption (If omitted defaults to False)
# aliases: List of alias addresses which are valid for posting (moderated list) # aliases: List of alias addresses which are valid for posting (moderated list)
# #

View file

@ -10,7 +10,9 @@ subscribers:
# name: Real name of the subscriber # name: Real name of the subscriber
# enabled: Subscriber is enabled (if omitted defaults to False) # enabled: Subscriber is enabled (if omitted defaults to False)
# use_smime: True/False (Use S/MIME for encryption. If omitted defaults to False) # use_smime: True/False (Use S/MIME for encryption. If omitted defaults to False)
# fingerprint: GPG fingerprint (Not required when use_smime == True) # use_transport: True/False (SMTP transport layer encryption only. If omitted defaults to False.
# Conflicts with use_smime == True)
# fingerprint: GPG fingerprint (Not required when use_smime == True or use_transport == True)
# gpg_plain: Plain text inline GPG encryption (If omitted defaults to False) # gpg_plain: Plain text inline GPG encryption (If omitted defaults to False)
# aliases: List of alias addresses which are valid for posting (moderated list) # aliases: List of alias addresses which are valid for posting (moderated list)
# #

View file

@ -61,7 +61,9 @@ lists:
# name: Real name of the subscriber # name: Real name of the subscriber
# enabled: Subscriber is enabled (if omitted defaults to False) # enabled: Subscriber is enabled (if omitted defaults to False)
# use_smime: True/False (Use S/MIME for encryption. If omitted defaults to False) # use_smime: True/False (Use S/MIME for encryption. If omitted defaults to False)
# fingerprint: GPG fingerprint (Not required when use_smime == True) # use_transport: True/False (SMTP transport layer encryption only. If omitted defaults to False.
# Conflicts with use_smime == True)
# fingerprint: GPG fingerprint (Not required when use_smime == True or use_transport == True)
# gpg_plain: Plain text inline GPG encryption (If omitted defaults to False) # gpg_plain: Plain text inline GPG encryption (If omitted defaults to False)
admin1@admin.domain: admin1@admin.domain:
name: Admin one name: Admin one
@ -106,7 +108,9 @@ lists:
# name: Real name of the subscriber # name: Real name of the subscriber
# enabled: Subscriber is enabled (if omitted defaults to False) # enabled: Subscriber is enabled (if omitted defaults to False)
# use_smime: True/False (Use S/MIME for encryption. If omitted defaults to False) # use_smime: True/False (Use S/MIME for encryption. If omitted defaults to False)
# fingerprint: GPG fingerprint (Not required when use_smime == True) # use_transport: True/False (SMTP transport layer encryption only. If omitted defaults to False.
# Conflicts with use_smime == True)
# fingerprint: GPG fingerprint (Not required when use_smime == True or use_transport == True)
# gpg_plain: Plain text inline GPG encryption (If omitted defaults to False) # gpg_plain: Plain text inline GPG encryption (If omitted defaults to False)
admin2@admin2.domain: admin2@admin2.domain:
name: Admin2 name: Admin2

View file

@ -384,6 +384,7 @@ The list administrators section:
fingerprint: 40CHARACTERFINGERPRINT fingerprint: 40CHARACTERFINGERPRINT
enabled: True enabled: True
use_smime: False use_smime: False
use_transport: False
gpg_plain: False gpg_plain: False
admin2@other.domain: admin2@other.domain:
@ -405,6 +406,21 @@ The list administrators section:
Send S/MIME encrypted mail to the admin if True. Otherwise use Send S/MIME encrypted mail to the admin if True. Otherwise use
PGP. Optional, defaults to False. PGP. Optional, defaults to False.
use_transport:
Do not bother with encryption and send plain text messages, i.e. rely
on the SMTP transport layer encryption. None of the admin messages are
really confidential.
This may also be a valid option for some subscribers, for example in
scenarios where the mail provider manages the subscriber key (sic!)
and does server side decryption anyway, or when mail is delivered to
an inbox stored on the same infrastructure as remail itself.
Not recommended for most cases.
Optional, defaults to False. Note, this is mutually exclusive with
the 'use_smime' option.
gpg_plain: gpg_plain:
If False send mail in the application/pgp-encrypted format. If True If False send mail in the application/pgp-encrypted format. If True

View file

@ -40,10 +40,11 @@ def show_attrs(obj, attrdict, indent):
print('%*s%-40s: %s' %(indent, '', attr, getattr(obj, attr))) print('%*s%-40s: %s' %(indent, '', attr, getattr(obj, attr)))
account_defaults = { account_defaults = {
'enabled' : False, 'enabled' : False,
'fingerprint' : None, 'fingerprint' : None,
'use_smime' : False, 'use_smime' : False,
'gpg_plain' : False, 'use_transport' : False,
'gpg_plain' : False,
} }
class account_config(object): class account_config(object):
@ -58,6 +59,11 @@ class account_config(object):
self.name = get_mandatory('name', cfgdict, base) self.name = get_mandatory('name', cfgdict, base)
set_defaults(self, account_defaults, cfgdict) set_defaults(self, account_defaults, cfgdict)
# Valdiate transport options to be coherent
if self.use_smime and self.use_transport:
txt = 'use_smime and use_transport cannot both be set for %s' % addr
raise RemailListConfigException(txt)
# Get the optional aliases to allow sending from # Get the optional aliases to allow sending from
# different accounts when the list is moderated # different accounts when the list is moderated
aliases = cfgdict.get('aliases') aliases = cfgdict.get('aliases')

View file

@ -71,12 +71,17 @@ class maillist(object):
def encrypt(self, msg_plain, account): def encrypt(self, msg_plain, account):
''' '''
Encrypt plain text message for the account Encrypt plain text message for the account or return the plain text
message when the account has the 'use_transport' option set. The
latter is used for delivery to admin accounts on the machine or the
protected network and for transport based security to mail providers
like gmail which manage the recipients S/MIME key and do server
side decryption anyway (shudder).
''' '''
msg = msg_from_string(msg_plain.as_string()) msg = msg_from_string(msg_plain.as_string())
if self.smime and account.use_smime: if self.smime and account.use_smime:
self.smime.encrypt(msg, account) self.smime.encrypt(msg, account)
else: elif not account.use_transport:
self.gpg.encrypt(msg, account) self.gpg.encrypt(msg, account)
return msg return msg
@ -317,7 +322,7 @@ class maillist(object):
continue continue
if account.use_smime and self.smime: if account.use_smime and self.smime:
self.smime.check_cert(account) self.smime.check_cert(account)
else: elif not account.use_transport:
self.gpg.check_key(account) self.gpg.check_key(account)
class maillist_checker(object): class maillist_checker(object):
@ -368,9 +373,9 @@ class maillist_checker(object):
if not account.enabled: if not account.enabled:
continue continue
try: try:
if not account.use_smime: if account.use_smime:
gpg.check_key(account)
else:
smime.check_cert(account) smime.check_cert(account)
elif not account.use_transport:
gpg.check_key(account)
except Exception as ex: except Exception as ex:
self.logger.log(str(ex) + '\n') self.logger.log(str(ex) + '\n')