diff mbox

[OpenWrt-Devel] uhttpd improvement/new feature ?

Message ID 20160128124620.721777fb@893jg42
State Changes Requested
Delegated to: Jo-Philipp Wich
Headers show

Commit Message

Sébastien Noel Jan. 28, 2016, 11:46 a.m. UTC
Hi everyone,

I'm in need of a feature in uhttpd, and i would like advice from you
guys how to implement this change correctly.
In attachment you will find my current "implementation" (well it's more
like a PoC, i'm not fluent in C, but it worked for the 3 sec i tested
it)

The story behind this change is that i have a letsencrypt (the new free
certificate authority) client in ash+openssl+curl that i would like
to run on openwrt; during the process, the letsencrypt service needs to
check if i'm the real owner of the server/domain and tries to download
a file from http://$server/.well-known/acme-challenge/XXX

So i need to make some sort of exception to the "-q" option in uhttpd
to redirect all HTTP -> HTTPS except for files under
/.well-known/acme-challenge/
(i just don't want to disable that feature entirely, it's so useful)

are you interested in a feature like that ?
if yes, what would you like me to change to the current patch ?

thanks,

best regards,
Sébastien
diff mbox

Patch

diff --git a/client.c b/client.c
index 73e0e49..b34c99c 100644
--- a/client.c
+++ b/client.c
@@ -232,6 +232,7 @@  static bool tls_redirect_check(struct client *cl)
 {
 	int rem, port;
 	struct blob_attr *cur;
+	struct no_tls_redirect *no_tls_redirect;
 	char *ptr, *url = NULL, *host = NULL;
 
 	if (cl->tls || !conf.tls_redirect)
@@ -254,6 +255,11 @@  static bool tls_redirect_check(struct client *cl)
 	if (!url || !host)
 		return true;
 
+	if (!list_empty(&conf.no_tls_redirect)) list_for_each_entry(no_tls_redirect, &conf.no_tls_redirect, list) {
+		if(strncmp(url, no_tls_redirect->path, strlen(no_tls_redirect->path)) == 0)
+			return true;
+	}
+
 	if ((ptr = strchr(host, ']')) != NULL)
 		*(ptr+1) = 0;
 	else if ((ptr = strchr(host, ':')) != NULL)
diff --git a/main.c b/main.c
index fb27665..e22a302 100644
--- a/main.c
+++ b/main.c
@@ -135,6 +135,7 @@  static int usage(const char *name)
 		"	-C file         ASN.1 server certificate file\n"
 		"	-K file         ASN.1 server private key file\n"
 		"	-q              Redirect all HTTP requests to HTTPS\n"
+		"	-Q path         Exception to '-q'\n"
 #endif
 		"	-h directory    Specify the document root, default is '.'\n"
 		"	-E string       Use given virtual URL as 404 error handler\n"
@@ -179,6 +180,9 @@  static void init_defaults_pre(void)
 	conf.cgi_prefix = "/cgi-bin";
 	conf.cgi_path = "/sbin:/usr/sbin:/bin:/usr/bin";
 	INIT_LIST_HEAD(&conf.cgi_alias);
+#ifdef HAVE_TLS
+	INIT_LIST_HEAD(&conf.no_tls_redirect);
+#endif
 }
 
 static void init_defaults_post(void)
@@ -222,6 +226,7 @@  int main(int argc, char **argv)
 	int cur_fd;
 	int bound = 0;
 #ifdef HAVE_TLS
+	struct no_tls_redirect *no_tls_redirect;
 	int n_tls = 0;
 	const char *tls_key = NULL, *tls_crt = NULL;
 #endif
@@ -232,7 +237,7 @@  int main(int argc, char **argv)
 	init_defaults_pre();
 	signal(SIGPIPE, SIG_IGN);
 
-	while ((ch = getopt(argc, argv, "A:aC:c:Dd:E:fh:H:I:i:K:k:L:l:m:N:n:p:qRr:Ss:T:t:U:u:Xx:y:")) != -1) {
+	while ((ch = getopt(argc, argv, "A:aC:c:Dd:E:fh:H:I:i:K:k:L:l:m:N:n:p:qQ:Rr:Ss:T:t:U:u:Xx:y:")) != -1) {
 		switch(ch) {
 #ifdef HAVE_TLS
 		case 'C':
@@ -247,6 +252,16 @@  int main(int argc, char **argv)
 			conf.tls_redirect = 1;
 			break;
 
+		case 'Q':
+			no_tls_redirect = calloc(1, sizeof(*no_tls_redirect));
+			if (!no_tls_redirect) {
+				fprintf(stderr, "Error: failed to allocate no_tls_redirect\n");
+				exit(1);
+			}
+			no_tls_redirect->path = strdup(optarg);
+			list_add(&no_tls_redirect->list, &conf.no_tls_redirect);
+			break;
+
 		case 's':
 			n_tls++;
 			/* fall through */
@@ -254,6 +269,7 @@  int main(int argc, char **argv)
 		case 'C':
 		case 'K':
 		case 'q':
+		case 'Q':
 		case 's':
 			fprintf(stderr, "uhttpd: TLS support not compiled, "
 			                "ignoring -%c\n", ch);
diff --git a/uhttpd.h b/uhttpd.h
index f9ea761..2851e0b 100644
--- a/uhttpd.h
+++ b/uhttpd.h
@@ -52,6 +52,13 @@  struct alias {
 	char *path;
 };
 
+#ifdef HAVE_TLS
+struct no_tls_redirect {
+	struct list_head list;
+	char *path;
+};
+#endif
+
 struct config {
 	const char *docroot;
 	const char *realm;
@@ -68,7 +75,9 @@  struct config {
 	int no_dirlists;
 	int network_timeout;
 	int rfc1918_filter;
+#ifdef HAVE_TLS
 	int tls_redirect;
+#endif
 	int tcp_keepalive;
 	int max_script_requests;
 	int max_connections;
@@ -78,6 +87,9 @@  struct config {
 	int ubus_cors;
 	int cgi_prefix_len;
 	struct list_head cgi_alias;
+#ifdef HAVE_TLS
+        struct list_head no_tls_redirect;
+#endif
 };
 
 struct auth_realm {