Home | History | Annotate | Download | only in microhttpd
      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