| /* |
| This file is part of libmicrohttpd |
| Copyright (C) 2010, 2011, 2012 Daniel Pittman and Christian Grothoff |
| |
| This library is free software; you can redistribute it and/or |
| modify it under the terms of the GNU Lesser General Public |
| License as published by the Free Software Foundation; either |
| version 2.1 of the License, or (at your option) any later version. |
| |
| This library is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public |
| License along with this library; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| /** |
| * @file basicauth.c |
| * @brief Implements HTTP basic authentication methods |
| * @author Amr Ali |
| * @author Matthieu Speder |
| */ |
| #include "platform.h" |
| #include <limits.h> |
| #include "internal.h" |
| #include "base64.h" |
| |
| /** |
| * Beginning string for any valid Basic authentication header. |
| */ |
| #define _BASIC_BASE "Basic " |
| |
| |
| /** |
| * Get the username and password from the basic authorization header sent by the client |
| * |
| * @param connection The MHD connection structure |
| * @param password a pointer for the password |
| * @return NULL if no username could be found, a pointer |
| * to the username if found |
| * @ingroup authentication |
| */ |
| char * |
| MHD_basic_auth_get_username_password (struct MHD_Connection *connection, |
| char** password) |
| { |
| const char *header; |
| char *decode; |
| const char *separator; |
| char *user; |
| |
| if ( (NULL == (header = MHD_lookup_connection_value (connection, |
| MHD_HEADER_KIND, |
| MHD_HTTP_HEADER_AUTHORIZATION))) || |
| (0 != strncmp (header, _BASIC_BASE, strlen(_BASIC_BASE))) ) |
| return NULL; |
| header += strlen (_BASIC_BASE); |
| if (NULL == (decode = BASE64Decode (header))) |
| { |
| #if HAVE_MESSAGES |
| MHD_DLOG (connection->daemon, |
| "Error decoding basic authentication\n"); |
| #endif |
| return NULL; |
| } |
| /* Find user:password pattern */ |
| if (NULL == (separator = strchr (decode, ':'))) |
| { |
| #if HAVE_MESSAGES |
| MHD_DLOG(connection->daemon, |
| "Basic authentication doesn't contain ':' separator\n"); |
| #endif |
| free (decode); |
| return NULL; |
| } |
| if (NULL == (user = strdup (decode))) |
| { |
| free (decode); |
| return NULL; |
| } |
| user[separator - decode] = '\0'; /* cut off at ':' */ |
| if (NULL != password) |
| { |
| *password = strdup (separator + 1); |
| if (NULL == *password) |
| { |
| #if HAVE_MESSAGES |
| MHD_DLOG(connection->daemon, |
| "Failed to allocate memory for password\n"); |
| #endif |
| free (decode); |
| free (user); |
| return NULL; |
| } |
| } |
| free (decode); |
| return user; |
| } |
| |
| |
| /** |
| * Queues a response to request basic authentication from the client. |
| * The given response object is expected to include the payload for |
| * the response; the "WWW-Authenticate" header will be added and the |
| * response queued with the 'UNAUTHORIZED' status code. |
| * |
| * @param connection The MHD connection structure |
| * @param realm the realm presented to the client |
| * @param response response object to modify and queue |
| * @return #MHD_YES on success, #MHD_NO otherwise |
| * @ingroup authentication |
| */ |
| int |
| MHD_queue_basic_auth_fail_response (struct MHD_Connection *connection, |
| const char *realm, |
| struct MHD_Response *response) |
| { |
| int ret; |
| size_t hlen = strlen(realm) + strlen("Basic realm=\"\"") + 1; |
| char *header; |
| |
| header = (char*)malloc(hlen); |
| if (NULL == header) |
| { |
| #if HAVE_MESSAGES |
| MHD_DLOG(connection->daemon, |
| "Failed to allocate memory for auth header\n"); |
| #endif /* HAVE_MESSAGES */ |
| return MHD_NO; |
| } |
| MHD_snprintf_ (header, |
| hlen, |
| "Basic realm=\"%s\"", |
| realm); |
| ret = MHD_add_response_header (response, |
| MHD_HTTP_HEADER_WWW_AUTHENTICATE, |
| header); |
| free(header); |
| if (MHD_YES == ret) |
| ret = MHD_queue_response (connection, |
| MHD_HTTP_UNAUTHORIZED, |
| response); |
| return ret; |
| } |
| |
| /* end of basicauth.c */ |