diff --git a/warden3/warden_server/warden_server.py b/warden3/warden_server/warden_server.py index 3f29de1291eb60c26204c4037659d2caf89dc395..e20d2d7adb59ab111296e5b2a7f9fdfea80cd9e2 100755 --- a/warden3/warden_server/warden_server.py +++ b/warden3/warden_server/warden_server.py @@ -137,7 +137,7 @@ def get_clean_root_logger(level=logging.INFO): # is not exactly supported by logging module. # So, we look directly inside logger class and clean up handlers/filters # manually. - logger = logging.getLogger() # no need to create new + logger = logging.getLogger(__name__) logger.setLevel(level) while logger.handlers: logger.removeHandler(logger.handlers[0]) @@ -354,7 +354,7 @@ class X509Authenticator(PlainAuthenticator): cert_names = self.get_cert_dns_names(env["SSL_CLIENT_CERT"]) except: exception = self.req.error(message="authenticate: cannot get or parse certificate from env", error=403, exc=sys.exc_info(), env=env) - exception.log(logging.getLogger()) + exception.log(logging.getLogger(__name__)) return None args["hostnames"] = [cert_names] @@ -362,6 +362,38 @@ class X509Authenticator(PlainAuthenticator): return PlainAuthenticator.authenticate(self, env, args) +class X509NameAuthenticator(PlainAuthenticator): + + def get_cert_name(self, pem): + + cert = M2Crypto.X509.load_cert_string(pem) + + subj = cert.get_subject() + commons = [n.get_data().as_text() for n in subj.get_entries_by_nid(subj.nid["CN"])] + + return commons[0] + + + def authenticate(self, env, args): + try: + name = self.get_cert_name(env["SSL_CLIENT_CERT"]) + except: + exception = self.req.error(message="authenticate: cannot get or parse certificate from env", error=403, exc=sys.exc_info(), env=env) + exception.log(logging.getLogger(__name__)) + return None + + print("cert name: %s" % name) + client = self.db.get_client_by_name(None, name, None) + + if not client: + logging.info("authenticate: client not found by name: \"%s\"" % (name)) + return None + + logging.info("authenticate: %s" % str(client)) + + return client + + class NoValidator(ObjectReq): def __init__(self, req): @@ -638,7 +670,7 @@ class MySQL(ObjectReq): # events get skipped silently. err = self.req.error(message="Unable to deserialize JSON event from db, id=%s" % r["id"], error=500, exc=sys.exc_info(), id=r["id"]) - err.log(logging.getLogger(), prio=logging.WARNING) + err.log(logging.getLogger(__name__), prio=logging.WARNING) events.append(e) return { @@ -673,7 +705,7 @@ class MySQL(ObjectReq): except Exception as e: self.con.rollback() exception = self.req.error(message="DB error", error=500, exc=sys.exc_info(), env=env) - exception.log(logging.getLogger()) + exception.log(logging.getLogger(__name__)) return [{"error": 500, "message": "DB error %s" % type(e).__name__}] @@ -864,7 +896,7 @@ class Server(ObjectReq): if exception: status = "%d %s" % exception.get_http_err_msg() output = json.dumps(exception.to_dict(), default=lambda v: str(v)) - exception.log(logging.getLogger()) + exception.log(logging.getLogger(__name__)) # Make sure everything is properly encoded - JSON and various function # may spit out unicode instead of str and it gets propagated up (str @@ -1148,7 +1180,7 @@ def build_server(conf): section_def = { "log": ["FileLogger", "SysLogger"], "db": ["MySQL"], - "auth": ["X509Authenticator", "PlainAuthenticator"], + "auth": ["X509Authenticator", "PlainAuthenticator", "X509NameAuthenticator"], "validator": ["JSONSchemaValidator", "NoValidator"], "handler": ["WardenHandler"], "server": ["Server"] @@ -1175,6 +1207,10 @@ def build_server(conf): "req": {"type": obj, "default": "req"}, "db": {"type": obj, "default": "db"} }, + "X509NameAuthenticator": { + "req": {"type": obj, "default": "req"}, + "db": {"type": obj, "default": "db"} + }, "NoValidator": { "req": {"type": obj, "default": "req"}, },