certidude/certidude/api/lease.py

48 lines
2.1 KiB
Python

import click
import falcon
import logging
import xattr
from datetime import datetime
from certidude import config, authority, push
from certidude.auth import login_required, authorize_admin, authorize_server
from certidude.decorators import serialize
logger = logging.getLogger(__name__)
# TODO: lease namespacing (?)
class LeaseDetailResource(object):
@serialize
@login_required
@authorize_admin
def on_get(self, req, resp, cn):
try:
path, buf, cert, signed, expires = authority.get_signed(cn)
return dict(
last_seen = xattr.getxattr(path, "user.lease.last_seen").decode("ascii"),
inner_address = xattr.getxattr(path, "user.lease.inner_address").decode("ascii"),
outer_address = xattr.getxattr(path, "user.lease.outer_address").decode("ascii")
)
except EnvironmentError: # Certificate or attribute not found
raise falcon.HTTPNotFound()
class LeaseResource(object):
@authorize_server
def on_post(self, req, resp):
common_name = req.get_param("client", required=True)
path, buf, cert, signed, expires = authority.get_signed(common_name) # TODO: catch exceptions
if req.get_param("serial") and cert.serial_number != req.get_param_as_int("serial"): # OCSP-ish solution for OpenVPN, not exposed for StrongSwan
raise falcon.HTTPForbidden("Forbidden", "Invalid serial number supplied")
xattr.setxattr(path, "user.lease.outer_address", req.get_param("outer_address", required=True).encode("ascii"))
xattr.setxattr(path, "user.lease.inner_address", req.get_param("inner_address", required=True).encode("ascii"))
xattr.setxattr(path, "user.lease.last_seen", datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z")
push.publish("lease-update", common_name)
# client-disconnect is pretty much unusable:
# - Android Connect Client results "IP packet with unknown IP version=2" on gateway
# - NetworkManager just kills OpenVPN client, disconnect is never reported
# - Disconnect is also not reported when uplink connection dies or laptop goes to sleep