about summary refs log tree commit diff stats
path: root/bonus
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-10-29 22:43:07 +0100
committerbptato <nincsnevem662@gmail.com>2023-10-29 22:47:04 +0100
commit31bd1c9e12f28ab301d0799f12ac9519d415b7f3 (patch)
treee2652aacb513d0b7bb04fb3fa7fca24bfbc8bbae /bonus
parenta9b2cb58c02bce64823b8867f1b52333bcdbf31a (diff)
downloadchawan-31bd1c9e12f28ab301d0799f12ac9519d415b7f3.tar.gz
gmifetch: fix bugs
* fix invalid file pointer being used after adding certificate (a pointer
  deref was missing there)
* fix compatibility with gemini servers that refuse to interpret URLs that
  contain the default port (yes, seriously)
Diffstat (limited to 'bonus')
-rw-r--r--bonus/gmifetch/gmifetch.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/bonus/gmifetch/gmifetch.c b/bonus/gmifetch/gmifetch.c
index 1cf5b7c5..85a7416b 100644
--- a/bonus/gmifetch/gmifetch.c
+++ b/bonus/gmifetch/gmifetch.c
@@ -488,7 +488,7 @@ void decode_query(const char *input_url, char *output_buffer)
 
 
 void read_post(const char *hostp, char *portp, char *pathp, const char *urlbuf,
-	char *khsbuf, FILE *known_hosts)
+	char *khsbuf, FILE **known_hosts)
 {
 	/* TODO move query strings here */
 	size_t n;
@@ -514,8 +514,8 @@ void read_post(const char *hostp, char *portp, char *pathp, const char *urlbuf,
 	p += sizeof("trust_cert=") - 1;
 	if (!strncmp(p, "always", 6)) {
 		/* move to file end */
-		fseek(known_hosts, 0L, SEEK_END);
-		last_pos = ftell(known_hosts);
+		fseek(*known_hosts, 0L, SEEK_END);
+		last_pos = ftell(*known_hosts);
 		if (!(p = strstr(p, "entry=")))
 			DIE("Invalid POST request: missing entry");
 		p += sizeof("entry=") - 1;
@@ -524,17 +524,17 @@ void read_post(const char *hostp, char *portp, char *pathp, const char *urlbuf,
 		p = buffer;
 		while ((p = strstr(p, "+")))
 			*p = ' ';
-		fwrite(buffer, 1, strlen(buffer), known_hosts);
-		fwrite("\n", 1, 1, known_hosts);
+		fwrite(buffer, 1, strlen(buffer), *known_hosts);
+		fwrite("\n", 1, 1, *known_hosts);
 		khslen = strlen(khsbuf);
 		khsbuf[khslen] = '~';
 		khsbuf[khslen + 1] = '\0';
 		if (!(known_hosts_tmp = fopen(khsbuf, "w+")))
 			PDIE("Error opening temporary hosts file");
-		rewind(known_hosts);
+		rewind(*known_hosts);
 		*portp = '\0';
 		total = 0;
-		while (fgets(buffer, BUFSIZE, known_hosts)) {
+		while (fgets(buffer, BUFSIZE, *known_hosts)) {
 			len = strlen(buffer);
 			if (!len)
 				continue;
@@ -560,12 +560,12 @@ void read_post(const char *hostp, char *portp, char *pathp, const char *urlbuf,
 		*portp = ':';
 		memcpy(buffer, khsbuf, BUFSIZE + 1);
 		buffer[khslen] = '\0';
-		fclose(known_hosts);
+		fclose(*known_hosts);
 		fclose(known_hosts_tmp);
 		if (rename(khsbuf, buffer))
 			PDIE("Failed to rename temporary file");
 		khsbuf[khslen] = '\0';
-		if (!(known_hosts = fopen(khsbuf, "a+")))
+		if (!(*known_hosts = fopen(khsbuf, "a+")))
 			PDIE("Failed to re-open known hosts file");
 	} else if (strncmp(p, "once", 4)) {
 		DIE("Invalid POST request");
@@ -656,10 +656,19 @@ int main(int argc, const char *argv[])
 	extract_hostname(input_url, &hostp, &portp, &pathp, &endp, urlbuf);
 	method = getenv("REQUEST_METHOD");
 	if (method && !strcmp(method, "POST"))
-		read_post(hostp, portp, pathp, urlbuf, khsbuf, known_hosts);
+		read_post(hostp, portp, pathp, urlbuf, khsbuf, &known_hosts);
 	connect_res = connect(hostp, portp, pathp, endp, &stored_digestp,
 		&their_time, hashbuf2, known_hosts);
 	if (connect_res == 1) { /* valid certificate */
+		/* I really wish this was explicitly mentioned in the
+		 * standard. Something like:
+		 *
+		 * !!!WARNING WARNING WARNING some gemini servers will
+		 * not accept URLs containing the default port number!!!
+		 */
+		if (!strncmp(portp, ":1965", 5))
+			/* move including null terminator */
+			memmove(portp, &portp[5], strlen(&portp[5]) + 1);
 		BIO_puts(conn, urlbuf);
 		read_response(urlbuf);
 	} else if (connect_res == 0) { /* invalid certificate */