diff --git a/ChangeLog b/ChangeLog index 187a4ac..1f98653 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2021-02-07 Omar Polo * ex.c (do_exec): [cgi] split the query in words if needed and add them to the argv + (launch_cgi): define TLS_CLIENT_NOT_BEFORE/NOT_AFTER in CGI scripts * parse.y (option): added prefork option diff --git a/ex.c b/ex.c index 0a65472..8d9f496 100644 --- a/ex.c +++ b/ex.c @@ -131,6 +131,18 @@ recv_vhost(int fd, struct vhost **vhost) return 1; } +int +send_time(int fd, time_t t) +{ + return write(fd, &t, sizeof(t)) == sizeof(t); +} + +int +recv_time(int fd, time_t *t) +{ + return read(fd, t, sizeof(*t)) == sizeof(*t); +} + /* send d though fd. see /usr/src/usr.sbin/syslogd/privsep_fdpass.c * for an example */ int @@ -270,11 +282,26 @@ do_exec(const char *ex, const char *spath, char *query) warn("execvp: %s", argv[0]); } +static inline void +setenv_time(const char *var, time_t t) +{ + char timebuf[21]; + struct tm tminfo; + + if (t == -1) + return; + + strftime(timebuf, sizeof(timebuf), "%FT%TZ", + gmtime_r(&t, &tminfo)); + setenv(var, timebuf, 1); +} + /* fd or -1 on error */ static int launch_cgi(struct iri *iri, const char *spath, char *relpath, const char *addr, const char *ruser, const char *cissuer, - const char *chash, struct vhost *vhost) + const char *chash, time_t notbefore, time_t notafter, + struct vhost *vhost) { int p[2]; /* read end, write end */ @@ -344,6 +371,8 @@ launch_cgi(struct iri *iri, const char *spath, char *relpath, safe_setenv("REMOTE_USER", ruser); safe_setenv("TLS_CLIENT_ISSUER", cissuer); safe_setenv("TLS_CLIENT_HASH", chash); + setenv_time("TLS_CLIENT_NOT_AFTER", notafter); + setenv_time("TLS_CLIENT_NOT_BEFORE", notbefore); strlcpy(path, ex, sizeof(path)); @@ -374,6 +403,7 @@ executor_main() char *spath, *relpath, *addr, *ruser, *cissuer, *chash; struct vhost *vhost; struct iri iri; + time_t notbefore, notafter; int d; #ifdef __OpenBSD__ @@ -397,11 +427,13 @@ executor_main() || !recv_string(exfd, &ruser) || !recv_string(exfd, &cissuer) || !recv_string(exfd, &chash) + || !recv_time(exfd, ¬before) + || !recv_time(exfd, ¬after) || !recv_vhost(exfd, &vhost)) break; d = launch_cgi(&iri, spath, relpath, addr, ruser, cissuer, chash, - vhost); + notbefore, notafter, vhost); if (!send_fd(exfd, d)) break; close(d); diff --git a/gmid.1 b/gmid.1 index 08b8e6e..faf3e4f 100644 --- a/gmid.1 +++ b/gmid.1 @@ -351,6 +351,13 @@ unset. The hash of the client certificate if provided, otherwise unset. The format is .Dq ALGO:HASH . +.It Ev TLS_CLIENT_NOT_AFTER +The time corresponding to the end of the validity period of the peer +certificate in the ISO 8601 format +.Pq e.g. Dq 2021-02-07T20:17:41Z . +.It Ev TLS_CLIENT_NOT_BEFORE +The time corresponding to the start of the validity period of the peer +certificate in the ISO 8601 format. .El .Pp .Sh MIME diff --git a/gmid.h b/gmid.h index 1beb95e..f6567ce 100644 --- a/gmid.h +++ b/gmid.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -242,6 +243,8 @@ int recv_iri(int, struct iri*); void free_recvd_iri(struct iri*); int send_vhost(int, struct vhost*); int recv_vhost(int, struct vhost**); +int send_time(int, time_t); +int recv_time(int, time_t*); int send_fd(int, int); int recv_fd(int); int executor_main(void); diff --git a/regress/env b/regress/env index d44783f..d7e2e12 100755 --- a/regress/env +++ b/regress/env @@ -42,6 +42,8 @@ echo AUTH_TYPE=$AUTH_TYPE echo REMOTE_USER=$REMOTE_USER echo TLS_CLIENT_ISSUER=$TLS_CLIENT_ISSUER echo TLS_CLIENT_HASH=$TLS_CLIENT_HASH +echo TLS_CLIENT_NOT_AFTER=$TLS_CLIENT_NOT_AFTER +echo TLS_CLIENT_NOT_BEFORE=$TLS_CLIENT_NOT_BEFORE echo echo echo " CGI Argument List" diff --git a/server.c b/server.c index 52c7420..6feb7b5 100644 --- a/server.c +++ b/server.c @@ -550,7 +550,6 @@ start_cgi(const char *spath, const char *relpath, struct pollfd *fds, struct client *c) { char addr[NI_MAXHOST]; - const char *ruser, *cissuer, *chash; int e; e = getnameinfo((struct sockaddr*)&c->addr, sizeof(c->addr), @@ -560,23 +559,15 @@ start_cgi(const char *spath, const char *relpath, if (e != 0) goto err; - if (tls_peer_cert_provided(c->ctx)) { - ruser = tls_peer_cert_subject(c->ctx); - cissuer = tls_peer_cert_issuer(c->ctx); - chash = tls_peer_cert_hash(c->ctx); - } else { - ruser = NULL; - cissuer = NULL; - chash = NULL; - } - if (!send_iri(exfd, &c->iri) || !send_string(exfd, spath) || !send_string(exfd, relpath) || !send_string(exfd, addr) - || !send_string(exfd, ruser) - || !send_string(exfd, cissuer) - || !send_string(exfd, chash) + || !send_string(exfd, tls_peer_cert_subject(c->ctx)) + || !send_string(exfd, tls_peer_cert_issuer(c->ctx)) + || !send_string(exfd, tls_peer_cert_hash(c->ctx)) + || !send_time(exfd, tls_peer_cert_notbefore(c->ctx)) + || !send_time(exfd, tls_peer_cert_notafter(c->ctx)) || !send_vhost(exfd, c->host)) goto err;