aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmar Polo <op@omarpolo.com>2021-02-07 21:47:01 +0000
committerOmar Polo <op@omarpolo.com>2021-02-07 21:47:01 +0000
commitb63e30ff449ee1cf0091d5431f9b72cdd3b1e7e0 (patch)
tree8eea2f7aea3bbed3ee91517076ca75e69b2296f7
parent9f006a2127398af12ecf9159cd5ef28b3685e7a6 (diff)
define TLS_CLIENT_NOT_BEFORE/NOT_AFTER in CGI scripts
-rw-r--r--ChangeLog1
-rw-r--r--ex.c36
-rw-r--r--gmid.17
-rw-r--r--gmid.h3
-rwxr-xr-xregress/env2
-rw-r--r--server.c19
6 files changed, 52 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 187a4ac..1f98653 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
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
+ (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, &notbefore)
+ || !recv_time(exfd, &notafter)
|| !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 <signal.h>
#include <stdio.h>
#include <stdlib.h>
+#include <time.h>
#include <tls.h>
#include <unistd.h>
@@ -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;