proc: expose HTTP Origin header in process environment
[project/uhttpd.git] / auth.c
diff --git a/auth.c b/auth.c
index afab2c0..69ccf46 100644 (file)
--- a/auth.c
+++ b/auth.c
@@ -1,24 +1,28 @@
 /*
  * uhttpd - Tiny single-threaded httpd
  *
- *   Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
- *   Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
+ *   Copyright (C) 2010-2013 Jo-Philipp Wich <xm@subsignal.org>
+ *   Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
  *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
 #define _GNU_SOURCE
 #define _XOPEN_SOURCE  700
+#include <strings.h>
+#ifdef HAVE_SHADOW
+#include <shadow.h>
+#endif
 #include "uhttpd.h"
 
 static LIST_HEAD(auth_realms);
@@ -69,7 +73,8 @@ void uh_auth_add(const char *path, const char *user, const char *pass)
        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;
@@ -78,8 +83,14 @@ bool uh_auth_check(struct client *cl, struct path_info *pi)
        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, ':');
@@ -90,14 +101,14 @@ bool uh_auth_check(struct client *cl, struct path_info *pi)
        }
 
        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;
 
-               if (strncasecmp(pi->name, realm->path, rlen) != 0)
+               if (strncasecmp(path, realm->path, rlen) != 0)
                        continue;
 
                req->realm = realm;
@@ -114,8 +125,17 @@ bool uh_auth_check(struct client *cl, struct path_info *pi)
        if (!req->realm)
                return true;
 
-       if (user_match && !strcmp(crypt(pass, realm->pass), realm->pass))
+       if (user_match &&
+           (!strcmp(pass, realm->pass) ||
+            !strcmp(crypt(pass, realm->pass), realm->pass))) {
+               if (uptr)
+                       *uptr = user;
+
+               if (pptr)
+                       *pptr = pass;
+
                return true;
+       }
 
        uh_http_header(cl, 401, "Authorization Required");
        ustream_printf(cl->us,