Compare commits

...

7 Commits

Author SHA1 Message Date
Omar Polo 97b306cbee add an implicit fastcgi parameter: GEMINI_SEARCH_STRING
it’s the QUERY_STRING decoded if it’s a search-string (i.e. not a
key-value pair.)  It’s useful for scripts to avoid percent-decoding
the querystring in the most common case of a query, because in Gemini
querystrings key-value paired are not common.

Idea from a discussion with Allen Sobot.
2022-11-27 15:35:10 +00:00
Omar Polo 77718c121f correction: QUERY_STRING is *not* urldecoded.
RFC3875 § 4.1.7 states that "the QUERY_STRING variable contains a
URL-encoded search or parameter string".
2022-11-27 12:52:17 +00:00
Omar Polo 17493a486c return after FCGI_END_REQUEST
this fixes a possible crash if `client_write' closes the connection,
because client_close can end up freeing the fastcgi bufferevent while
we're looping.

We don't support fastcgi multiplexing, so once we get an END_REQUEST
there's nothing more to do.

Prodded into looking here after a bug report from Allen Sobot, thanks!
2022-11-27 10:34:30 +00:00
Omar Polo eb4f96c10a typo 2022-11-27 10:06:08 +00:00
Omar Polo e92efb0d8e don't crash when specifying fcgi UNIX sockets to connect to 2022-11-27 10:05:56 +00:00
Omar Polo 872a717687 when switching user also set the groups 2022-11-27 10:05:13 +00:00
Omar Polo b24c6fcc1c adjust pledge/unveil on OpenBSD
to connect to unix-domain sockets the `unix' pledge is needed and also
unveil "w".  gmid can't mutate files because it doesn't pledge `wpath'
nor `cpath'.
2022-11-27 10:04:39 +00:00
7 changed files with 29 additions and 10 deletions

11
fcgi.c
View File

@ -290,7 +290,7 @@ fcgi_read(struct bufferevent *bev, void *d)
/* TODO: do something with the status? */
c->type = REQUEST_DONE;
client_write(c->bev, c);
break;
return;
case FCGI_STDERR:
/* discard stderr (for now) */
@ -344,6 +344,7 @@ void
fcgi_req(struct client *c)
{
char addr[NI_MAXHOST], buf[22];
char *qs;
int e;
time_t tim;
struct tm tminfo;
@ -368,6 +369,14 @@ fcgi_req(struct client *c)
fcgi_send_param(c->cgibev, "SERVER_PROTOCOL", "GEMINI");
fcgi_send_param(c->cgibev, "SERVER_SOFTWARE", GMID_VERSION);
if (*c->iri.query != '\0' &&
strchr(c->iri.query, '=') == NULL &&
(qs = strdup(c->iri.query)) != NULL) {
pct_decode_str(qs);
fcgi_send_param(c->cgibev, "GEMINI_SEARCH_STRING", qs);
free(qs);
}
TAILQ_FOREACH(p, &c->host->params, envs) {
fcgi_send_param(c->cgibev, p->name, p->value);
}

7
gmid.c
View File

@ -296,9 +296,10 @@ drop_priv(void)
}
if (pw != NULL) {
if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
fatal("setresuid(%d): %s", pw->pw_uid,
strerror(errno));
if (setgroups(1, &pw->pw_gid) == -1 ||
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1 ||
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
fatal("cannot drop privileges");
}
if (getuid() == 0)

View File

@ -286,6 +286,12 @@ Full path to the FastCGI script being executed.
The full IRI of the request.
.It Ev GEMINI_URL_PATH
The path of the request.
.It Ev GEMINI_SEARCH_STRING
The decoded
.Ev QUERY_STRING
if defined in the request and if it doesn't contain any unencoded
.Sq =
characters, otherwise unset.
.It Ev PATH_INFO
The portion of the requested path that is derived from the the IRI
path hierarchy following the part that identifies the script itself.
@ -301,7 +307,7 @@ builds this by appending the
.Ev PATH_INFO
to the virtual host directory root.
.It Ev QUERY_STRING
The decoded query string.
The URL-encoded search or parameter string.
.It Ev REMOTE_ADDR , Ev REMOTE_HOST
Textual representation of the client IP.
.It Ev REQUEST_METHOD

4
iri.c
View File

@ -488,7 +488,9 @@ pct_decode_str(char *s)
char *t;
for (t = s; *t; ++t) {
if (*t == '%' && valid_pct_enc_string(t))
if (*t == '+')
*t = ' ';
else if (*t == '%' && valid_pct_enc_string(t))
pct_decode(t);
}

View File

@ -1178,7 +1178,8 @@ fastcgi_conf(const char *path, const char *port)
if (*f->path == '\0') {
f->id = i;
(void) strlcpy(f->path, path, sizeof(f->path));
(void) strlcpy(f->port, port, sizeof(f->port));
if (port != NULL)
(void) strlcpy(f->port, port, sizeof(f->port));
return i;
}

View File

@ -611,14 +611,14 @@ sandbox_server_process(int can_open_sockets)
if (*l->dir == '\0')
continue;
if (unveil(l->dir, "r") == -1)
if (unveil(l->dir, "rw") == -1)
fatal("unveil %s for domain %s",
l->dir,
h->domain);
}
}
if (pledge("stdio recvfd rpath inet dns", NULL) == -1)
if (pledge("stdio recvfd rpath unix inet dns", NULL) == -1)
fatal("pledge");
}

View File

@ -722,7 +722,7 @@ apply_fastcgi(struct client *c)
log_debug(c, "opening fastcgi connection for (%s,%s)",
f->path, f->port);
if (*f->port != '\0')
if (*f->port == '\0')
c->pfd = fcgi_open_sock(f);
else
c->pfd = fcgi_open_conn(f);