1
0
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:
Lauri Võsandi 2015-09-06 09:14:37 +03:00
commit 79ee9aa22c
3 changed files with 61 additions and 70 deletions

View File

@ -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"))
@ -356,3 +354,44 @@ class ApplicationConfigurationResource(CertificateAuthorityBase):
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

View File

@ -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")

View File

@ -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))