commit 677afbd3f873425bcc6f9a23be7efe3066aed70a from: Omar Polo date: Wed Dec 02 14:17:19 2020 UTC clients certs support for CGI internally, gmid doesn’t care if the client issued a certificate, but now we pass that information to the CGI script in some new environment variables. commit - c603f1260de9fb2cc81dd886a5ddb8e43caa9d0c commit + 677afbd3f873425bcc6f9a23be7efe3066aed70a blob - a82bd4f6ff8fb55c88165308a35dc104b9a0bec3 blob + 91d9da971685ea3909deb27798254c548e2353a6 --- README.md +++ README.md @@ -127,6 +127,10 @@ with these additional variables set: > The remote IP address. +`REMOTE_ADDR` + +> The remote IP address. + `DOCUMENT_ROOT` > The root directory being served, the one provided with the @@ -134,6 +138,23 @@ with these additional variables set: > parameter to > **gmid** +`AUTH_TYPE` + +> The string "Certificate" if the client used a certificate, otherwise unset. + +`REMOTE_USER` + +> The subject of the client certificate if provided, otherwise unset. + +`TLS_CLIENT_ISSUER` + +> The is the issuer of the client certificate if provided, otherwise unset. + +`TLS_CLIENT_HASH` + +> The hash of the client certificate if provided, otherwise unset. +> The format is "ALGO:HASH". + Let's say you have a script in */cgi-bin/script* and the user request is blob - 1a8de5bbdc2bc2bbfa8625092f33ae2fa77ab1d1 blob + 069deea7d7fdb0a25c8c72d27b2f91d6ad79f113 --- gmid.1 +++ gmid.1 @@ -110,11 +110,22 @@ The request relative to the script. The query parameters. .It Ev REMOTE_HOST The remote IP address. +.It Ev REMOTE_ADDR +The remote IP address. .It Ev DOCUMENT_ROOT The root directory being served, the one provided with the .Ar d parameter to .Nm +.It Ev AUTH_TYPE +The string "Certificate" if the client used a certificate, otherwise unset. +.It Ev REMOTE_USER +The subject of the client certificate if provided, otherwise unset. +.It Ev TLS_CLIENT_ISSUER +The is the issuer of the client certificate if provided, otherwise unset. +.It Ev TLS_CLIENT_HASH +The hash of the client certificate if provided, otherwise unset. +The format is "ALGO:HASH". .El .Pp Let's say you have a script in blob - 65dd66e88127e265cebd4c49480a448cf3468ca5 blob + d75f9b3dccebe0281d83e43ac8644639db569e75 --- gmid.c +++ gmid.c @@ -56,6 +56,13 @@ #define MAX_USERS 64 #endif +#define SAFE_SETENV(var, val) do { \ + const char *_tmp = (val); \ + if (_tmp == NULL) \ + _tmp = ""; \ + setenv((var), _tmp, 1); \ + } while(0) + enum { S_OPEN, S_INITIALIZING, @@ -502,18 +509,26 @@ start_cgi(const char *spath, const char *relpath, cons argv[0] = argv[1] = ex; /* fix the env */ - setenv("SERVER_SOFTWARE", "gmid", 1); - setenv("SERVER_PORT", portno, 1); + SAFE_SETENV("GATEWAY_INTERFACE", "CGI/1.1"); + SAFE_SETENV("SERVER_SOFTWARE", "gmid"); + SAFE_SETENV("SERVER_PORT", portno); /* setenv("SERVER_NAME", "", 1); */ - setenv("SCRIPT_NAME", spath, 1); - setenv("SCRIPT_EXECUTABLE", ex, 1); - setenv("REQUEST_URI", requri, 1); - setenv("REQUEST_RELATIVE", relpath, 1); - if (query != NULL) - setenv("QUERY_STRING", query, 1); - setenv("REMOTE_HOST", addr, 1); - setenv("DOCUMENT_ROOT", dir, 1); + SAFE_SETENV("SCRIPT_NAME", spath); + SAFE_SETENV("SCRIPT_EXECUTABLE", ex); + SAFE_SETENV("REQUEST_URI", requri); + SAFE_SETENV("REQUEST_RELATIVE", relpath); + SAFE_SETENV("QUERY_STRING", query); + SAFE_SETENV("REMOTE_HOST", addr); + SAFE_SETENV("REMOTE_ADDR", addr); + SAFE_SETENV("DOCUMENT_ROOT", dir); + if (tls_peer_cert_provided(c->ctx)) { + SAFE_SETENV("AUTH_TYPE", "Certificate"); + SAFE_SETENV("REMOTE_USER", tls_peer_cert_subject(c->ctx)); + SAFE_SETENV("TLS_CLIENT_ISSUER", tls_peer_cert_issuer(c->ctx)); + SAFE_SETENV("TLS_CLIENT_HASH", tls_peer_cert_hash(c->ctx)); + } + execvp(ex, argv); goto childerr; } @@ -1036,6 +1051,10 @@ main(int argc, char **argv) if ((conf = tls_config_new()) == NULL) err(1, "tls_config_new"); + /* optionally accept client certs, but don't try to verify them */ + tls_config_verify_client_optional(conf); + tls_config_insecure_noverifycert(conf); + if (tls_config_set_protocols(conf, TLS_PROTOCOL_TLSv1_2 | TLS_PROTOCOL_TLSv1_3) == -1) err(1, "tls_config_set_protocols");