mirror of
https://github.com/laurivosandi/certidude
synced 2024-12-22 16:25:17 +00:00
tests: Fix NetworkManager setup tests
This commit is contained in:
parent
9922516d24
commit
505fa9d557
@ -20,7 +20,6 @@ script:
|
|||||||
- sudo find /home/ -type d -exec chmod 755 {} \; # Allow certidude serve to read templates
|
- 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 adminbot -G sudo -p '$1$PBkf5waA$n9EV6WJ7PS6lyGWkgeTPf1'
|
||||||
- sudo useradd userbot -G users -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 chmod 777 . # Allow forked processes to write .coverage files
|
||||||
- sudo coverage run --parallel-mode --source certidude -m py.test tests
|
- sudo coverage run --parallel-mode --source certidude -m py.test tests
|
||||||
- sudo coverage combine
|
- sudo coverage combine
|
||||||
|
@ -31,6 +31,16 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
NOW = datetime.utcnow().replace(tzinfo=None)
|
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):
|
def setup_client(prefix="client_", dh=False):
|
||||||
# Create section in /etc/certidude/client.conf
|
# Create section in /etc/certidude/client.conf
|
||||||
def wrapper(func):
|
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", "tap-dev", "no")
|
||||||
nm_config.set("vpn", "remote-cert-tls", "server") # Assert TLS Server flag of X.509 certificate
|
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", "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", "proto", endpoint_proto)
|
||||||
nm_config.set("vpn", "key", endpoint_key_path)
|
nm_config.set("vpn", "key", endpoint_key_path)
|
||||||
nm_config.set("vpn", "cert", endpoint_certificate_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",
|
default="/etc/openvpn/site-to-client.conf",
|
||||||
type=click.File(mode="w", atomic=True, lazy=True),
|
type=click.File(mode="w", atomic=True, lazy=True),
|
||||||
help="OpenVPN configuration file")
|
help="OpenVPN configuration file")
|
||||||
|
@fqdn_required
|
||||||
@setup_client(prefix="server_", dh=True)
|
@setup_client(prefix="server_", dh=True)
|
||||||
def certidude_setup_openvpn_server(authority, common_name, config, subnet, route, local, proto, port, **paths):
|
def certidude_setup_openvpn_server(authority, common_name, config, subnet, route, local, proto, port, **paths):
|
||||||
# Install dependencies
|
# 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),
|
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)
|
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']))
|
@click.option("--verify-client", "-vc", default="optional", type=click.Choice(['optional', 'on', 'off']))
|
||||||
|
@fqdn_required
|
||||||
@setup_client(prefix="server_", dh=True)
|
@setup_client(prefix="server_", dh=True)
|
||||||
def certidude_setup_nginx(authority, common_name, site_config, tls_config, verify_client, **paths):
|
def certidude_setup_nginx(authority, common_name, site_config, tls_config, verify_client, **paths):
|
||||||
|
|
||||||
apt("nginx")
|
apt("nginx")
|
||||||
rpm("nginx")
|
rpm("nginx")
|
||||||
from jinja2 import Environment, PackageLoader
|
from jinja2 import Environment, PackageLoader
|
||||||
env = Environment(loader=PackageLoader("certidude", "templates"), trim_blocks=True)
|
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 = globals() # Grab const.BLAH
|
||||||
context.update(locals())
|
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),
|
type=click.File(mode="w", atomic=True, lazy=True),
|
||||||
help="OpenVPN configuration file")
|
help="OpenVPN configuration file")
|
||||||
@setup_client()
|
@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
|
# Install dependencies
|
||||||
apt("openvpn")
|
apt("openvpn")
|
||||||
rpm("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("proto %s\n" % proto)
|
||||||
config.write("dev tun-%s\n" % remote.split(".")[0])
|
config.write("dev tun-%s\n" % remote.split(".")[0])
|
||||||
config.write("nobind\n")
|
config.write("nobind\n")
|
||||||
config.write("key %s\n" % client_config.get(authority, "key path"))
|
config.write("key %s\n" % paths.get("key path"))
|
||||||
config.write("cert %s\n" % client_config.get(authority, "certificate path"))
|
config.write("cert %s\n" % paths.get("certificate path"))
|
||||||
config.write("ca %s\n" % client_config.get(authority, "authority path"))
|
config.write("ca %s\n" % paths.get("authority path"))
|
||||||
config.write("crl-verify %s\n" % client_config.get(authority, "revocations path"))
|
config.write("crl-verify %s\n" % paths.get("revocations path"))
|
||||||
config.write("comp-lzo\n")
|
config.write("comp-lzo\n")
|
||||||
config.write("user nobody\n")
|
config.write("user nobody\n")
|
||||||
config.write("group nogroup\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("--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("--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")
|
@click.option("--route", "-r", type=ip_network, multiple=True, help="Subnets to advertise via this connection, multiple allowed")
|
||||||
|
@fqdn_required
|
||||||
@setup_client(prefix="server_")
|
@setup_client(prefix="server_")
|
||||||
def certidude_setup_strongswan_server(authority, common_name, subnet, route, **paths):
|
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
|
# Install dependencies
|
||||||
apt("strongswan")
|
apt("strongswan")
|
||||||
rpm("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("--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("--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)
|
@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):
|
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
|
# 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-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")
|
apt("python-mimeparse python-markdown python-xattr python-jinja2 python-cffi python-openssl")
|
||||||
|
@ -101,6 +101,10 @@ def test_cli_setup_authority():
|
|||||||
if os.path.exists("/var/log/certidude.log"):
|
if os.path.exists("/var/log/certidude.log"):
|
||||||
os.unlink("/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
|
# Remove nginx stuff
|
||||||
if os.path.exists("/etc/nginx/sites-available/ca.conf"):
|
if os.path.exists("/etc/nginx/sites-available/ca.conf"):
|
||||||
os.unlink("/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.cli import entry_point as cli
|
||||||
from certidude import const
|
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.setgid(0) # Restore GID
|
||||||
os.umask(0022)
|
os.umask(0022)
|
||||||
|
|
||||||
@ -472,9 +480,15 @@ def test_cli_setup_authority():
|
|||||||
#############
|
#############
|
||||||
clean_client()
|
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"])
|
result = runner.invoke(cli, ["setup", "nginx", "-cn", "www.example.lan", "ca.example.lan"])
|
||||||
assert not result.exception, result.output
|
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
|
import os
|
||||||
|
|
||||||
with open("/etc/certidude/client.conf", "a") as fh:
|
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"])
|
result = runner.invoke(cli, ["request", "--no-wait"])
|
||||||
assert not result.exception, result.output
|
assert not result.exception, result.output
|
||||||
|
assert "refused to sign" in result.output, result.output
|
||||||
|
|
||||||
child_pid = os.fork()
|
child_pid = os.fork()
|
||||||
if not child_pid:
|
if not child_pid:
|
||||||
@ -512,9 +527,15 @@ def test_cli_setup_authority():
|
|||||||
if not os.path.exists("/etc/openvpn/keys"):
|
if not os.path.exists("/etc/openvpn/keys"):
|
||||||
os.makedirs("/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"])
|
result = runner.invoke(cli, ['setup', 'openvpn', 'server', "-cn", "vpn.example.lan", "ca.example.lan"])
|
||||||
assert not result.exception, result.output
|
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:
|
with open("/etc/certidude/client.conf", "a") as fh:
|
||||||
fh.write("insecure = true\n")
|
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"])
|
result = runner.invoke(cli, ['setup', 'openvpn', 'client', "-cn", "roadwarrior1", "ca.example.lan", "vpn.example.lan"])
|
||||||
assert not result.exception, result.output
|
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:
|
with open("/etc/certidude/client.conf", "a") as fh:
|
||||||
fh.write("insecure = true\n")
|
fh.write("insecure = true\n")
|
||||||
|
|
||||||
@ -556,9 +580,15 @@ def test_cli_setup_authority():
|
|||||||
|
|
||||||
clean_client()
|
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"])
|
result = runner.invoke(cli, ['setup', 'strongswan', 'server', "-cn", "ipsec.example.lan", "ca.example.lan"])
|
||||||
assert not result.exception, result.output
|
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:
|
with open("/etc/certidude/client.conf", "a") as fh:
|
||||||
fh.write("insecure = true\n")
|
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"])
|
result = runner.invoke(cli, ['setup', 'strongswan', 'client', "-cn", "roadwarrior2", "ca.example.lan", "ipsec.example.lan"])
|
||||||
assert not result.exception, result.output
|
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:
|
with open("/etc/certidude/client.conf", "a") as fh:
|
||||||
fh.write("insecure = true\n")
|
fh.write("insecure = true\n")
|
||||||
|
|
||||||
@ -597,12 +630,31 @@ def test_cli_setup_authority():
|
|||||||
### NetworkManager ###
|
### NetworkManager ###
|
||||||
######################
|
######################
|
||||||
|
|
||||||
|
clean_client()
|
||||||
|
|
||||||
result = runner.invoke(cli, ['setup', 'openvpn', 'networkmanager', "-cn", "roadwarrior3", "ca.example.lan", "vpn.example.lan"])
|
result = runner.invoke(cli, ['setup', 'openvpn', 'networkmanager', "-cn", "roadwarrior3", "ca.example.lan", "vpn.example.lan"])
|
||||||
assert not result.exception, result.output
|
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"])
|
result = runner.invoke(cli, ['setup', 'strongswan', 'networkmanager', "-cn", "roadwarrior4", "ca.example.lan", "ipsec.example.lan"])
|
||||||
assert not result.exception, result.output
|
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 ###
|
### Final tests ###
|
||||||
|
Loading…
Reference in New Issue
Block a user