summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipalib/plugins/join.py52
-rw-r--r--ipapython/certdb.py150
2 files changed, 195 insertions, 7 deletions
diff --git a/ipalib/plugins/join.py b/ipalib/plugins/join.py
index d75043fd..5f0d9974 100644
--- a/ipalib/plugins/join.py
+++ b/ipalib/plugins/join.py
@@ -26,6 +26,15 @@ from ipalib import Command, Str, Int
from ipalib import errors
import krbV
import os, subprocess
+from ipapython import ipautil
+from ipapython import certdb
+from ipapython import dogtag
+import tempfile
+import sha
+import httplib
+import xml.dom.minidom
+import stat
+import shutil
def get_realm():
krbctx = krbV.default_context()
@@ -103,14 +112,43 @@ class join(Command):
def __get_keytab(self, principal, stdin=None):
args = ["/usr/sbin/ipa-getkeytab", "-s", self.env.host, "-p", principal,"-k", "/tmp/kt"]
- return self.__run(args, stdin)
+ return ipautil.run(args, stdin)
- def __run(self, args, stdin=None):
- if stdin:
- p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
- stdout,stderr = p.communicate(stdin)
+ def _generate_server_cert(self, hostname):
+ subject = "CN=%s,OU=pki-ipa,O=IPA" % hostname
+ cdb = certdb.CertDB(secdir=None, temporary=True)
+
+ csr = cdb.generate_csr(subject, keysize=1024)
+
+ # Request a cert
+ try:
+ result = api.Command['cert_request'](unicode(csr), **{})
+ except KeyError:
+ return "Certificates are not supported"
+
+ # Load the cert into our temporary database
+ if result.get('certificate', False):
+ cert_file = cdb.secdir + "/cert.txt"
+ f = open(cert_file, "w")
+ f.write(result.get('certificate'))
+ f.close()
+
+ cdb.add_certificate(cert_file, "Server-Cert", is_ca=False)
+
+ ca_chain = dogtag.get_ca_certchain()
+
+ ca_file = cdb.secdir + "/ca.txt"
+ f = open(ca_file, "w")
+ f.write(ca_chain)
+ f.close()
+
+ cdb.add_certificate(ca_file, "caCert", is_ca=True)
+
+ result = cdb.create_pkcs12("/tmp/server.p12", "Server-Cert")
else:
- p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
- stdout,stderr = p.communicate()
+ # Raise some error?
+ pass
+
+ return result
api.register(join)
diff --git a/ipapython/certdb.py b/ipapython/certdb.py
new file mode 100644
index 00000000..15f6c16a
--- /dev/null
+++ b/ipapython/certdb.py
@@ -0,0 +1,150 @@
+# Authors: Rob Crittenden <rcritten@redhat.com>
+#
+# Copyright (C) 2009 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; version 2 only
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+from ipapython import ipautil
+from ipapython import nsslib
+import tempfile
+import sha
+import shutil
+import os
+
+class CertDB():
+ """
+ To be used for temporary NSS databases only. If temporary is set then
+ this willcompletely remove the database it is working on when the
+ class is destroyed.
+ """
+ def __init__(self, secdir, password=None, temporary=False):
+ if secdir is None:
+ secdir = tempfile.mkdtemp(prefix = "certdb-")
+ if password is None:
+ password = self.generate_random()
+ self.secdir = secdir
+ self.password = password
+ self.temporary = temporary
+ self.noise_file = secdir + "/noise"
+ self.pwd_file = secdir + "/pwd"
+ self.csr_file = secdir + "/csr.txt"
+
+ f = open(self.pwd_file, "w")
+ f.write(self.password)
+ f.close()
+
+ if not ipautil.file_exists(secdir + "/secmod.db"):
+ self.run_certutil(["-N", "-f", self.pwd_file])
+
+ def __del__(self):
+ if self.temporary:
+ shutil.rmtree(self.secdir)
+ else:
+ # clean up
+ if ipautil.file_exists(self.noise_file):
+ os.remove(self.noise_file)
+
+ def run_certutil(self, args, stdin=None):
+ new_args = ["/usr/bin/certutil", "-d", self.secdir]
+ new_args = new_args + args
+ return ipautil.run(new_args, stdin)
+
+ def generate_random(self):
+ return sha.sha(ipautil.ipa_generate_password()).hexdigest()
+
+ def create_noise_file(self):
+ """
+ Generate a noise file to be used when creating a key
+ """
+ if ipautil.file_exists(self.noise_file):
+ os.remove(self.noise_file)
+
+ f = open(self.noise_file, "w")
+ f.write(self.generate_random())
+ f.close()
+
+ return
+
+ def generate_csr(self, subject, keysize=2048, keytype="rsa"):
+ """
+ Generate a Certificate Signing Request (CSR) and return as a
+ string the base-64 result with the BEGIN/END block.
+ """
+ self.create_noise_file()
+ args = ["-R", "-s", subject,
+ "-o", self.csr_file,
+ "-k", keytype,
+ "-g", str(keysize),
+ "-z", self.noise_file,
+ "-f", self.pwd_file,
+ "-a"]
+ self.run_certutil(args)
+
+ # read in the CSR
+ f = open(self.csr_file, "r")
+ csr = f.readlines()
+ f.close()
+ csr = "".join(csr)
+
+ # We just want the CSR bits, make sure there is nothing else
+ s = csr.find("-----BEGIN NEW CERTIFICATE REQUEST-----")
+ e = csr.find("-----END NEW CERTIFICATE REQUEST-----")
+ if e > 0:
+ e = e + 37
+ if s >= 0:
+ csr = csr[s:]
+
+ return csr
+
+ def add_certificate(self, cert_file, nickname="Server-Cert", is_ca=False):
+ """
+ Add a certificate to our NSS database.
+
+ Only supports base64-encoded certificates, not DER-encoded.
+ """
+ if is_ca:
+ trust_flag="CT,C,C"
+ else:
+ trust_flag="u,u,u"
+
+ # Generate a CSR
+ args = ["-A",
+ "-n", nickname,
+ "-t", trust_flag,
+ "-i", cert_file,
+ "-f", self.pwd_file,
+ "-a"]
+
+ self.run_certutil(args)
+
+ def create_pkcs12(self, pkcs12_file, nickname="Server-Cert", password=None):
+ if password is None:
+ password = self.password
+
+ p12pwd_file = self.secdir + "/pkcs12_pwd"
+ f = open(p12pwd_file, "w")
+ f.write(password)
+ f.close()
+
+ args = ["/usr/bin/pk12util",
+ "-d", self.secdir,
+ "-o", pkcs12_file,
+ "-n", nickname,
+ "-k", self.pwd_file,
+ "-w", p12pwd_file]
+ ipautil.run(args)
+
+ return password