|
@@ -0,0 +1,66 @@
|
|
|
|
+import cherrypy
|
|
|
|
+from bottle import (
|
|
|
|
+ default_app,
|
|
|
|
+ auth_basic,
|
|
|
|
+ HTTPError,
|
|
|
|
+ HTTPResponse,
|
|
|
|
+ route,
|
|
|
|
+ request,
|
|
|
|
+)
|
|
|
|
+from passlib.hash import bcrypt
|
|
|
|
+from hashes import users
|
|
|
|
+
|
|
|
|
+def basic_auth(user, password, realm=None):
|
|
|
|
+ if realm in users and user in users[realm]:
|
|
|
|
+ return bcrypt.verify(password, users[realm][user])
|
|
|
|
+ print(f"user not found {realm} {user}")
|
|
|
|
+ return False
|
|
|
|
+
|
|
|
|
+def verify_cert(pem):
|
|
|
|
+ return True
|
|
|
|
+
|
|
|
|
+def auth_client_cert(check):
|
|
|
|
+ def decorator(func):
|
|
|
|
+ def wrapper(*a, **ka):
|
|
|
|
+ if 'X-Forwarded-Tls-Client-Cert' in request.headers:
|
|
|
|
+ cert = request.headers['X-Forwarded-Tls-Client-Cert']
|
|
|
|
+ else:
|
|
|
|
+ cert = None
|
|
|
|
+ if cert and verify_cert(cert):
|
|
|
|
+ return HTTPResponse(status=200)
|
|
|
|
+ return func(*a, **ka)
|
|
|
|
+ return wrapper
|
|
|
|
+ return decorator
|
|
|
|
+
|
|
|
|
+def auth_basic(check, text="Access denied"):
|
|
|
|
+ ''' Callback decorator to require HTTP auth (basic).
|
|
|
|
+ TODO: Add route(check_auth=...) parameter. '''
|
|
|
|
+ def decorator(func):
|
|
|
|
+ def wrapper(vhost, *a, **ka):
|
|
|
|
+ realm = vhost
|
|
|
|
+ user, password = request.auth or (None, None)
|
|
|
|
+ if user is None or not check(user, password, realm=realm):
|
|
|
|
+ err = HTTPError(401, text)
|
|
|
|
+ err.add_header('WWW-Authenticate', 'Basic realm="%s"' % realm)
|
|
|
|
+ return err
|
|
|
|
+ return func(vhost, *a, **ka)
|
|
|
|
+ return wrapper
|
|
|
|
+ return decorator
|
|
|
|
+
|
|
|
|
+@route('/authenticate/<vhost>')
|
|
|
|
+@auth_client_cert(verify_cert)
|
|
|
|
+@auth_basic(basic_auth)
|
|
|
|
+def auth(vhost):
|
|
|
|
+ return HTTPResponse(status=200)
|
|
|
|
+
|
|
|
|
+cherrypy.server.ssl_certificate = '/etc/private-ca/server-cert.pem'
|
|
|
|
+cherrypy.server.ssl_private_key = '/etc/private-ca/server-key.pem'
|
|
|
|
+
|
|
|
|
+cherrypy.config.update({
|
|
|
|
+ 'server.socket_host': "0.0.0.0",
|
|
|
|
+ 'server.socket_port': 1234,
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+cherrypy.tree.graft(default_app(), "/")
|
|
|
|
+cherrypy.engine.start()
|
|
|
|
+cherrypy.engine.block()
|