Offline IMAP, Python, SSL CA Certs & passwords
SSL CA Certificates
offlineimap
was written in python. The result is that there is a quirk with python on OSX. Essentially since OSX 10.6, CA Root Certificates are stored in the secure keychain, and python will look into that store. However, for some legacy reason the path to some Root Cert(s) need to be specified (but python looks into the keychain anyway) for offlineimap
to work.
In this example, there are already certs outside of the keychain:
% ls -la /etc/ssl
total 424
drwxr-xr-x 6 root wheel 192 9 Sep 2019 ./
drwxr-xr-x 115 root wheel 3680 27 Jun 03:02 ../
-rw-r--r-- 1 root wheel 346545 9 Sep 2019 cert.pem
drwxr-xr-x 2 root wheel 64 9 Sep 2019 certs/
-rw-r--r-- 1 root wheel 745 9 Sep 2019 openssl.cnf
-rw-r--r-- 1 root wheel 1006 9 Sep 2019 x509v3.cnf
the sub-directory /etc/ssl/certs
is empty, though.
So all I did was define the path in offlineimaprc:
# Note according to the example config file this has to be placed in [Repository Remote]
slcacertfile = /etc/ssl/cert.pem
That did the trick.
Being safe with passwords in imap
and smtp
config files
If you use a *nix
program to interact with IMAP or SMTP servers where you need to authenticate yourself, you shouldn’t even think about placing plain text passwords in the config files of those programs.
You could create (like I did originally), a python program to retrieve the password from the keychain
:
#!/usr/bin/python3
import re, subprocess
def get_password(account=None, server=None):
params = {
'security' : '/usr/bin/security',
'command' : 'find-internet-password',
'account' : account,
'server' : server,
'keychain' : '/Users/<username>/Library/Keychains/login.keychain-db',
}
command = "%(security)s -v %(command)s -g -a %(account)s -s %(server)s %(keychain)s" % params
output = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT)
outtext = [l for l in output.splitlines() if l.startswith(b'password: ')][0]
return re.match(r'password: "(.*)"', outtext).group(1)
then you’d call this function when needed.
But there is an easier method. If you look at the code above, it invokes a program called security
which is OSX’s CLI to interact with the keycahin
. After some experimentation I found you could just use the code below to retrieve the password. This code is what you’d place in your config file:
mbsync
config:
PassCmd "security find-internet-password -s '<server URL>' -a '<account>' -w"
Note that you omit the https://
in the <server>
URL. <account>
is, e.g. ‘me@gmail.com’.
Now that you know how to use security
you can build that into any script.