Commit Diff


commit - 0adbbd328a93482b82c4e5d5650c5311212bf388
commit + 06efacffbc9efa9ab5a6f1337e8c7acbffa0e6ee
blob - fa8132a21696068f4db352dd35593a0f5141eaf6
blob + bde278404461202ccc124ec456b9c0009d3e7807
--- gotwebd/auth.c
+++ gotwebd/auth.c
@@ -28,6 +28,9 @@
 #include <string.h>
 #include <unistd.h>
 
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+
 #include "got_error.h"
 #include "got_reference.h"
 
@@ -46,8 +49,31 @@ struct gotwebd_auth_client {
 static volatile int client_cnt;
 static int inflight;
 
-/* int */
-/* auth_is_allowed(const char *token, ) */
+/*
+ * The token format is:
+ *
+ *    "v1"[issued at/64bit][expire/64bit][username]"\0"[host]
+ *
+ * followed by the HMAC-SHA256 of it, all encoded in base64.
+ */
+
+/*
+ * XXX the idea is that this takes the token, the ACLs and the
+ * repository name (the TODO part) and returns whether the user is
+ * allowed to access the given repository.
+ */
+int
+auth_is_allowed(const char *token)
+{
+	return !strcmp(token, "42");
+}
+
+/* checks whether the token's signature matches, i.e. if it looks good. */
+int
+auth_check_token(const char *token)
+{
+	return !strcmp(token, "42");
+}
 
 static int
 auth_socket_listen(struct gotwebd *env, struct socket *sock,
blob - a392cac3f02e8a6e6be4488c768edde81e6d1655
blob + 98b573ad9c778c1a1e852430162d12d1be11dfc4
--- gotwebd/gotweb.c
+++ gotwebd/gotweb.c
@@ -256,7 +256,42 @@ recv_request(struct imsg *imsg)
 
 	return c;
 }
+
+static int
+do_login(struct request *c)
+{
+	struct querystring *qs = c->t->qs;
+	int r;
 
+	if (gotwebd_env->gotwebd_verbose > 0)
+		log_info("processing login: code='%s'", qs->login);
+
+	if (!auth_check_token(qs->login)) {
+		log_warnx("invalid code for login");
+		if (gotweb_reply(c, 401, "text/html", NULL) == -1)
+			return (-1);
+		return gotweb_render_page(c->tp,
+		    gotweb_render_unauthorized);
+	}
+
+	/*
+	 * Set cookie -- if not Expire param is given, it becomes a
+	 * "session" cookie which should be cleared when the browser
+	 * gets closed.  Depending on user configuration, these might
+	 * still persist though.
+	 */
+	r = tp_writef(c->tp, "Set-Cookie: gwdauth=%s;"
+	    " SameSite=Strict; Secure; Path=/; HttpOnly\r\n",
+	    qs->login);
+	if (r == -1)
+		return (-1);
+
+	if (gotweb_reply(c, 200, "text/html", NULL) == -1)
+		return (-1);
+
+	return gotweb_render_page(c->tp, gotweb_render_authorized);
+}
+
 int
 gotweb_process_request(struct request *c)
 {
@@ -283,30 +318,18 @@ gotweb_process_request(struct request *c)
 		goto err;
 	}
 
-	if (qs->login) {
-		if (gotwebd_env->gotwebd_verbose > 0)
-			log_info("processing login: code='%s'", qs->login);
+	if (qs->login)
+		return do_login(c);
 
-		/* xxx */
-		if (strcmp(qs->login, "42") != 0) {
-			log_warnx("invalid code for login");
-			if (gotweb_reply(c, 401, "text/html", NULL) == -1)
-				return (-1);
-			return gotweb_render_page(c->tp,
-			    gotweb_render_unauthorized);
-		}
-
-		/* Set cookie */
-		r = tp_writef(c->tp, "Set-Cookie: gwdauth=%s;"
-		    " SameSite=Strict; Secure; Path=/; HttpOnly\r\n",
-		    qs->login);
-		if (r == -1)
-			return (-1);
-
-		if (gotweb_reply(c, 200, "text/html", NULL) == -1)
-			return (-1);
-
-		return gotweb_render_page(c->tp, gotweb_render_authorized);
+	/*
+	 * assume all requests have to be from logged users.
+	 * TODO: pass the ACLs and the current repository.
+	 */
+	log_info("auth code is %s", c->auth_cookie);
+	if (!auth_is_allowed(c->auth_cookie)) {
+		if (gotweb_reply(c, 401, "text/html", NULL) == -1)
+			return -1;
+		return gotweb_render_page(c->tp, gotweb_render_unauthorized);
 	}
 
 	/* Log the request. */
blob - 2f8293f012017b37b7f116ff8eed22b51e241760
blob + b5864d25a22fbb8ba0d3d41cdb8283fbf5873c39
--- gotwebd/gotwebd.h
+++ gotwebd/gotwebd.h
@@ -559,5 +559,7 @@ int config_getcfg(struct gotwebd *, struct imsg *);
 int config_init(struct gotwebd *);
 
 /* auth.c */
+int auth_is_allowed(const char *);
+int auth_check_token(const char *);
 void gotwebd_auth(struct gotwebd *, int);
 int auth_privinit(struct gotwebd *env, uid_t, gid_t);