1 /* 2 This file is part of libmicrohttpd 3 Copyright (C) 2010, 2011, 2012 Daniel Pittman and Christian Grothoff 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 /** 20 * @file basicauth.c 21 * @brief Implements HTTP basic authentication methods 22 * @author Amr Ali 23 * @author Matthieu Speder 24 */ 25 #include "platform.h" 26 #include <limits.h> 27 #include "internal.h" 28 #include "base64.h" 29 30 /** 31 * Beginning string for any valid Basic authentication header. 32 */ 33 #define _BASIC_BASE "Basic " 34 35 36 /** 37 * Get the username and password from the basic authorization header sent by the client 38 * 39 * @param connection The MHD connection structure 40 * @param password a pointer for the password 41 * @return NULL if no username could be found, a pointer 42 * to the username if found 43 * @ingroup authentication 44 */ 45 char * 46 MHD_basic_auth_get_username_password (struct MHD_Connection *connection, 47 char** password) 48 { 49 const char *header; 50 char *decode; 51 const char *separator; 52 char *user; 53 54 if ( (NULL == (header = MHD_lookup_connection_value (connection, 55 MHD_HEADER_KIND, 56 MHD_HTTP_HEADER_AUTHORIZATION))) || 57 (0 != strncmp (header, _BASIC_BASE, strlen(_BASIC_BASE))) ) 58 return NULL; 59 header += strlen (_BASIC_BASE); 60 if (NULL == (decode = BASE64Decode (header))) 61 { 62 #if HAVE_MESSAGES 63 MHD_DLOG (connection->daemon, 64 "Error decoding basic authentication\n"); 65 #endif 66 return NULL; 67 } 68 /* Find user:password pattern */ 69 if (NULL == (separator = strchr (decode, ':'))) 70 { 71 #if HAVE_MESSAGES 72 MHD_DLOG(connection->daemon, 73 "Basic authentication doesn't contain ':' separator\n"); 74 #endif 75 free (decode); 76 return NULL; 77 } 78 if (NULL == (user = strdup (decode))) 79 { 80 free (decode); 81 return NULL; 82 } 83 user[separator - decode] = '\0'; /* cut off at ':' */ 84 if (NULL != password) 85 { 86 *password = strdup (separator + 1); 87 if (NULL == *password) 88 { 89 #if HAVE_MESSAGES 90 MHD_DLOG(connection->daemon, 91 "Failed to allocate memory for password\n"); 92 #endif 93 free (decode); 94 free (user); 95 return NULL; 96 } 97 } 98 free (decode); 99 return user; 100 } 101 102 103 /** 104 * Queues a response to request basic authentication from the client. 105 * The given response object is expected to include the payload for 106 * the response; the "WWW-Authenticate" header will be added and the 107 * response queued with the 'UNAUTHORIZED' status code. 108 * 109 * @param connection The MHD connection structure 110 * @param realm the realm presented to the client 111 * @param response response object to modify and queue 112 * @return #MHD_YES on success, #MHD_NO otherwise 113 * @ingroup authentication 114 */ 115 int 116 MHD_queue_basic_auth_fail_response (struct MHD_Connection *connection, 117 const char *realm, 118 struct MHD_Response *response) 119 { 120 int ret; 121 size_t hlen = strlen(realm) + strlen("Basic realm=\"\"") + 1; 122 char *header; 123 124 header = (char*)malloc(hlen); 125 if (NULL == header) 126 { 127 #if HAVE_MESSAGES 128 MHD_DLOG(connection->daemon, 129 "Failed to allocate memory for auth header\n"); 130 #endif /* HAVE_MESSAGES */ 131 return MHD_NO; 132 } 133 MHD_snprintf_ (header, 134 hlen, 135 "Basic realm=\"%s\"", 136 realm); 137 ret = MHD_add_response_header (response, 138 MHD_HTTP_HEADER_WWW_AUTHENTICATE, 139 header); 140 free(header); 141 if (MHD_YES == ret) 142 ret = MHD_queue_response (connection, 143 MHD_HTTP_UNAUTHORIZED, 144 response); 145 return ret; 146 } 147 148 /* end of basicauth.c */ 149