tests: Fix NetworkManager setup tests

This commit is contained in:
Lauri Võsandi 2017-05-04 06:40:47 +00:00
parent 9922516d24
commit 505fa9d557
3 changed files with 74 additions and 35 deletions

View File

@ -20,7 +20,6 @@ script:
- sudo find /home/ -type d -exec chmod 755 {} \; # Allow certidude serve to read templates
- sudo useradd adminbot -G sudo -p '$1$PBkf5waA$n9EV6WJ7PS6lyGWkgeTPf1'
- sudo useradd userbot -G users -p '$1$PBkf5waA$n9EV6WJ7PS6lyGWkgeTPf1'
- sudo adduser --system --no-create-home --group certidude
- sudo chmod 777 . # Allow forked processes to write .coverage files
- sudo coverage run --parallel-mode --source certidude -m py.test tests
- sudo coverage combine

View File

@ -31,6 +31,16 @@ logger = logging.getLogger(__name__)
NOW = datetime.utcnow().replace(tzinfo=None)
def fqdn_required(func):
def wrapped(**args):
common_name = args.get("common_name")
if "." in common_name:
logger.info("Using fully qualified hostname %s" % common_name)
else:
raise ValueError("Fully qualified hostname not specified as common name, make sure hostname -f works")
return func(**args)
return wrapped
def setup_client(prefix="client_", dh=False):
# Create section in /etc/certidude/client.conf
def wrapper(func):
@ -306,7 +316,7 @@ def certidude_request(fork, renew, no_wait):
nm_config.set("vpn", "tap-dev", "no")
nm_config.set("vpn", "remote-cert-tls", "server") # Assert TLS Server flag of X.509 certificate
nm_config.set("vpn", "remote", service_config.get(endpoint, "remote"))
nm_config.set("vpn", "port", endpoint_port)
nm_config.set("vpn", "port", str(endpoint_port))
nm_config.set("vpn", "proto", endpoint_proto)
nm_config.set("vpn", "key", endpoint_key_path)
nm_config.set("vpn", "cert", endpoint_certificate_path)
@ -383,6 +393,7 @@ def certidude_request(fork, renew, no_wait):
default="/etc/openvpn/site-to-client.conf",
type=click.File(mode="w", atomic=True, lazy=True),
help="OpenVPN configuration file")
@fqdn_required
@setup_client(prefix="server_", dh=True)
def certidude_setup_openvpn_server(authority, common_name, config, subnet, route, local, proto, port, **paths):
# Install dependencies
@ -443,32 +454,14 @@ def certidude_setup_openvpn_server(authority, common_name, config, subnet, route
type=click.File(mode="w", atomic=True, lazy=True),
help="Site configuration file of nginx, /etc/nginx/sites-available/%s.conf by default" % const.HOSTNAME)
@click.option("--verify-client", "-vc", default="optional", type=click.Choice(['optional', 'on', 'off']))
@fqdn_required
@setup_client(prefix="server_", dh=True)
def certidude_setup_nginx(authority, common_name, site_config, tls_config, verify_client, **paths):
apt("nginx")
rpm("nginx")
from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader("certidude", "templates"), trim_blocks=True)
if "." not in common_name:
raise ValueError("Fully qualified hostname not specified as common name, make sure hostname -f works")
client_config = ConfigParser()
if os.path.exists(const.CLIENT_CONFIG_PATH):
client_config.readfp(open(const.CLIENT_CONFIG_PATH))
if client_config.has_section(authority):
click.echo("Section '%s' already exists in %s, remove to regenerate" % (authority, const.CLIENT_CONFIG_PATH))
else:
client_config.add_section(authority)
client_config.set(authority, "trigger", "interface up")
client_config.set(authority, "common name", common_name)
client_config.set(authority, "request path", request_path)
client_config.set(authority, "key path", key_path)
client_config.set(authority, "certificate path", certificate_path)
client_config.set(authority, "authority path", authority_path)
client_config.set(authority, "revocations path", revocations_path)
with open(const.CLIENT_CONFIG_PATH + ".part", 'wb') as fh:
client_config.write(fh)
os.rename(const.CLIENT_CONFIG_PATH + ".part", const.CLIENT_CONFIG_PATH)
click.echo("Section '%s' added to %s" % (authority, const.CLIENT_CONFIG_PATH))
context = globals() # Grab const.BLAH
context.update(locals())
@ -507,7 +500,7 @@ def certidude_setup_nginx(authority, common_name, site_config, tls_config, verif
type=click.File(mode="w", atomic=True, lazy=True),
help="OpenVPN configuration file")
@setup_client()
def certidude_setup_openvpn_client(authority, remote, common_name, config, proto, **ctx):
def certidude_setup_openvpn_client(authority, remote, common_name, config, proto, **paths):
# Install dependencies
apt("openvpn")
rpm("openvpn")
@ -536,10 +529,10 @@ def certidude_setup_openvpn_client(authority, remote, common_name, config, proto
config.write("proto %s\n" % proto)
config.write("dev tun-%s\n" % remote.split(".")[0])
config.write("nobind\n")
config.write("key %s\n" % client_config.get(authority, "key path"))
config.write("cert %s\n" % client_config.get(authority, "certificate path"))
config.write("ca %s\n" % client_config.get(authority, "authority path"))
config.write("crl-verify %s\n" % client_config.get(authority, "revocations path"))
config.write("key %s\n" % paths.get("key path"))
config.write("cert %s\n" % paths.get("certificate path"))
config.write("ca %s\n" % paths.get("authority path"))
config.write("crl-verify %s\n" % paths.get("revocations path"))
config.write("comp-lzo\n")
config.write("user nobody\n")
config.write("group nogroup\n")
@ -559,11 +552,9 @@ def certidude_setup_openvpn_client(authority, remote, common_name, config, proto
@click.option("--common-name", "-cn", default=const.FQDN, help="Common name, %s by default" % const.FQDN)
@click.option("--subnet", "-sn", default=u"192.168.33.0/24", type=ip_network, help="IPsec virtual subnet, 192.168.33.0/24 by default")
@click.option("--route", "-r", type=ip_network, multiple=True, help="Subnets to advertise via this connection, multiple allowed")
@fqdn_required
@setup_client(prefix="server_")
def certidude_setup_strongswan_server(authority, common_name, subnet, route, **paths):
if "." not in common_name:
raise ValueError("Hostname has to be fully qualified!")
# Install dependencies
apt("strongswan")
rpm("strongswan")
@ -729,11 +720,8 @@ def certidude_setup_openvpn_networkmanager(authority, remote, common_name, **pat
@click.option("--directory", help="Directory for authority files")
@click.option("--server-flags", is_flag=True, help="Add TLS Server and IKE Intermediate extended key usage flags")
@click.option("--outbox", default="smtp://smtp.%s" % const.DOMAIN, help="SMTP server, smtp://smtp.%s by default" % const.DOMAIN)
@fqdn_required
def certidude_setup_authority(username, kerberos_keytab, nginx_config, country, state, locality, organization, organizational_unit, common_name, directory, authority_lifetime, push_server, outbox, server_flags):
if "." not in common_name:
raise ValueError("No FQDN configured on this system!")
click.echo("Using fully qualified hostname: %s" % common_name)
# Install only rarely changing stuff from OS package management
apt("python-setproctitle cython python-dev libkrb5-dev libldap2-dev libffi-dev libssl-dev")
apt("python-mimeparse python-markdown python-xattr python-jinja2 python-cffi python-openssl")

View File

@ -101,6 +101,10 @@ def test_cli_setup_authority():
if os.path.exists("/var/log/certidude.log"):
os.unlink("/var/log/certidude.log")
# systemd
if os.path.exists("/etc/systemd/system/certidude.service"):
os.unlink("/etc/systemd/system/certidude.service")
# Remove nginx stuff
if os.path.exists("/etc/nginx/sites-available/ca.conf"):
os.unlink("/etc/nginx/sites-available/ca.conf")
@ -125,7 +129,11 @@ def test_cli_setup_authority():
from certidude.cli import entry_point as cli
from certidude import const
result = runner.invoke(cli, ['setup', 'authority'])
result = runner.invoke(cli, ['setup', 'authority', '-s'])
os.setgid(0) # Restore GID
os.umask(0022)
result = runner.invoke(cli, ['setup', 'authority']) # For if-else branches
os.setgid(0) # Restore GID
os.umask(0022)
@ -472,9 +480,15 @@ def test_cli_setup_authority():
#############
clean_client()
result = runner.invoke(cli, ["setup", "nginx", "-cn", "www", "ca.example.lan"])
assert result.exception # FQDN required
result = runner.invoke(cli, ["setup", "nginx", "-cn", "www.example.lan", "ca.example.lan"])
assert not result.exception, result.output
result = runner.invoke(cli, ["setup", "nginx", "-cn", "www.example.lan", "ca.example.lan"])
assert not result.exception, result.output # blah already exists, remove to regenerate
import os
with open("/etc/certidude/client.conf", "a") as fh:
@ -482,6 +496,7 @@ def test_cli_setup_authority():
result = runner.invoke(cli, ["request", "--no-wait"])
assert not result.exception, result.output
assert "refused to sign" in result.output, result.output
child_pid = os.fork()
if not child_pid:
@ -512,9 +527,15 @@ def test_cli_setup_authority():
if not os.path.exists("/etc/openvpn/keys"):
os.makedirs("/etc/openvpn/keys")
result = runner.invoke(cli, ['setup', 'openvpn', 'server', "-cn", "vpn", "ca.example.lan"])
assert result.exception, result.output
result = runner.invoke(cli, ['setup', 'openvpn', 'server', "-cn", "vpn.example.lan", "ca.example.lan"])
assert not result.exception, result.output
result = runner.invoke(cli, ['setup', 'openvpn', 'server', "-cn", "vpn.example.lan", "ca.example.lan"])
assert not result.exception, result.output # blah already exists, remove to regenerate
with open("/etc/certidude/client.conf", "a") as fh:
fh.write("insecure = true\n")
@ -541,6 +562,9 @@ def test_cli_setup_authority():
result = runner.invoke(cli, ['setup', 'openvpn', 'client', "-cn", "roadwarrior1", "ca.example.lan", "vpn.example.lan"])
assert not result.exception, result.output
result = runner.invoke(cli, ['setup', 'openvpn', 'client', "-cn", "roadwarrior1", "ca.example.lan", "vpn.example.lan"])
assert not result.exception, result.output # blah already exists, remove to regenerate
with open("/etc/certidude/client.conf", "a") as fh:
fh.write("insecure = true\n")
@ -556,9 +580,15 @@ def test_cli_setup_authority():
clean_client()
result = runner.invoke(cli, ['setup', 'strongswan', 'server', "-cn", "ipsec", "ca.example.lan"])
assert result.exception, result.output # FQDN required
result = runner.invoke(cli, ['setup', 'strongswan', 'server', "-cn", "ipsec.example.lan", "ca.example.lan"])
assert not result.exception, result.output
result = runner.invoke(cli, ['setup', 'strongswan', 'server', "-cn", "ipsec.example.lan", "ca.example.lan"])
assert not result.exception, result.output # blah already exists, remove to regenerate
with open("/etc/certidude/client.conf", "a") as fh:
fh.write("insecure = true\n")
@ -585,6 +615,9 @@ def test_cli_setup_authority():
result = runner.invoke(cli, ['setup', 'strongswan', 'client', "-cn", "roadwarrior2", "ca.example.lan", "ipsec.example.lan"])
assert not result.exception, result.output
result = runner.invoke(cli, ['setup', 'strongswan', 'client', "-cn", "roadwarrior2", "ca.example.lan", "ipsec.example.lan"])
assert not result.exception, result.output # blah already exists, remove to regenerate
with open("/etc/certidude/client.conf", "a") as fh:
fh.write("insecure = true\n")
@ -597,12 +630,31 @@ def test_cli_setup_authority():
### NetworkManager ###
######################
clean_client()
result = runner.invoke(cli, ['setup', 'openvpn', 'networkmanager', "-cn", "roadwarrior3", "ca.example.lan", "vpn.example.lan"])
assert not result.exception, result.output
with open("/etc/certidude/client.conf", "a") as fh:
fh.write("insecure = true\n")
result = runner.invoke(cli, ["request", "--no-wait"])
assert not result.exception, result.output
assert "Writing certificate to:" in result.output, result.output
clean_client()
result = runner.invoke(cli, ['setup', 'strongswan', 'networkmanager', "-cn", "roadwarrior4", "ca.example.lan", "ipsec.example.lan"])
assert not result.exception, result.output
with open("/etc/certidude/client.conf", "a") as fh:
fh.write("insecure = true\n")
result = runner.invoke(cli, ["request", "--no-wait"])
assert not result.exception, result.output
assert "Writing certificate to:" in result.output, result.output
###################
### Final tests ###