1
0
mirror of https://github.com/laurivosandi/certidude synced 2024-09-28 13:01:43 +00:00

Merge pull request #3 from plaes/work

Misc cosmetic improvements
This commit is contained in:
Lauri Võsandi 2015-08-28 09:04:05 +03:00
commit 70f89f996a
7 changed files with 63 additions and 20 deletions

View File

@ -60,7 +60,7 @@ To install Certidude:
.. code:: bash .. code:: bash
apt-get install -y python3 python3-pip python3-dev cython3 build-essential libffi-dev libssl-dev apt-get install -y python3 python3-pip python3-dev cython3 build-essential libffi-dev libssl-dev libkrb5-dev
pip3 install certidude pip3 install certidude
Make sure you're running PyOpenSSL 0.15+ and netifaces 0.10.4+ from PyPI, Make sure you're running PyOpenSSL 0.15+ and netifaces 0.10.4+ from PyPI,

View File

@ -9,18 +9,15 @@ import mimetypes
import netifaces import netifaces
import os import os
import pwd import pwd
import random
import re import re
import signal import signal
import socket import socket
import subprocess import subprocess
import sys import sys
import time
from certidude.helpers import expand_paths, \ from certidude.helpers import expand_paths, \
certidude_request_certificate certidude_request_certificate
from certidude.signer import SignServer from certidude.signer import SignServer
from certidude.wrappers import CertificateAuthorityConfig, \ from certidude.wrappers import CertificateAuthorityConfig, subject2dn
CertificateAuthority, Certificate, subject2dn, Request
from datetime import datetime from datetime import datetime
from humanize import naturaltime from humanize import naturaltime
from ipaddress import ip_network from ipaddress import ip_network
@ -46,7 +43,7 @@ assert hasattr(crypto.X509Req(), "get_extensions"), "You're running too old vers
# keyUsage, extendedKeyUsage - https://www.openssl.org/docs/apps/x509v3_config.html # keyUsage, extendedKeyUsage - https://www.openssl.org/docs/apps/x509v3_config.html
# strongSwan key paths - https://wiki.strongswan.org/projects/1/wiki/SimpleCA # strongSwan key paths - https://wiki.strongswan.org/projects/1/wiki/SimpleCA
config = CertificateAuthorityConfig("/etc/ssl/openssl.cnf") config = CertificateAuthorityConfig()
# Parse command-line argument defaults from environment # Parse command-line argument defaults from environment
HOSTNAME = socket.gethostname() HOSTNAME = socket.gethostname()
@ -77,6 +74,11 @@ def certidude_spawn(kill, no_interaction):
""" """
Spawn processes for signers Spawn processes for signers
""" """
# Check whether we have privileges
os.umask(0o027)
uid = os.getuid()
if uid != 0:
raise click.ClickException("Not running as root")
# Process directories # Process directories
run_dir = "/run/certidude" run_dir = "/run/certidude"
@ -88,10 +90,6 @@ def certidude_spawn(kill, no_interaction):
click.echo("Creating: %s" % signer_dir) click.echo("Creating: %s" % signer_dir)
os.makedirs(signer_dir) os.makedirs(signer_dir)
os.umask(0o027)
uid = os.getuid()
assert uid == 0, "Not running as root"
# Preload charmap encoding for byte_string() function of pyOpenSSL # Preload charmap encoding for byte_string() function of pyOpenSSL
# in order to enable chrooting # in order to enable chrooting
"".encode("charmap") "".encode("charmap")
@ -103,6 +101,7 @@ def certidude_spawn(kill, no_interaction):
# TODO: use os.mknod instead # TODO: use os.mknod instead
os.system("mknod -m 444 %s c 1 9" % os.path.join(chroot_dir, "dev", "urandom")) os.system("mknod -m 444 %s c 1 9" % os.path.join(chroot_dir, "dev", "urandom"))
ca_loaded = False
for ca in config.all_authorities(): for ca in config.all_authorities():
socket_path = os.path.join(signer_dir, ca.slug + ".sock") socket_path = os.path.join(signer_dir, ca.slug + ".sock")
pidfile_path = os.path.join(signer_dir, ca.slug + ".pid") pidfile_path = os.path.join(signer_dir, ca.slug + ".pid")
@ -125,7 +124,9 @@ def certidude_spawn(kill, no_interaction):
sleep(1) sleep(1)
except ProcessLookupError: except ProcessLookupError:
pass pass
ca_loaded = True
else: else:
ca_loaded = True
continue continue
child_pid = os.fork() child_pid = os.fork()
@ -144,6 +145,10 @@ def certidude_spawn(kill, no_interaction):
asyncore.loop() asyncore.loop()
else: else:
click.echo("Spawned certidude signer process with PID %d at %s" % (child_pid, socket_path)) click.echo("Spawned certidude signer process with PID %d at %s" % (child_pid, socket_path))
ca_loaded = True
if not ca_loaded:
raise click.ClickException("No CA sections defined in configuration: {}".format(config.path))
@click.command("client", help="Setup X.509 certificates for application") @click.command("client", help="Setup X.509 certificates for application")
@ -469,6 +474,12 @@ def certidude_setup_authority(parent, country, state, locality, organization, or
_, _, uid, gid, gecos, root, shell = pwd.getpwnam(group) _, _, uid, gid, gecos, root, shell = pwd.getpwnam(group)
os.setgid(gid) os.setgid(gid)
slug = os.path.basename(directory[:-1] if directory.endswith('/') else directory)
if not slug:
raise ValueError("Please supply proper target path")
click.echo("CA configuration files are saved to: {}".format(os.path.abspath(slug)))
click.echo("Generating 4096-bit RSA key...") click.echo("Generating 4096-bit RSA key...")
if pkcs11: if pkcs11:
@ -477,8 +488,6 @@ def certidude_setup_authority(parent, country, state, locality, organization, or
key = crypto.PKey() key = crypto.PKey()
key.generate_key(crypto.TYPE_RSA, 4096) key.generate_key(crypto.TYPE_RSA, 4096)
slug = os.path.basename(directory)
if not crl_distribution_url: if not crl_distribution_url:
crl_distribution_url = "http://%s/api/%s/revoked/" % (common_name, slug) crl_distribution_url = "http://%s/api/%s/revoked/" % (common_name, slug)
@ -575,9 +584,13 @@ def certidude_setup_authority(parent, country, state, locality, organization, or
with open(ca_key, "wb") as fh: with open(ca_key, "wb") as fh:
fh.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key)) fh.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key))
click.echo("Insert following to /etc/ssl/openssl.cnf:") with open(os.path.join(directory, "openssl.cnf.example"), "w") as fh:
fh.write(env.get_template("openssl.cnf").render(locals()))
click.echo("You need to copy the contents of the 'openssl.cnf.example'")
click.echo("to system-wide OpenSSL configuration file, usually located")
click.echo("at /etc/ssl/openssl.cnf")
click.echo() click.echo()
click.secho(env.get_template("openssl.cnf").render(locals()), fg="blue")
click.echo() click.echo()
click.echo("Use following commands to inspect the newly created files:") click.echo("Use following commands to inspect the newly created files:")

View File

@ -1,3 +1,6 @@
# You have to copy the settings to the system-wide
# OpenSSL configuration (usually /etc/ssl/openssl.cnf
[CA_{{slug}}] [CA_{{slug}}]
default_crl_days = {{revocation_list_lifetime}} default_crl_days = {{revocation_list_lifetime}}
default_days = {{certificate_lifetime}} default_days = {{certificate_lifetime}}
@ -38,3 +41,4 @@ emailAddress = optional
basicConstraints = CA:FALSE basicConstraints = CA:FALSE
keyUsage = nonRepudiation,digitalSignature,keyEncipherment keyUsage = nonRepudiation,digitalSignature,keyEncipherment
extendedKeyUsage = clientAuth extendedKeyUsage = clientAuth

View File

@ -61,13 +61,19 @@ def subject2dn(subject):
class CertificateAuthorityConfig(object): class CertificateAuthorityConfig(object):
""" """
Attempt to parse CA-s from openssl.cnf Certificate Authority configuration
:param path: Absolute path to configuration file.
Defaults to /etc/ssl/openssl.cnf
""" """
def __init__(self, *args): def __init__(self, path='/etc/ssl/openssl.cnf', *args):
#: Path to file where current configuration is loaded from.
self.path = path
self._config = RawConfigParser() self._config = RawConfigParser()
for arg in args: self._config.readfp(itertools.chain(["[global]"], open(self.path)))
self._config.readfp(itertools.chain(["[global]"], open(os.path.expanduser(arg))))
def get(self, section, key, default=""): def get(self, section, key, default=""):
if self._config.has_option(section, key): if self._config.has_option(section, key):

View File

@ -11,7 +11,7 @@ from certidude.api import CertificateAuthorityResource, \
# TODO: deduplicate routing code # TODO: deduplicate routing code
# TODO: set up /run/certidude/api paths and permissions # TODO: set up /run/certidude/api paths and permissions
config = CertificateAuthorityConfig("/etc/ssl/openssl.cnf") config = CertificateAuthorityConfig()
assert os.getenv("PUSH_SUBSCRIBE"), "Please set PUSH_SUBSCRIBE to your web server's subscription URL" assert os.getenv("PUSH_SUBSCRIBE"), "Please set PUSH_SUBSCRIBE to your web server's subscription URL"
assert os.getenv("PUSH_PUBLISH"), "Please set PUSH_PUBLISH to your web server's publishing URL" assert os.getenv("PUSH_PUBLISH"), "Please set PUSH_PUBLISH to your web server's publishing URL"

19
requirements.txt Normal file
View File

@ -0,0 +1,19 @@
cffi==1.2.1
click==5.1
cryptography==1.0
falcon==0.3.0
humanize==0.5.1
idna==2.0
Jinja2==2.8
ldap3==0.9.8.8
MarkupSafe==0.23
netifaces==0.10.4
pyasn1==0.1.8
pycountry==1.14
pycparser==2.14
pycrypto==2.6.1
pykerberos==1.1.8
pyOpenSSL==0.15.1
python-mimeparse==0.1.4
setproctitle==1.1.9
six==1.9.0

View File

@ -28,7 +28,8 @@ setup(
"pycrypto", "pycrypto",
"cryptography", "cryptography",
"markupsafe", "markupsafe",
"ldap3" "ldap3",
"pykerberos",
], ],
scripts=[ scripts=[
"misc/certidude" "misc/certidude"