define TLS_CLIENT_NOT_BEFORE/NOT_AFTER in CGI scripts

This commit is contained in:
Omar Polo 2021-02-07 21:47:01 +00:00
parent 9f006a2127
commit b63e30ff44
6 changed files with 52 additions and 16 deletions

View File

@ -1,6 +1,7 @@
2021-02-07 Omar Polo <op@omarpolo.com> 2021-02-07 Omar Polo <op@omarpolo.com>
* ex.c (do_exec): [cgi] split the query in words if needed and add them to the argv * 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 * parse.y (option): added prefork option

36
ex.c
View File

@ -131,6 +131,18 @@ recv_vhost(int fd, struct vhost **vhost)
return 1; 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 /* send d though fd. see /usr/src/usr.sbin/syslogd/privsep_fdpass.c
* for an example */ * for an example */
int int
@ -270,11 +282,26 @@ do_exec(const char *ex, const char *spath, char *query)
warn("execvp: %s", argv[0]); 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 */ /* fd or -1 on error */
static int static int
launch_cgi(struct iri *iri, const char *spath, char *relpath, launch_cgi(struct iri *iri, const char *spath, char *relpath,
const char *addr, const char *ruser, const char *cissuer, 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 */ 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("REMOTE_USER", ruser);
safe_setenv("TLS_CLIENT_ISSUER", cissuer); safe_setenv("TLS_CLIENT_ISSUER", cissuer);
safe_setenv("TLS_CLIENT_HASH", chash); 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)); strlcpy(path, ex, sizeof(path));
@ -374,6 +403,7 @@ executor_main()
char *spath, *relpath, *addr, *ruser, *cissuer, *chash; char *spath, *relpath, *addr, *ruser, *cissuer, *chash;
struct vhost *vhost; struct vhost *vhost;
struct iri iri; struct iri iri;
time_t notbefore, notafter;
int d; int d;
#ifdef __OpenBSD__ #ifdef __OpenBSD__
@ -397,11 +427,13 @@ executor_main()
|| !recv_string(exfd, &ruser) || !recv_string(exfd, &ruser)
|| !recv_string(exfd, &cissuer) || !recv_string(exfd, &cissuer)
|| !recv_string(exfd, &chash) || !recv_string(exfd, &chash)
|| !recv_time(exfd, &notbefore)
|| !recv_time(exfd, &notafter)
|| !recv_vhost(exfd, &vhost)) || !recv_vhost(exfd, &vhost))
break; break;
d = launch_cgi(&iri, spath, relpath, addr, ruser, cissuer, chash, d = launch_cgi(&iri, spath, relpath, addr, ruser, cissuer, chash,
vhost); notbefore, notafter, vhost);
if (!send_fd(exfd, d)) if (!send_fd(exfd, d))
break; break;
close(d); close(d);

7
gmid.1
View File

@ -351,6 +351,13 @@ unset.
The hash of the client certificate if provided, otherwise unset. The hash of the client certificate if provided, otherwise unset.
The format is The format is
.Dq ALGO:HASH . .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 .El
.Pp .Pp
.Sh MIME .Sh MIME

3
gmid.h
View File

@ -28,6 +28,7 @@
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#include <tls.h> #include <tls.h>
#include <unistd.h> #include <unistd.h>
@ -242,6 +243,8 @@ int recv_iri(int, struct iri*);
void free_recvd_iri(struct iri*); void free_recvd_iri(struct iri*);
int send_vhost(int, struct vhost*); int send_vhost(int, struct vhost*);
int recv_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 send_fd(int, int);
int recv_fd(int); int recv_fd(int);
int executor_main(void); int executor_main(void);

View File

@ -42,6 +42,8 @@ echo AUTH_TYPE=$AUTH_TYPE
echo REMOTE_USER=$REMOTE_USER echo REMOTE_USER=$REMOTE_USER
echo TLS_CLIENT_ISSUER=$TLS_CLIENT_ISSUER echo TLS_CLIENT_ISSUER=$TLS_CLIENT_ISSUER
echo TLS_CLIENT_HASH=$TLS_CLIENT_HASH 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 echo
echo " CGI Argument List" echo " CGI Argument List"

View File

@ -550,7 +550,6 @@ start_cgi(const char *spath, const char *relpath,
struct pollfd *fds, struct client *c) struct pollfd *fds, struct client *c)
{ {
char addr[NI_MAXHOST]; char addr[NI_MAXHOST];
const char *ruser, *cissuer, *chash;
int e; int e;
e = getnameinfo((struct sockaddr*)&c->addr, sizeof(c->addr), e = getnameinfo((struct sockaddr*)&c->addr, sizeof(c->addr),
@ -560,23 +559,15 @@ start_cgi(const char *spath, const char *relpath,
if (e != 0) if (e != 0)
goto err; 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) if (!send_iri(exfd, &c->iri)
|| !send_string(exfd, spath) || !send_string(exfd, spath)
|| !send_string(exfd, relpath) || !send_string(exfd, relpath)
|| !send_string(exfd, addr) || !send_string(exfd, addr)
|| !send_string(exfd, ruser) || !send_string(exfd, tls_peer_cert_subject(c->ctx))
|| !send_string(exfd, cissuer) || !send_string(exfd, tls_peer_cert_issuer(c->ctx))
|| !send_string(exfd, chash) || !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)) || !send_vhost(exfd, c->host))
goto err; goto err;