Blame src/microhttpd/basicauth.c

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 */