auth: store parsed username and password
authorJo-Philipp Wich <jo@mein.io>
Sun, 2 Jul 2017 14:19:16 +0000 (16:19 +0200)
committerJo-Philipp Wich <jo@mein.io>
Sun, 2 Jul 2017 14:19:16 +0000 (16:19 +0200)
Store the parsed username and password information as HTTP headers in the
clients header blob buffer for later use by proc.c

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
auth.c
file.c
uhttpd.h

diff --git a/auth.c b/auth.c
index 0c4872fe3ed8077e5838d72f9f4c285680a97623..69ccf468334d5d15264d5dc0793233020f7f5971 100644 (file)
--- a/auth.c
+++ b/auth.c
@@ -73,7 +73,8 @@ void uh_auth_add(const char *path, const char *user, const char *pass)
        list_add(&new->list, &auth_realms);
 }
 
        list_add(&new->list, &auth_realms);
 }
 
-bool uh_auth_check(struct client *cl, struct path_info *pi)
+bool uh_auth_check(struct client *cl, const char *path, const char *auth,
+                   char **uptr, char **pptr)
 {
        struct http_request *req = &cl->request;
        struct auth_realm *realm;
 {
        struct http_request *req = &cl->request;
        struct auth_realm *realm;
@@ -82,8 +83,14 @@ bool uh_auth_check(struct client *cl, struct path_info *pi)
        char *pass = NULL;
        int plen;
 
        char *pass = NULL;
        int plen;
 
-       if (pi->auth && !strncasecmp(pi->auth, "Basic ", 6)) {
-               const char *auth = pi->auth + 6;
+       if (uptr)
+               *uptr = NULL;
+
+       if (pptr)
+               *pptr = NULL;
+
+       if (auth && !strncasecmp(auth, "Basic ", 6)) {
+               auth += 6;
 
                uh_b64decode(uh_buf, sizeof(uh_buf), auth, strlen(auth));
                pass = strchr(uh_buf, ':');
 
                uh_b64decode(uh_buf, sizeof(uh_buf), auth, strlen(auth));
                pass = strchr(uh_buf, ':');
@@ -94,14 +101,14 @@ bool uh_auth_check(struct client *cl, struct path_info *pi)
        }
 
        req->realm = NULL;
        }
 
        req->realm = NULL;
-       plen = strlen(pi->name);
+       plen = strlen(path);
        list_for_each_entry(realm, &auth_realms, list) {
                int rlen = strlen(realm->path);
 
                if (plen < rlen)
                        continue;
 
        list_for_each_entry(realm, &auth_realms, list) {
                int rlen = strlen(realm->path);
 
                if (plen < rlen)
                        continue;
 
-               if (strncasecmp(pi->name, realm->path, rlen) != 0)
+               if (strncasecmp(path, realm->path, rlen) != 0)
                        continue;
 
                req->realm = realm;
                        continue;
 
                req->realm = realm;
@@ -120,8 +127,15 @@ bool uh_auth_check(struct client *cl, struct path_info *pi)
 
        if (user_match &&
            (!strcmp(pass, realm->pass) ||
 
        if (user_match &&
            (!strcmp(pass, realm->pass) ||
-            !strcmp(crypt(pass, realm->pass), realm->pass)))
+            !strcmp(crypt(pass, realm->pass), realm->pass))) {
+               if (uptr)
+                       *uptr = user;
+
+               if (pptr)
+                       *pptr = pass;
+
                return true;
                return true;
+       }
 
        uh_http_header(cl, 401, "Authorization Required");
        ustream_printf(cl->us,
 
        uh_http_header(cl, 401, "Authorization Required");
        ustream_printf(cl->us,
diff --git a/file.c b/file.c
index 047b4daccb879a331b0b627ef04dd9ed47f5da3a..e20071b1186a1fa9adca3cf28c00818a2ee306d4 100644 (file)
--- a/file.c
+++ b/file.c
@@ -795,6 +795,7 @@ static bool __handle_file_request(struct client *cl, char *url)
        struct dispatch_handler *d;
        struct blob_attr *tb[__HDR_MAX];
        struct path_info *pi;
        struct dispatch_handler *d;
        struct blob_attr *tb[__HDR_MAX];
        struct path_info *pi;
+       char *user, *pass;
 
        pi = uh_path_lookup(cl, url);
        if (!pi)
 
        pi = uh_path_lookup(cl, url);
        if (!pi)
@@ -804,11 +805,15 @@ static bool __handle_file_request(struct client *cl, char *url)
                return true;
 
        blobmsg_parse(hdr_policy, __HDR_MAX, tb, blob_data(cl->hdr.head), blob_len(cl->hdr.head));
                return true;
 
        blobmsg_parse(hdr_policy, __HDR_MAX, tb, blob_data(cl->hdr.head), blob_len(cl->hdr.head));
-       if (tb[HDR_AUTHORIZATION])
-               pi->auth = blobmsg_data(tb[HDR_AUTHORIZATION]);
+       if (tb[HDR_AUTHORIZATION]) {
+               if (!uh_auth_check(cl, pi->name, blobmsg_data(tb[HDR_AUTHORIZATION]), &user, &pass))
+                       return true;
 
 
-       if (!uh_auth_check(cl, pi))
-               return true;
+               if (user && pass) {
+                       blobmsg_add_string(&cl->hdr, "http-auth-user", user);
+                       blobmsg_add_string(&cl->hdr, "http-auth-pass", pass);
+               }
+       }
 
        d = dispatch_find(url, pi);
        if (d)
 
        d = dispatch_find(url, pi);
        if (d)
index fe05f0d9284782dbdf1ec600a41f2042c3fa605e..b358a0b44236aa6e00b2805e9a12ca3a2d29f75b 100644 (file)
--- a/uhttpd.h
+++ b/uhttpd.h
@@ -300,7 +300,8 @@ void uh_client_read_cb(struct client *cl);
 void uh_client_notify_state(struct client *cl);
 
 void uh_auth_add(const char *path, const char *user, const char *pass);
 void uh_client_notify_state(struct client *cl);
 
 void uh_auth_add(const char *path, const char *user, const char *pass);
-bool uh_auth_check(struct client *cl, struct path_info *pi);
+bool uh_auth_check(struct client *cl, const char *path, const char *auth,
+                   char **uptr, char **pptr);
 
 void uh_close_listen_fds(void);
 void uh_close_fds(void);
 
 void uh_close_listen_fds(void);
 void uh_close_fds(void);