commit 774cc56ed257aed6f744768dd8d35ac4fa5bdb04
parent ca4ffa457c0f93d20e70de92b2f64f4e291207aa
Author: Joris Vink <joris@coders.se>
Date: Sat, 11 Dec 2021 22:37:15 +0100
Python: Add an req.connection.x509dict
This dictionary for now only contains the subject and issuer names
from the client certificate (if one was provided) with their
X509_NAME components.
Eg:
{
"issuer": {
"C": "SE",
"O": "kore autogen: x509name-test",
"CN": "localhost"
},
"subject": {
"C": "SE",
"O": "kore autogen: x509name-test",
"CN": "localhost"
}
}
Diffstat:
2 files changed, 95 insertions(+), 0 deletions(-)
diff --git a/include/kore/python_methods.h b/include/kore/python_methods.h
@@ -696,11 +696,13 @@ static PyObject *pyconnection_get_fd(struct pyconnection *, void *);
static PyObject *pyconnection_get_addr(struct pyconnection *, void *);
static PyObject *pyconnection_get_peer_x509(struct pyconnection *, void *);
+static PyObject *pyconnection_get_peer_x509dict(struct pyconnection *, void *);
static PyGetSetDef pyconnection_getset[] = {
GETTER("fd", pyconnection_get_fd),
GETTER("addr", pyconnection_get_addr),
GETTER("x509", pyconnection_get_peer_x509),
+ GETTER("x509dict", pyconnection_get_peer_x509dict),
GETTER(NULL, NULL),
};
diff --git a/src/python.c b/src/python.c
@@ -119,6 +119,9 @@ static int pyhttp_iterobj_chunk_sent(struct netbuf *);
static int pyhttp_iterobj_next(struct pyhttp_iterobj *);
static void pyhttp_iterobj_disconnect(struct connection *);
+static int pyconnection_x509_cb(void *, int, int, const char *,
+ const void *, size_t, int);
+
#if defined(KORE_USE_PGSQL)
static int pykore_pgsql_result(struct pykore_pgsql *);
static void pykore_pgsql_callback(struct kore_pgsql *, void *);
@@ -2845,6 +2848,96 @@ pyconnection_get_peer_x509(struct pyconnection *pyc, void *closure)
return (bytes);
}
+static PyObject *
+pyconnection_get_peer_x509dict(struct pyconnection *pyc, void *closure)
+{
+ X509_NAME *name;
+ PyObject *dict, *issuer, *subject, *ret;
+
+ ret = NULL;
+ issuer = NULL;
+ subject = NULL;
+
+ if (pyc->c->cert == NULL) {
+ Py_RETURN_NONE;
+ }
+
+ if ((dict = PyDict_New()) == NULL)
+ goto out;
+
+ if ((issuer = PyDict_New()) == NULL)
+ goto out;
+
+ if (PyDict_SetItemString(dict, "issuer", issuer) == -1)
+ goto out;
+
+ if ((subject = PyDict_New()) == NULL)
+ goto out;
+
+ if (PyDict_SetItemString(dict, "subject", subject) == -1)
+ goto out;
+
+ PyErr_Clear();
+
+ if ((name = X509_get_issuer_name(pyc->c->cert)) == NULL) {
+ PyErr_Format(PyExc_RuntimeError,
+ "X509_get_issuer_name: %s", ssl_errno_s);
+ goto out;
+ }
+
+ if (!kore_x509name_foreach(name, 0, issuer, pyconnection_x509_cb)) {
+ if (PyErr_Occurred() == NULL) {
+ PyErr_Format(PyExc_RuntimeError,
+ "failed to add issuer name to dictionary");
+ }
+ goto out;
+ }
+
+ if ((name = X509_get_subject_name(pyc->c->cert)) == NULL) {
+ PyErr_Format(PyExc_RuntimeError,
+ "X509_get_subject_name: %s", ssl_errno_s);
+ goto out;
+ }
+
+ if (!kore_x509name_foreach(name, 0, subject, pyconnection_x509_cb)) {
+ if (PyErr_Occurred() == NULL) {
+ PyErr_Format(PyExc_RuntimeError,
+ "failed to add subject name to dictionary");
+ }
+ goto out;
+ }
+
+ ret = dict;
+ dict = NULL;
+
+out:
+ Py_XDECREF(dict);
+ Py_XDECREF(issuer);
+ Py_XDECREF(subject);
+
+ return (ret);
+}
+
+static int
+pyconnection_x509_cb(void *udata, int islast, int nid, const char *field,
+ const void *data, size_t len, int flags)
+{
+ PyObject *dict, *obj;
+
+ dict = udata;
+
+ if ((obj = PyUnicode_FromStringAndSize(data, len)) == NULL)
+ return (KORE_RESULT_ERROR);
+
+ if (PyDict_SetItemString(dict, field, obj) == -1) {
+ Py_DECREF(obj);
+ return (KORE_RESULT_ERROR);
+ }
+
+ Py_DECREF(obj);
+ return (KORE_RESULT_OK);
+}
+
static void
pytimer_run(void *arg, u_int64_t now)
{