1 /* 2 * uhttpd - Tiny single-threaded httpd 3 * 4 * Copyright (C) 2010-2013 Jo-Philipp Wich <xm@subsignal.org> 5 * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org> 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #define _GNU_SOURCE 21 #define _XOPEN_SOURCE 700 22 #include <strings.h> 23 #ifdef HAVE_SHADOW 24 #include <shadow.h> 25 #endif 26 #include "uhttpd.h" 27 28 static LIST_HEAD(auth_realms); 29 30 void uh_auth_add(const char *path, const char *user, const char *pass) 31 { 32 struct auth_realm *new = NULL; 33 struct passwd *pwd; 34 const char *new_pass = NULL; 35 char *dest_path, *dest_user, *dest_pass; 36 37 #ifdef HAVE_SHADOW 38 struct spwd *spwd; 39 #endif 40 41 /* given password refers to a passwd entry */ 42 if ((strlen(pass) > 3) && !strncmp(pass, "$p$", 3)) { 43 #ifdef HAVE_SHADOW 44 /* try to resolve shadow entry */ 45 spwd = getspnam(&pass[3]); 46 if (spwd) 47 new_pass = spwd->sp_pwdp; 48 #endif 49 if (!new_pass) { 50 pwd = getpwnam(&pass[3]); 51 if (pwd && pwd->pw_passwd && pwd->pw_passwd[0] && 52 pwd->pw_passwd[0] != '!') 53 new_pass = pwd->pw_passwd; 54 } 55 } else { 56 new_pass = pass; 57 } 58 59 if (!new_pass || !new_pass[0]) 60 return; 61 62 new = calloc_a(sizeof(*new), 63 &dest_path, strlen(path) + 1, 64 &dest_user, strlen(user) + 1, 65 &dest_pass, strlen(new_pass) + 1); 66 67 if (!new) 68 return; 69 70 new->path = strcpy(dest_path, path); 71 new->user = strcpy(dest_user, user); 72 new->pass = strcpy(dest_pass, new_pass); 73 list_add(&new->list, &auth_realms); 74 } 75 76 bool uh_auth_check(struct client *cl, const char *path, const char *auth, 77 char **uptr, char **pptr) 78 { 79 struct http_request *req = &cl->request; 80 struct auth_realm *realm; 81 bool user_match = false; 82 char *user = NULL; 83 char *pass = NULL; 84 int plen; 85 86 if (uptr) 87 *uptr = NULL; 88 89 if (pptr) 90 *pptr = NULL; 91 92 if (auth && !strncasecmp(auth, "Basic ", 6)) { 93 auth += 6; 94 95 uh_b64decode(uh_buf, sizeof(uh_buf), auth, strlen(auth)); 96 pass = strchr(uh_buf, ':'); 97 if (pass) { 98 user = uh_buf; 99 *pass++ = 0; 100 } 101 } 102 103 req->realm = NULL; 104 plen = strlen(path); 105 list_for_each_entry(realm, &auth_realms, list) { 106 int rlen = strlen(realm->path); 107 108 if (plen < rlen) 109 continue; 110 111 if (strncasecmp(path, realm->path, rlen) != 0) 112 continue; 113 114 req->realm = realm; 115 if (!user) 116 break; 117 118 if (strcmp(user, realm->user) != 0) 119 continue; 120 121 user_match = true; 122 break; 123 } 124 125 if (!req->realm) 126 return true; 127 128 if (user_match && 129 (!strcmp(pass, realm->pass) || 130 !strcmp(crypt(pass, realm->pass), realm->pass))) { 131 if (uptr) 132 *uptr = user; 133 134 if (pptr) 135 *pptr = pass; 136 137 return true; 138 } 139 140 uh_http_header(cl, 401, "Authorization Required"); 141 ustream_printf(cl->us, 142 "WWW-Authenticate: Basic realm=\"%s\"\r\n" 143 "Content-Type: text/plain\r\n\r\n", 144 conf.realm); 145 uh_chunk_printf(cl, "Authorization Required\n"); 146 uh_request_done(cl); 147 148 return false; 149 } 150
This page was automatically generated by LXR 0.3.1. • OpenWrt