Add support for OS-specific CA bundle locations

GitHub pull: #19
Suggested-by: Michael Vogt <mvo@ubuntu.com>
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
This commit is contained in:
Eygene Ryabinkin 2014-09-21 11:15:38 +04:00
parent aef88cc1f8
commit 818486283e
3 changed files with 79 additions and 1 deletions

View File

@ -8,6 +8,9 @@ ChangeLog
OfflineIMAP v6.5.6.1 (YYYY-MM-DD) OfflineIMAP v6.5.6.1 (YYYY-MM-DD)
================================= =================================
* Support default CA bundle locations for a couple of
known Unix systems (Michael Vogt, GutHub pull #19)
* Create SQLite database directory if it doesn't exist * Create SQLite database directory if it doesn't exist
yet; warn if path is not a directory (Nick Farrell, yet; warn if path is not a directory (Nick Farrell,
GutHub pull #102) GutHub pull #102)

View File

@ -19,6 +19,7 @@ from offlineimap.repository.Base import BaseRepository
from offlineimap import folder, imaputil, imapserver, OfflineImapError from offlineimap import folder, imaputil, imapserver, OfflineImapError
from offlineimap.folder.UIDMaps import MappedIMAPFolder from offlineimap.folder.UIDMaps import MappedIMAPFolder
from offlineimap.threadutil import ExitNotifyThread from offlineimap.threadutil import ExitNotifyThread
from offlineimap.utils.distro import get_os_sslcertfile
from threading import Event from threading import Event
import os import os
from sys import exc_info from sys import exc_info
@ -200,7 +201,7 @@ class IMAPRepository(BaseRepository):
def getsslcacertfile(self): def getsslcacertfile(self):
"""Return the absolute path of the CA certfile to use, if any""" """Return the absolute path of the CA certfile to use, if any"""
cacertfile = self.getconf('sslcacertfile', None) cacertfile = self.getconf('sslcacertfile', get_os_sslcertfile())
if cacertfile is None: if cacertfile is None:
return None return None
cacertfile = os.path.expanduser(cacertfile) cacertfile = os.path.expanduser(cacertfile)

View File

@ -0,0 +1,74 @@
# Copyright 2014 Eygene A. Ryabinkin.
#
# Module that supports distribution-specific functions.
import platform
import os
# Each dictionary value is either string or some iterable.
#
# For the former we will just return the value, for an iterable
# we will walk through the values and will return the first
# one that corresponds to the existing file.
__DEF_OS_LOCATIONS = {
'freebsd': '/usr/local/share/certs/ca-root-nss.crt',
'openbsd': None,
'netbsd': None,
'dragonfly': None,
'darwin': [
# MacPorts, port curl-ca-bundle
'/opt/local/share/curl/curl-ca-bundle.crt',
],
'linux-ubuntu': '/etc/ssl/certs/ca-certificates.crt',
'linux-debian': '/etc/ssl/certs/ca-certificates.crt',
'linux-fedora': '/etc/pki/tls/certs/ca-bundle.crt',
'linux-redhat': '/etc/pki/tls/certs/ca-bundle.crt',
'linux-suse': '/etc/ssl/ca-bundle.pem',
}
def get_os_name():
"""
Finds out OS name. For non-Linux system it will be just a plain
OS name (like FreeBSD), for Linux it will be "linux-<distro>",
where <distro> is the name of the distribution, as returned by
the first component of platform.linux_distribution.
Return value will be all-lowercase to avoid confusion about
proper name capitalisation.
"""
OS = platform.system().lower()
if OS.startswith('linux'):
DISTRO = platform.linux_distribution()[0]
if DISTRO:
OS = OS + "-%s" % DISTRO.lower()
return OS
def get_os_sslcertfile():
"""
Finds out the location for the distribution-specific
CA certificate file bundle.
Returns the location of the file or None if there is
no known CA certificate file or all known locations
correspond to non-existing filesystem objects.
"""
OS = get_os_name()
if OS in __DEF_OS_LOCATIONS:
l = __DEF_OS_LOCATIONS[OS]
if not hasattr(l, '__iter__'):
l = (l, )
for f in l:
assert (type(f) == type(""))
if os.path.exists(f) and \
(os.path.isfile(f) or os.path.islink(f)):
return f
return None