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