diff options
| author | Simo Sorce <simo@redhat.com> | 2016-12-13 10:32:32 -0500 |
|---|---|---|
| committer | Jan Cholasta <jcholast@redhat.com> | 2017-02-15 07:13:37 +0100 |
| commit | d124e307f3b7d88bca53784f030ed6043b224432 (patch) | |
| tree | 775fca61a10a7b2b2d0af42cf5ae9290fa6103ec /ipapython | |
| parent | d2f5fc304f1938d23171ae330fa20b213ceed54e (diff) | |
| download | freeipa-d124e307f3b7d88bca53784f030ed6043b224432.tar.gz freeipa-d124e307f3b7d88bca53784f030ed6043b224432.tar.xz freeipa-d124e307f3b7d88bca53784f030ed6043b224432.zip | |
Separate RA cert store from the HTTP cert store
This is in preparation for separating out the user under which the
ipa api framework runs as.
This commit also removes certs.NSS_DIR to avoid confusion and replaces
it where appropriate with the correct NSS DB directory, either the old
HTTPD_ALIAS_DIR ot the RA DB IPA_RADB_DIR. In some cases its use is
removed altogether as it was simply not necessary.
https://fedorahosted.org/freeipa/ticket/5959
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
Diffstat (limited to 'ipapython')
| -rw-r--r-- | ipapython/certdb.py | 93 |
1 files changed, 92 insertions, 1 deletions
diff --git a/ipapython/certdb.py b/ipapython/certdb.py index 948132633..08b8391b1 100644 --- a/ipapython/certdb.py +++ b/ipapython/certdb.py @@ -17,7 +17,11 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # +import binascii import os +import io +import pwd +import grp import re import tempfile import shutil @@ -26,6 +30,7 @@ from cryptography.hazmat.primitives import serialization from nss import nss from nss.error import NSPRError +from ipaplatform.tasks import tasks from ipapython.dn import DN from ipapython.ipa_log_manager import root_logger from ipapython import ipautil @@ -45,6 +50,8 @@ else: CA_NICKNAME_FMT = "%s IPA CA" +NSS_FILES = ("cert8.db", "key3.db", "secmod.db", "pwdfile.txt") + def get_ca_nickname(realm, format=CA_NICKNAME_FMT): return format % realm @@ -106,13 +113,63 @@ class NSSDatabase(object): new_args = new_args + args return ipautil.run(new_args, stdin, **kwargs) - def create_db(self, password_filename): + def create_db(self, password_filename=None, user=None, group=None, + mode=None, backup=False): """Create cert DB :param password_filename: Name of file containing the database password + :param user: User owner the secdir + :param group: Group owner of the secdir + :param mode: Mode of the secdir + :param backup: Backup the sedir files """ + dirmode = 0o750 + filemode = 0o640 + if mode is not None: + dirmode = mode + filemode = mode & 0o666 + + uid = -1 + gid = -1 + if user is not None: + uid = pwd.getpwnam(user).pw_uid + if group is not None: + gid = grp.getgrnam(group).gr_gid + + if backup: + for filename in NSS_FILES: + path = os.path.join(self.secdir, filename) + ipautil.backup_file(path) + + if not os.path.exists(self.secdir): + os.makedirs(self.secdir, dirmode) + + if password_filename is None: + password_filename = os.path.join(self.secdir, 'pwdfile.txt') + + if not os.path.exists(password_filename): + # Create the password file for this db + hex_str = binascii.hexlify(os.urandom(10)) + with io.open(os.open(password_filename, + os.O_CREAT | os.O_WRONLY, + filemode), 'wb', closefd=True) as f: + f.write(hex_str) + f.flush() + self.run_certutil(["-N", "-f", password_filename]) + # Finally fix up perms + os.chown(self.secdir, uid, gid) + os.chmod(self.secdir, dirmode) + tasks.restore_context(self.secdir) + for filename in NSS_FILES: + path = os.path.join(self.secdir, filename) + if os.path.exists(path): + if uid != -1 or gid != -1: + os.chown(path, uid, gid) + os.chmod(path, filemode) + tasks.restore_context(path) + def list_certs(self): """Return nicknames and cert flags for all certs in the database @@ -161,6 +218,31 @@ class NSSDatabase(object): return root_nicknames + def export_pkcs12(self, nickname, pkcs12_filename, db_password_filename, + pkcs12_passwd=None): + args = [PK12UTIL, "-d", self.secdir, + "-o", pkcs12_filename, + "-n", nickname, + "-k", db_password_filename] + pkcs12_password_file = None + if pkcs12_passwd is not None: + pkcs12_password_file = ipautil.write_tmp_file(pkcs12_passwd + '\n') + args = args + ["-w", pkcs12_password_file.name] + try: + ipautil.run(args) + except ipautil.CalledProcessError as e: + if e.returncode == 17: + raise RuntimeError("incorrect password for pkcs#12 file %s" % + pkcs12_filename) + elif e.returncode == 10: + raise RuntimeError("Failed to open %s" % pkcs12_filename) + else: + raise RuntimeError("unknown error exporting pkcs#12 file %s" % + pkcs12_filename) + finally: + if pkcs12_password_file is not None: + pkcs12_password_file.close() + def import_pkcs12(self, pkcs12_filename, db_password_filename, pkcs12_passwd=None): args = [PK12UTIL, "-d", self.secdir, @@ -508,3 +590,12 @@ class NSSDatabase(object): finally: del certdb, cert nss.nss_shutdown() + + def publish_ca_cert(self, canickname, location): + args = ["-L", "-n", canickname, "-a"] + result = self.run_certutil(args, capture_output=True) + cert = result.output + fd = open(location, "w+") + fd.write(cert) + fd.close() + os.chmod(location, 0o444) |
