mirror of
				https://github.com/laurivosandi/certidude
				synced 2025-10-31 01:19:11 +00:00 
			
		
		
		
	tests: Attempt to set up nchan as part of unittests
This commit is contained in:
		| @@ -8,6 +8,9 @@ after_success: | |||||||
| virtualenv: | virtualenv: | ||||||
|   system_site_packages: true |   system_site_packages: true | ||||||
| install: | install: | ||||||
|  |   - sudo add-apt-repository ppa:nginx/stable  -y | ||||||
|  |   - sudo apt update | ||||||
|  |   - sudo apt install libnginx-mod-nchan | ||||||
|   - echo "127.0.0.1 localhost" | sudo tee /etc/hosts |   - echo "127.0.0.1 localhost" | sudo tee /etc/hosts | ||||||
|   - echo "127.0.1.1 ca.example.lan ca" | sudo tee -a /etc/hosts |   - echo "127.0.1.1 ca.example.lan ca" | sudo tee -a /etc/hosts | ||||||
|   - echo "127.0.0.1 vpn.example.lan vpn" | sudo tee -a /etc/hosts |   - echo "127.0.0.1 vpn.example.lan vpn" | sudo tee -a /etc/hosts | ||||||
| @@ -32,4 +35,5 @@ addons: | |||||||
|   hostname: ca |   hostname: ca | ||||||
|   apt: |   apt: | ||||||
|     packages: |     packages: | ||||||
|  |     - software-properties-common | ||||||
|     - python-configparser |     - python-configparser | ||||||
|   | |||||||
| @@ -137,7 +137,7 @@ class StaticResource(object): | |||||||
|     def __call__(self, req, resp): |     def __call__(self, req, resp): | ||||||
|         path = os.path.realpath(os.path.join(self.root, req.path[1:])) |         path = os.path.realpath(os.path.join(self.root, req.path[1:])) | ||||||
|         if not path.startswith(self.root): |         if not path.startswith(self.root): | ||||||
|             raise falcon.HTTPForbidden |             raise falcon.HTTPBadRequest() | ||||||
|  |  | ||||||
|         if os.path.isdir(path): |         if os.path.isdir(path): | ||||||
|             path = os.path.join(path, "index.html") |             path = os.path.join(path, "index.html") | ||||||
|   | |||||||
| @@ -172,7 +172,7 @@ class RequestDetailResource(object): | |||||||
|  |  | ||||||
|         try: |         try: | ||||||
|             _, buf, _ = authority.get_request(cn) |             _, buf, _ = authority.get_request(cn) | ||||||
|         except EnvironmentError: |         except errors.RequestDoesNotExist: | ||||||
|             logger.warning(u"Failed to serve non-existant request %s to %s", |             logger.warning(u"Failed to serve non-existant request %s to %s", | ||||||
|                 cn, req.context.get("remote_addr")) |                 cn, req.context.get("remote_addr")) | ||||||
|             raise falcon.HTTPNotFound() |             raise falcon.HTTPNotFound() | ||||||
| @@ -227,8 +227,8 @@ class RequestDetailResource(object): | |||||||
|         try: |         try: | ||||||
|             authority.delete_request(cn) |             authority.delete_request(cn) | ||||||
|             # Logging implemented in the function above |             # Logging implemented in the function above | ||||||
|         except EnvironmentError as e: |         except errors.RequestDoesNotExist as e: | ||||||
|             resp.body = "No certificate CN=%s found" % cn |             resp.body = "No certificate signing request for %s found" % cn | ||||||
|             logger.warning(u"User %s failed to delete signing request %s from %s, reason: %s", |             logger.warning(u"User %s failed to delete signing request %s from %s, reason: %s", | ||||||
|                 req.context["user"], cn, req.context.get("remote_addr"), e) |                 req.context["user"], cn, req.context.get("remote_addr"), e) | ||||||
|             raise falcon.HTTPNotFound() |             raise falcon.HTTPNotFound() | ||||||
|   | |||||||
| @@ -33,9 +33,12 @@ def get_request(common_name): | |||||||
|     if not re.match(RE_HOSTNAME, common_name): |     if not re.match(RE_HOSTNAME, common_name): | ||||||
|         raise ValueError("Invalid common name %s" % repr(common_name)) |         raise ValueError("Invalid common name %s" % repr(common_name)) | ||||||
|     path = os.path.join(config.REQUESTS_DIR, common_name + ".pem") |     path = os.path.join(config.REQUESTS_DIR, common_name + ".pem") | ||||||
|     with open(path) as fh: |     try: | ||||||
|         buf = fh.read() |         with open(path) as fh: | ||||||
|         return path, buf, x509.load_pem_x509_csr(buf, default_backend()) |             buf = fh.read() | ||||||
|  |             return path, buf, x509.load_pem_x509_csr(buf, default_backend()) | ||||||
|  |     except EnvironmentError: | ||||||
|  |         raise errors.RequestDoesNotExist("Certificate signing request file %s does not exist" % path) | ||||||
|  |  | ||||||
| def get_signed(common_name): | def get_signed(common_name): | ||||||
|     if not re.match(RE_HOSTNAME, common_name): |     if not re.match(RE_HOSTNAME, common_name): | ||||||
| @@ -210,8 +213,7 @@ def delete_request(common_name): | |||||||
|     if not re.match(RE_HOSTNAME, common_name): |     if not re.match(RE_HOSTNAME, common_name): | ||||||
|         raise ValueError("Invalid common name") |         raise ValueError("Invalid common name") | ||||||
|  |  | ||||||
|     path = os.path.join(config.REQUESTS_DIR, common_name + ".pem") |     path, buf, csr = get_request(common_name) | ||||||
|     _, buf, csr = get_request(common_name) |  | ||||||
|     os.unlink(path) |     os.unlink(path) | ||||||
|  |  | ||||||
|     # Publish event at CA channel |     # Publish event at CA channel | ||||||
|   | |||||||
| @@ -92,9 +92,10 @@ def setup_client(prefix="client_", dh=False): | |||||||
| @click.option("-nw", "--no-wait", default=False, is_flag=True, help="Return immideately if server doesn't autosign") | @click.option("-nw", "--no-wait", default=False, is_flag=True, help="Return immideately if server doesn't autosign") | ||||||
| def certidude_request(fork, renew, no_wait): | def certidude_request(fork, renew, no_wait): | ||||||
|     # Here let's try to avoid compiling packages from scratch |     # Here let's try to avoid compiling packages from scratch | ||||||
|     rpm("openssl") # TODO |     rpm("openssl") or \ | ||||||
|     apt("openssl python-cryptography python-jinja2") # Native packages on Ubuntu 16.04 |     apt("openssl python-cryptography python-jinja2") or \ | ||||||
|     pip("cryptography jinja2") # Mac OS X, should be skipped on Ubuntu |     pip("cryptography jinja2") | ||||||
|  |  | ||||||
|     import requests |     import requests | ||||||
|     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) | ||||||
| @@ -270,16 +271,6 @@ def certidude_request(fork, renew, no_wait): | |||||||
|                         "%s/ipsec.conf" % const.STRONGSWAN_PREFIX) |                         "%s/ipsec.conf" % const.STRONGSWAN_PREFIX) | ||||||
|                     break |                     break | ||||||
|  |  | ||||||
|                 # Regenerate /etc/ipsec.secrets |  | ||||||
|                 with open("%s/ipsec.secrets.part" % const.STRONGSWAN_PREFIX, "w") as fh: |  | ||||||
|                     for filename in os.listdir("%s/ipsec.d/private" % const.STRONGSWAN_PREFIX): |  | ||||||
|                         if not filename.endswith(".pem"): |  | ||||||
|                             continue |  | ||||||
|                         fh.write(": RSA %s/ipsec.d/private/%s\n" % (const.STRONGSWAN_PREFIX, filename)) |  | ||||||
|                 os.rename( |  | ||||||
|                     "%s/ipsec.secrets.part" % const.STRONGSWAN_PREFIX, |  | ||||||
|                     "%s/ipsec.secrets" % const.STRONGSWAN_PREFIX) |  | ||||||
|  |  | ||||||
|                 # Attempt to reload config or start if it's not running |                 # Attempt to reload config or start if it's not running | ||||||
|                 if os.path.exists("/usr/sbin/strongswan"): # wtf fedora |                 if os.path.exists("/usr/sbin/strongswan"): # wtf fedora | ||||||
|                     if os.system("strongswan update"): |                     if os.system("strongswan update"): | ||||||
| @@ -319,7 +310,8 @@ def certidude_request(fork, renew, no_wait): | |||||||
|                 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", str(endpoint_port)) |                 nm_config.set("vpn", "port", str(endpoint_port)) | ||||||
|                 nm_config.set("vpn", "proto", endpoint_proto) |                 if endpoint_proto == "tcp": | ||||||
|  |                     nm_config.set("vpn", "proto-tcp", "yes") | ||||||
|                 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) | ||||||
|                 nm_config.set("vpn", "ca", endpoint_authority_path) |                 nm_config.set("vpn", "ca", endpoint_authority_path) | ||||||
| @@ -498,7 +490,7 @@ def certidude_setup_nginx(authority, common_name, site_config, tls_config, verif | |||||||
| @click.option("--common-name", "-cn", default=const.HOSTNAME, help="Common name, %s by default" % const.HOSTNAME) | @click.option("--common-name", "-cn", default=const.HOSTNAME, help="Common name, %s by default" % const.HOSTNAME) | ||||||
| @click.option('--proto', "-t", default="udp", type=click.Choice(['udp', 'tcp']), help="OpenVPN transport protocol, UDP by default") | @click.option('--proto', "-t", default="udp", type=click.Choice(['udp', 'tcp']), help="OpenVPN transport protocol, UDP by default") | ||||||
| @click.option("--config", "-o", | @click.option("--config", "-o", | ||||||
|     default="/etc/openvpn/client-to-site.conf", |     default="/etc/openvpn/client-to-site.conf", # TODO: created initially disabled 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") | ||||||
| @setup_client() | @setup_client() | ||||||
| @@ -580,19 +572,24 @@ def certidude_setup_strongswan_server(authority, common_name, subnet, route, **p | |||||||
|  |  | ||||||
|     # Create corresponding section to /etc/ipsec.conf |     # Create corresponding section to /etc/ipsec.conf | ||||||
|     from ipsecparse import loads |     from ipsecparse import loads | ||||||
|     config = loads(open("%s/ipsec.conf" % const.STRONGSWAN_PREFIX).read()) |     ipsec_conf = loads(open("%s/ipsec.conf" % const.STRONGSWAN_PREFIX).read()) | ||||||
|     config["conn", authority] = dict( |     ipsec_conf["ca", authority] = dict( | ||||||
|  |         auto="add", | ||||||
|  |         cacert=paths.get("authority_path")) | ||||||
|  |     ipsec_conf["conn", authority] = dict( | ||||||
|         leftcert=paths.get("certificate_path"), |         leftcert=paths.get("certificate_path"), | ||||||
|         leftsubnet=",".join(route), |         leftsubnet=",".join(route), | ||||||
|         right="%any", |         right="%any", | ||||||
|         rightsourceip=str(subnet), |         rightsourceip=str(subnet), | ||||||
|         closeaction="restart", |         closeaction="restart", | ||||||
|         auto="ignore") |         auto="ignore") | ||||||
|     with open("%s/ipsec.conf.part" % const.STRONGSWAN_PREFIX, "w") as fh: |     with open("%s/ipsec.conf" % const.STRONGSWAN_PREFIX, "w") as fh: | ||||||
|         fh.write(config.dumps()) |         fh.write(ipsec_conf.dumps()) | ||||||
|     os.rename( |     with open("%s/ipsec.secrets" % const.STRONGSWAN_PREFIX, "a") as fh: | ||||||
|         "%s/ipsec.conf.part" % const.STRONGSWAN_PREFIX, |         fh.write(": RSA %s\n" % paths.get("key_path")) | ||||||
|         "%s/ipsec.conf" % const.STRONGSWAN_PREFIX) |     if os.path.exists("/etc/apparmor.d/local"): | ||||||
|  |         with open("/etc/apparmor.d/local/usr.lib.ipsec.charon", "w") as fh: | ||||||
|  |             fh.write(os.path.join(const.STORAGE_PATH, "**") + " r,\n") # TODO: dedup! | ||||||
|  |  | ||||||
|     click.echo() |     click.echo() | ||||||
|     click.echo("If you're running Ubuntu make sure you're not affected by #1505222") |     click.echo("If you're running Ubuntu make sure you're not affected by #1505222") | ||||||
| @@ -606,8 +603,7 @@ def certidude_setup_strongswan_server(authority, common_name, subnet, route, **p | |||||||
| @setup_client() | @setup_client() | ||||||
| def certidude_setup_strongswan_client(authority, remote, common_name, **paths): | def certidude_setup_strongswan_client(authority, remote, common_name, **paths): | ||||||
|     # Install dependencies |     # Install dependencies | ||||||
|     apt("strongswan") |     apt("strongswan") or rpm("strongswan") | ||||||
|     rpm("strongswan") |  | ||||||
|     pip("ipsecparse") |     pip("ipsecparse") | ||||||
|  |  | ||||||
|     # Create corresponding section in /etc/certidude/services.conf |     # Create corresponding section in /etc/certidude/services.conf | ||||||
| @@ -629,24 +625,29 @@ def certidude_setup_strongswan_client(authority, remote, common_name, **paths): | |||||||
|  |  | ||||||
|     # Create corresponding section in /etc/ipsec.conf |     # Create corresponding section in /etc/ipsec.conf | ||||||
|     from ipsecparse import loads |     from ipsecparse import loads | ||||||
|     config = loads(open('%s/ipsec.conf' % const.STRONGSWAN_PREFIX).read()) |     ipsec_conf = loads(open('%s/ipsec.conf' % const.STRONGSWAN_PREFIX).read()) | ||||||
|     config["conn", remote] = dict( |     ipsec_conf["ca", authority] = dict( | ||||||
|  |         auto="add", | ||||||
|  |         cacert=paths.get("authority_path")) | ||||||
|  |     ipsec_conf["conn", remote] = dict( | ||||||
|         leftsourceip="%config", |         leftsourceip="%config", | ||||||
|         left="%defaultroute", |         left="%defaultroute", | ||||||
|         leftcert=paths.get("certificate_path"), |         leftcert=paths.get("certificate_path"), | ||||||
|         rightid="%any", |         rightid="%any", | ||||||
|         right=remote, |         right=remote, | ||||||
|         #rightsubnet=route, |         rightsubnet="0.0.0.0/0", # To allow anything suggested by gateway | ||||||
|         keyexchange="ikev2", |         keyexchange="ikev2", | ||||||
|         keyingtries="300", |         keyingtries="300", | ||||||
|         dpdaction="restart", |         dpdaction="restart", | ||||||
|         closeaction="restart", |         closeaction="restart", | ||||||
|         auto="ignore") |         auto="ignore") | ||||||
|     with open("%s/ipsec.conf.part" % const.STRONGSWAN_PREFIX, "w") as fh: |     with open("%s/ipsec.conf" % const.STRONGSWAN_PREFIX, "w") as fh: | ||||||
|         fh.write(config.dumps()) |         fh.write(ipsec_conf.dumps()) | ||||||
|     os.rename( |     with open("%s/ipsec.secrets" % const.STRONGSWAN_PREFIX, "a") as fh: | ||||||
|         "%s/ipsec.conf.part" % const.STRONGSWAN_PREFIX, |         fh.write(": RSA %s\n" % paths.get("key_path")) | ||||||
|         "%s/ipsec.conf" % const.STRONGSWAN_PREFIX) |     if os.path.exists("/etc/apparmor.d/local"): | ||||||
|  |         with open("/etc/apparmor.d/local/usr.lib.ipsec.charon", "w") as fh: | ||||||
|  |             fh.write(os.path.join(const.STORAGE_PATH, "**") + " r,\n") | ||||||
|  |  | ||||||
|     click.echo("Generated section %s in %s" % (authority, const.CLIENT_CONFIG_PATH)) |     click.echo("Generated section %s in %s" % (authority, const.CLIENT_CONFIG_PATH)) | ||||||
|     click.echo("Run 'certidude request' to request certificates and to enable services") |     click.echo("Run 'certidude request' to request certificates and to enable services") | ||||||
| @@ -800,21 +801,23 @@ def certidude_setup_authority(username, kerberos_keytab, nginx_config, country, | |||||||
|     certidude_path = sys.argv[0] |     certidude_path = sys.argv[0] | ||||||
|  |  | ||||||
|     # Push server config generation |     # Push server config generation | ||||||
|     if not os.path.exists("/etc/nginx") or os.getenv("TRAVIS"): |     if os.path.exists("/etc/nginx"): | ||||||
|         click.echo("Directory /etc/nginx does not exist, hence not creating nginx configuration") |         listen = "127.0.1.1" | ||||||
|         listen = "0.0.0.0" |  | ||||||
|         port = "80" |  | ||||||
|     else: |  | ||||||
|         port = "8080" |         port = "8080" | ||||||
|         click.echo("Generating: %s" % nginx_config.name) |         click.echo("Generating: %s" % nginx_config.name) | ||||||
|         nginx_config.write(env.get_template("server/nginx.conf").render(vars())) |         nginx_config.write(env.get_template("server/nginx.conf").render(vars())) | ||||||
|  |         nginx_config.close() | ||||||
|         if not os.path.exists("/etc/nginx/sites-enabled/certidude.conf"): |         if not os.path.exists("/etc/nginx/sites-enabled/certidude.conf"): | ||||||
|             os.symlink("../sites-available/certidude.conf", "/etc/nginx/sites-enabled/certidude.conf") |             os.symlink("../sites-available/certidude.conf", "/etc/nginx/sites-enabled/certidude.conf") | ||||||
|             click.echo("Symlinked %s -> /etc/nginx/sites-enabled/" % nginx_config.name) |             click.echo("Symlinked %s -> /etc/nginx/sites-enabled/" % nginx_config.name) | ||||||
|         if os.path.exists("/etc/nginx/sites-enabled/default"): |         if os.path.exists("/etc/nginx/sites-enabled/default"): | ||||||
|             os.unlink("/etc/nginx/sites-enabled/default") |             os.unlink("/etc/nginx/sites-enabled/default") | ||||||
|         if not push_server: |         os.system("service nginx restart") | ||||||
|             click.echo("Remember to install nchan capable nginx instead of regular nginx!") |     else: | ||||||
|  |         click.echo("Directory /etc/nginx does not exist, hence not creating nginx configuration") | ||||||
|  |         click.echo("Remember to install/configure nchan capable nginx instead of regular nginx!") | ||||||
|  |         listen = "0.0.0.0" | ||||||
|  |         port = "80" | ||||||
|  |  | ||||||
|     if os.path.exists("/etc/systemd"): |     if os.path.exists("/etc/systemd"): | ||||||
|         if os.path.exists("/etc/systemd/system/certidude.service"): |         if os.path.exists("/etc/systemd/system/certidude.service"): | ||||||
|   | |||||||
| @@ -40,6 +40,8 @@ def apt(packages): | |||||||
|         cmd = ["/usr/bin/apt-get", "install", "-yqq"] + packages.split(" ") |         cmd = ["/usr/bin/apt-get", "install", "-yqq"] + packages.split(" ") | ||||||
|         click.echo("Running: %s" % " ".join(cmd)) |         click.echo("Running: %s" % " ".join(cmd)) | ||||||
|         subprocess.call(cmd) |         subprocess.call(cmd) | ||||||
|  |         return True | ||||||
|  |     return False | ||||||
|  |  | ||||||
|  |  | ||||||
| def rpm(packages): | def rpm(packages): | ||||||
| @@ -50,10 +52,13 @@ def rpm(packages): | |||||||
|         cmd = ["/usr/bin/dnf", "install", "-y"] + packages.split(" ") |         cmd = ["/usr/bin/dnf", "install", "-y"] + packages.split(" ") | ||||||
|         click.echo("Running: %s" % " ".join(cmd)) |         click.echo("Running: %s" % " ".join(cmd)) | ||||||
|         subprocess.call(cmd) |         subprocess.call(cmd) | ||||||
|  |         return True | ||||||
|  |     return False | ||||||
|  |  | ||||||
|  |  | ||||||
| def pip(packages): | def pip(packages): | ||||||
|     click.echo("Running: pip install %s" % packages) |     click.echo("Running: pip install %s" % packages) | ||||||
|     import pip |     import pip | ||||||
|     pip.main(['install'] + packages.split(" ")) |     pip.main(['install'] + packages.split(" ")) | ||||||
|  |     return True | ||||||
|  |  | ||||||
|   | |||||||
| @@ -71,11 +71,6 @@ EVENT_SOURCE_SUBSCRIBE = cp.get("push", "event source subscribe") | |||||||
| LONG_POLL_PUBLISH = cp.get("push", "long poll publish") | LONG_POLL_PUBLISH = cp.get("push", "long poll publish") | ||||||
| LONG_POLL_SUBSCRIBE = cp.get("push", "long poll subscribe") | LONG_POLL_SUBSCRIBE = cp.get("push", "long poll subscribe") | ||||||
|  |  | ||||||
| if const.DOMAIN == "example.lan": # TODO: include nginx setup in Travis |  | ||||||
|     EVENT_SOURCE_PUBLISH = "" |  | ||||||
|     LONG_POLL_PUBLISH = "" |  | ||||||
|     LONG_POLL_SUBSCRIBE = "//nonexistant/lp/sub/%s" |  | ||||||
|  |  | ||||||
| LOGGING_BACKEND = cp.get("logging", "backend") | LOGGING_BACKEND = cp.get("logging", "backend") | ||||||
|  |  | ||||||
| if "whitelist" == AUTHORIZATION_BACKEND: | if "whitelist" == AUTHORIZATION_BACKEND: | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ SERVER_LOG_PATH = "/var/log/certidude-server.log" | |||||||
| SIGNER_SOCKET_PATH = "/run/certidude/signer.sock" | SIGNER_SOCKET_PATH = "/run/certidude/signer.sock" | ||||||
| SIGNER_PID_PATH = os.path.join(RUN_DIR, "signer.pid") | SIGNER_PID_PATH = os.path.join(RUN_DIR, "signer.pid") | ||||||
| SIGNER_LOG_PATH = "/var/log/certidude-signer.log" | SIGNER_LOG_PATH = "/var/log/certidude-signer.log" | ||||||
| STORAGE_PATH = "/var/lib/certidude" | STORAGE_PATH = "/var/lib/certidude/" | ||||||
|  |  | ||||||
| try: | try: | ||||||
|     FQDN = socket.getaddrinfo(socket.gethostname(), 0, socket.AF_INET, 0, 0, socket.AI_CANONNAME)[0][3] |     FQDN = socket.getaddrinfo(socket.gethostname(), 0, socket.AF_INET, 0, 0, socket.AI_CANONNAME)[0][3] | ||||||
|   | |||||||
| @@ -2,6 +2,9 @@ | |||||||
| class RequestExists(Exception): | class RequestExists(Exception): | ||||||
|     pass |     pass | ||||||
|  |  | ||||||
|  | class RequestDoesNotExist(Exception): | ||||||
|  |     pass | ||||||
|  |  | ||||||
| class FatalError(Exception): | class FatalError(Exception): | ||||||
|     """ |     """ | ||||||
|     Exception to be raised when user intervention is required |     Exception to be raised when user intervention is required | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ server { | |||||||
|     root {{static_path}}; |     root {{static_path}}; | ||||||
|  |  | ||||||
|     location /api/ { |     location /api/ { | ||||||
|         proxy_pass http://127.0.0.1{% if port != 80 %}:{{ port }}{% endif %}/api/; |         proxy_pass http://127.0.1.1{% if port != 80 %}:{{ port }}{% endif %}/api/; | ||||||
|         proxy_set_header Host $host; |         proxy_set_header Host $host; | ||||||
|         proxy_set_header X-Real-IP $remote_addr; |         proxy_set_header X-Real-IP $remote_addr; | ||||||
|         proxy_connect_timeout 600; |         proxy_connect_timeout 600; | ||||||
|   | |||||||
| @@ -72,6 +72,12 @@ def clean_client(): | |||||||
|             if filename.endswith(".pem"): |             if filename.endswith(".pem"): | ||||||
|                 os.unlink(os.path.join("/tmp/ca.example.lan", filename)) |                 os.unlink(os.path.join("/tmp/ca.example.lan", filename)) | ||||||
|  |  | ||||||
|  |     # Reset IPsec stuff | ||||||
|  |     with open("/etc/ipsec.conf", "w") as fh: # TODO: make compatible with Fedora | ||||||
|  |         pass | ||||||
|  |     with open("/etc/ipsec.secrets", "w") as fh: # TODO: make compatible with Fedora | ||||||
|  |         pass | ||||||
|  |  | ||||||
|  |  | ||||||
| def test_cli_setup_authority(): | def test_cli_setup_authority(): | ||||||
|     import os |     import os | ||||||
| @@ -110,12 +116,13 @@ def test_cli_setup_authority(): | |||||||
|         os.unlink("/etc/nginx/sites-available/ca.conf") |         os.unlink("/etc/nginx/sites-available/ca.conf") | ||||||
|     if os.path.exists("/etc/nginx/sites-enabled/ca.conf"): |     if os.path.exists("/etc/nginx/sites-enabled/ca.conf"): | ||||||
|         os.unlink("/etc/nginx/sites-enabled/ca.conf") |         os.unlink("/etc/nginx/sites-enabled/ca.conf") | ||||||
|  |     if os.path.exists("/etc/nginx/sites-available/certidude.conf"): | ||||||
|  |         os.unlink("/etc/nginx/sites-available/certidude.conf") | ||||||
|  |     if os.path.exists("/etc/nginx/sites-enabled/certidude.conf"): | ||||||
|  |         os.unlink("/etc/nginx/sites-enabled/certidude.conf") | ||||||
|     if os.path.exists("/etc/nginx/conf.d/tls.conf"): |     if os.path.exists("/etc/nginx/conf.d/tls.conf"): | ||||||
|         os.unlink("/etc/nginx/conf.d/tls.conf") |         os.unlink("/etc/nginx/conf.d/tls.conf") | ||||||
|  |  | ||||||
|     with open("/etc/ipsec.conf", "w") as fh: # TODO: make compatible with Fedora |  | ||||||
|         pass |  | ||||||
|  |  | ||||||
|     # Remove OpenVPN stuff |     # Remove OpenVPN stuff | ||||||
|     if os.path.exists("/etc/openvpn"): |     if os.path.exists("/etc/openvpn"): | ||||||
|         for filename in os.listdir("/etc/openvpn"): |         for filename in os.listdir("/etc/openvpn"): | ||||||
| @@ -167,7 +174,7 @@ def test_cli_setup_authority(): | |||||||
|     server_pid = os.fork() |     server_pid = os.fork() | ||||||
|     if not server_pid: |     if not server_pid: | ||||||
|         # Fork to prevent umask, setuid, setgid side effects |         # Fork to prevent umask, setuid, setgid side effects | ||||||
|         result = runner.invoke(cli, ['serve', '-p', '80', '-l', '127.0.1.1']) |         result = runner.invoke(cli, ['serve', '-p', '8080', '-l', '127.0.1.1']) | ||||||
|         assert not result.exception, result.output |         assert not result.exception, result.output | ||||||
|         return |         return | ||||||
|  |  | ||||||
| @@ -210,7 +217,7 @@ def test_cli_setup_authority(): | |||||||
|     r = requests.get("http://ca.example.lan/nonexistant.html") |     r = requests.get("http://ca.example.lan/nonexistant.html") | ||||||
|     assert r.status_code == 404, r.text |     assert r.status_code == 404, r.text | ||||||
|     r = requests.get("http://ca.example.lan/../nonexistant.html") |     r = requests.get("http://ca.example.lan/../nonexistant.html") | ||||||
|     assert r.status_code == 403, r.text |     assert r.status_code == 400, r.text | ||||||
|  |  | ||||||
|     r = client().simulate_get("/") |     r = client().simulate_get("/") | ||||||
|     assert r.status_code == 200, r.text |     assert r.status_code == 200, r.text | ||||||
| @@ -219,7 +226,7 @@ def test_cli_setup_authority(): | |||||||
|     r = client().simulate_get("/nonexistant.html") |     r = client().simulate_get("/nonexistant.html") | ||||||
|     assert r.status_code == 404, r.text |     assert r.status_code == 404, r.text | ||||||
|     r = client().simulate_get("/../nonexistant.html") |     r = client().simulate_get("/../nonexistant.html") | ||||||
|     assert r.status_code == 403, r.text |     assert r.status_code == 400, r.text | ||||||
|  |  | ||||||
|     # Test request submission |     # Test request submission | ||||||
|     buf = generate_csr(cn=u"test") |     buf = generate_csr(cn=u"test") | ||||||
| @@ -232,6 +239,7 @@ def test_cli_setup_authority(): | |||||||
|         headers={"content-type":"application/pkcs10"}) |         headers={"content-type":"application/pkcs10"}) | ||||||
|     assert r.status_code == 202 # success |     assert r.status_code == 202 # success | ||||||
|     assert "Stored request " in inbox.pop(), inbox |     assert "Stored request " in inbox.pop(), inbox | ||||||
|  |     assert os.path.exists("/var/lib/certidude/ca.example.lan/requests/test.pem") | ||||||
|  |  | ||||||
|     # Test request deletion |     # Test request deletion | ||||||
|     r = client().simulate_delete("/api/request/test/") |     r = client().simulate_delete("/api/request/test/") | ||||||
| @@ -242,6 +250,7 @@ def test_cli_setup_authority(): | |||||||
|     r = client().simulate_delete("/api/request/test/", |     r = client().simulate_delete("/api/request/test/", | ||||||
|         headers={"User-Agent":UA_FEDORA_FIREFOX, "Authorization":admintoken}) |         headers={"User-Agent":UA_FEDORA_FIREFOX, "Authorization":admintoken}) | ||||||
|     assert r.status_code == 403, r.text # CSRF prevented |     assert r.status_code == 403, r.text # CSRF prevented | ||||||
|  |     assert os.path.exists("/var/lib/certidude/ca.example.lan/requests/test.pem") | ||||||
|     r = client().simulate_delete("/api/request/test/", |     r = client().simulate_delete("/api/request/test/", | ||||||
|         headers={"Authorization":admintoken}) |         headers={"Authorization":admintoken}) | ||||||
|     assert r.status_code == 200, r.text |     assert r.status_code == 200, r.text | ||||||
| @@ -632,6 +641,7 @@ def test_cli_setup_authority(): | |||||||
|     assert not result.exception, result.output |     assert not result.exception, result.output | ||||||
|     assert "Writing certificate to:" in result.output, result.output |     assert "Writing certificate to:" in result.output, result.output | ||||||
|     assert os.path.exists("/tmp/ca.example.lan/server_cert.pem") |     assert os.path.exists("/tmp/ca.example.lan/server_cert.pem") | ||||||
|  |     assert os.path.exists("/etc/openvpn/site-to-client.conf") | ||||||
|  |  | ||||||
|     # Reset config |     # Reset config | ||||||
|     os.unlink("/etc/certidude/client.conf") |     os.unlink("/etc/certidude/client.conf") | ||||||
| @@ -649,6 +659,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 "Writing certificate to:" in result.output, result.output |     assert "Writing certificate to:" in result.output, result.output | ||||||
|  |     assert os.path.exists("/etc/openvpn/client-to-site.conf") | ||||||
|  |  | ||||||
|     # TODO: assert key, req, cert paths were included correctly in OpenVPN config |     # TODO: assert key, req, cert paths were included correctly in OpenVPN config | ||||||
|     # TODO: test client verification with curl |     # TODO: test client verification with curl | ||||||
| @@ -664,6 +675,7 @@ def test_cli_setup_authority(): | |||||||
|  |  | ||||||
|     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 | ||||||
|  |     assert open("/etc/ipsec.secrets").read() == ": RSA /tmp/ca.example.lan/server_key.pem\n" | ||||||
|  |  | ||||||
|     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 # client conf already exists, remove to regenerate |     assert not result.exception, result.output # client conf already exists, remove to regenerate | ||||||
| @@ -766,6 +778,13 @@ def test_cli_setup_authority(): | |||||||
|     with open("/run/certidude/server.pid") as fh: |     with open("/run/certidude/server.pid") as fh: | ||||||
|         os.kill(int(fh.read()), 1) |         os.kill(int(fh.read()), 1) | ||||||
|  |  | ||||||
|  |     # Note: STORAGE_PATH was mangled above, hence it's /tmp not /var/lib/certidude | ||||||
|  |     assert open("/etc/apparmor.d/local/usr.lib.ipsec.charon").read() == "/tmp/** r,\n" | ||||||
|  |  | ||||||
|     assert len(inbox) == 0, inbox # Make sure all messages were checked |     assert len(inbox) == 0, inbox # Make sure all messages were checked | ||||||
|  |  | ||||||
|     os.waitpid(server_pid, 0) |     os.waitpid(server_pid, 0) | ||||||
|  |  | ||||||
|  |     os.system("service nginx stop") | ||||||
|  |     os.system("service openvpn stop") | ||||||
|  |     os.system("ipsec stop") | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user