mirror of
				https://github.com/laurivosandi/certidude
				synced 2025-10-31 09:29:13 +00:00 
			
		
		
		
	tests: Fix NetworkManager setup tests
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
| @@ -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") | ||||
|   | ||||
| @@ -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 ### | ||||
|   | ||||
		Reference in New Issue
	
	Block a user