mirror of
https://github.com/laurivosandi/certidude
synced 2024-12-23 00:25:18 +00:00
Merge pull request #4 from plaes/wip
Refactoring and making sure things actually work
This commit is contained in:
commit
79ee9aa22c
@ -1,18 +1,16 @@
|
|||||||
import re
|
import re
|
||||||
import falcon
|
import falcon
|
||||||
import ipaddress
|
import ipaddress
|
||||||
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import types
|
import types
|
||||||
import urllib.request
|
|
||||||
import click
|
import click
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from certidude.wrappers import Request, Certificate
|
from certidude.wrappers import Request, Certificate, CertificateAuthorityConfig
|
||||||
from certidude.auth import login_required
|
from certidude.auth import login_required
|
||||||
from certidude.mailer import Mailer
|
|
||||||
from pyasn1.codec.der import decoder
|
from pyasn1.codec.der import decoder
|
||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
from OpenSSL import crypto
|
|
||||||
from jinja2 import Environment, PackageLoader, Template
|
from jinja2 import Environment, PackageLoader, Template
|
||||||
|
|
||||||
env = Environment(loader=PackageLoader("certidude", "templates"))
|
env = Environment(loader=PackageLoader("certidude", "templates"))
|
||||||
@ -355,4 +353,45 @@ class ApplicationConfigurationResource(CertificateAuthorityBase):
|
|||||||
resp.append_header("Content-Type", "application/ovpn")
|
resp.append_header("Content-Type", "application/ovpn")
|
||||||
resp.append_header("Content-Disposition", "attachment; filename=%s.ovpn" % cn)
|
resp.append_header("Content-Disposition", "attachment; filename=%s.ovpn" % cn)
|
||||||
resp.body = Template(open("/etc/openvpn/%s.template" % ca.slug).read()).render(ctx)
|
resp.body = Template(open("/etc/openvpn/%s.template" % ca.slug).read()).render(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
class StaticResource(object):
|
||||||
|
def __init__(self, root):
|
||||||
|
self.root = os.path.realpath(root)
|
||||||
|
|
||||||
|
def __call__(self, req, resp):
|
||||||
|
|
||||||
|
path = os.path.realpath(os.path.join(self.root, req.path[1:]))
|
||||||
|
if not path.startswith(self.root):
|
||||||
|
raise falcon.HTTPForbidden
|
||||||
|
|
||||||
|
print("Serving:", path)
|
||||||
|
if os.path.exists(path):
|
||||||
|
content_type, content_encoding = mimetypes.guess_type(path)
|
||||||
|
if content_type:
|
||||||
|
resp.append_header("Content-Type", content_type)
|
||||||
|
if content_encoding:
|
||||||
|
resp.append_header("Content-Encoding", content_encoding)
|
||||||
|
resp.append_header("Content-Disposition", "attachment")
|
||||||
|
resp.stream = open(path, "rb")
|
||||||
|
else:
|
||||||
|
resp.status = falcon.HTTP_404
|
||||||
|
resp.body = "File '%s' not found" % req.path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def certidude_app():
|
||||||
|
config = CertificateAuthorityConfig()
|
||||||
|
|
||||||
|
app = falcon.API()
|
||||||
|
app.add_route("/api/{ca}/ocsp/", CertificateStatusResource(config))
|
||||||
|
app.add_route("/api/{ca}/signed/{cn}/openvpn", ApplicationConfigurationResource(config))
|
||||||
|
app.add_route("/api/{ca}/certificate/", CertificateAuthorityResource(config))
|
||||||
|
app.add_route("/api/{ca}/revoked/", RevocationListResource(config))
|
||||||
|
app.add_route("/api/{ca}/signed/{cn}/", SignedCertificateDetailResource(config))
|
||||||
|
app.add_route("/api/{ca}/signed/", SignedCertificateListResource(config))
|
||||||
|
app.add_route("/api/{ca}/request/{cn}/", RequestDetailResource(config))
|
||||||
|
app.add_route("/api/{ca}/request/", RequestListResource(config))
|
||||||
|
app.add_route("/api/{ca}/", IndexResource(config))
|
||||||
|
|
||||||
|
return app
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
import asyncore
|
import asyncore
|
||||||
import click
|
import click
|
||||||
import falcon
|
|
||||||
import logging
|
import logging
|
||||||
import mimetypes
|
|
||||||
import netifaces
|
import netifaces
|
||||||
import os
|
import os
|
||||||
import pwd
|
import pwd
|
||||||
@ -761,30 +759,6 @@ def certidude_sign(common_name, overwrite, lifetime):
|
|||||||
click.echo("Added extension %s: %s" % (key, value))
|
click.echo("Added extension %s: %s" % (key, value))
|
||||||
click.echo()
|
click.echo()
|
||||||
|
|
||||||
class StaticResource(object):
|
|
||||||
def __init__(self, root):
|
|
||||||
self.root = os.path.realpath(root)
|
|
||||||
click.echo("Serving static from: %s" % self.root)
|
|
||||||
|
|
||||||
def __call__(self, req, resp):
|
|
||||||
|
|
||||||
path = os.path.realpath(os.path.join(self.root, req.path[1:]))
|
|
||||||
if not path.startswith(self.root):
|
|
||||||
raise falcon.HTTPForbidden
|
|
||||||
|
|
||||||
print("Serving:", path)
|
|
||||||
if os.path.exists(path):
|
|
||||||
content_type, content_encoding = mimetypes.guess_type(path)
|
|
||||||
if content_type:
|
|
||||||
resp.append_header("Content-Type", content_type)
|
|
||||||
if content_encoding:
|
|
||||||
resp.append_header("Content-Encoding", content_encoding)
|
|
||||||
resp.append_header("Content-Disposition", "attachment")
|
|
||||||
resp.stream = open(path, "rb")
|
|
||||||
else:
|
|
||||||
resp.status = falcon.HTTP_404
|
|
||||||
resp.body = "File '%s' not found" % req.path
|
|
||||||
|
|
||||||
@click.command("serve", help="Run built-in HTTP server")
|
@click.command("serve", help="Run built-in HTTP server")
|
||||||
@click.option("-u", "--user", default="certidude", help="Run as user")
|
@click.option("-u", "--user", default="certidude", help="Run as user")
|
||||||
@click.option("-p", "--port", default=80, help="Listen port")
|
@click.option("-p", "--port", default=80, help="Listen port")
|
||||||
@ -798,34 +772,27 @@ def certidude_serve(user, port, listen, enable_signature):
|
|||||||
|
|
||||||
click.echo("Serving API at %s:%d" % (listen, port))
|
click.echo("Serving API at %s:%d" % (listen, port))
|
||||||
import pwd
|
import pwd
|
||||||
import falcon
|
|
||||||
from wsgiref.simple_server import make_server, WSGIServer
|
from wsgiref.simple_server import make_server, WSGIServer
|
||||||
from socketserver import ThreadingMixIn
|
from socketserver import ThreadingMixIn
|
||||||
from certidude.api import CertificateAuthorityResource, \
|
from certidude.api import certidude_app, StaticResource
|
||||||
RequestDetailResource, RequestListResource, \
|
|
||||||
SignedCertificateDetailResource, SignedCertificateListResource, \
|
|
||||||
RevocationListResource, IndexResource, ApplicationConfigurationResource, \
|
|
||||||
CertificateStatusResource
|
|
||||||
|
|
||||||
class ThreadingWSGIServer(ThreadingMixIn, WSGIServer):
|
class ThreadingWSGIServer(ThreadingMixIn, WSGIServer):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
click.echo("Listening on %s:%d" % (listen, port))
|
click.echo("Listening on %s:%d" % (listen, port))
|
||||||
|
|
||||||
app = falcon.API()
|
app = certidude_app()
|
||||||
app.add_route("/api/{ca}/ocsp/", CertificateStatusResource(config))
|
|
||||||
app.add_route("/api/{ca}/signed/{cn}/openvpn", ApplicationConfigurationResource(config))
|
|
||||||
app.add_route("/api/{ca}/certificate/", CertificateAuthorityResource(config))
|
|
||||||
app.add_route("/api/{ca}/revoked/", RevocationListResource(config))
|
|
||||||
app.add_route("/api/{ca}/signed/{cn}/", SignedCertificateDetailResource(config))
|
|
||||||
app.add_route("/api/{ca}/signed/", SignedCertificateListResource(config))
|
|
||||||
app.add_route("/api/{ca}/request/{cn}/", RequestDetailResource(config))
|
|
||||||
app.add_route("/api/{ca}/request/", RequestListResource(config))
|
|
||||||
app.add_route("/api/{ca}/", IndexResource(config))
|
|
||||||
|
|
||||||
app.add_sink(StaticResource(os.path.join(os.path.dirname(__file__), "static")))
|
app.add_sink(StaticResource(os.path.join(os.path.dirname(__file__), "static")))
|
||||||
|
|
||||||
httpd = make_server(listen, port, app, ThreadingWSGIServer)
|
httpd = make_server(listen, port, app, ThreadingWSGIServer)
|
||||||
|
|
||||||
if user:
|
if user:
|
||||||
|
# Load required utils which cannot be imported from chroot
|
||||||
|
# TODO: Figure out better approach
|
||||||
|
from jinja2.debug import make_traceback as _make_traceback
|
||||||
|
"".encode("charmap")
|
||||||
|
|
||||||
_, _, uid, gid, gecos, root, shell = pwd.getpwnam(user)
|
_, _, uid, gid, gecos, root, shell = pwd.getpwnam(user)
|
||||||
if uid == 0:
|
if uid == 0:
|
||||||
click.echo("Please specify unprivileged user")
|
click.echo("Please specify unprivileged user")
|
||||||
@ -835,7 +802,7 @@ def certidude_serve(user, port, listen, enable_signature):
|
|||||||
os.setuid(uid)
|
os.setuid(uid)
|
||||||
os.umask(0o007)
|
os.umask(0o007)
|
||||||
elif os.getuid() == 0:
|
elif os.getuid() == 0:
|
||||||
click.echo("Warning: running as root, this is not reccommended!")
|
click.echo("Warning: running as root, this is not recommended!")
|
||||||
httpd.serve_forever()
|
httpd.serve_forever()
|
||||||
|
|
||||||
@click.group("strongswan", help="strongSwan helpers")
|
@click.group("strongswan", help="strongSwan helpers")
|
||||||
|
@ -1,29 +1,14 @@
|
|||||||
|
"""
|
||||||
|
certidude.wsgi
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Certidude web app factory for WSGI-compatible web servers
|
||||||
|
"""
|
||||||
import os
|
import os
|
||||||
import falcon
|
from certidude.api import certidude_app
|
||||||
from certidude.wrappers import CertificateAuthorityConfig
|
|
||||||
from certidude.api import CertificateAuthorityResource, \
|
|
||||||
RequestDetailResource, RequestListResource, \
|
|
||||||
SignedCertificateDetailResource, SignedCertificateListResource, \
|
|
||||||
RevocationListResource, IndexResource, ApplicationConfigurationResource, \
|
|
||||||
CertificateStatusResource
|
|
||||||
|
|
||||||
# TODO: deduplicate routing code
|
|
||||||
# TODO: set up /run/certidude/api paths and permissions
|
# TODO: set up /run/certidude/api paths and permissions
|
||||||
|
|
||||||
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"
|
||||||
|
|
||||||
app = falcon.API()
|
app = certidude_app()
|
||||||
app.add_route("/api/{ca}/ocsp/", CertificateStatusResource(config))
|
|
||||||
app.add_route("/api/{ca}/signed/{cn}/openvpn", ApplicationConfigurationResource(config))
|
|
||||||
app.add_route("/api/{ca}/certificate/", CertificateAuthorityResource(config))
|
|
||||||
app.add_route("/api/{ca}/revoked/", RevocationListResource(config))
|
|
||||||
app.add_route("/api/{ca}/signed/{cn}/", SignedCertificateDetailResource(config))
|
|
||||||
app.add_route("/api/{ca}/signed/", SignedCertificateListResource(config))
|
|
||||||
app.add_route("/api/{ca}/request/{cn}/", RequestDetailResource(config))
|
|
||||||
app.add_route("/api/{ca}/request/", RequestListResource(config))
|
|
||||||
app.add_route("/api/{ca}/", IndexResource(config))
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user