Home | History | Annotate | Download | only in examples
      1 /*
      2      This file is part of libmicrohttpd
      3      Copyright (C) 2010 Christian Grothoff (and other contributing authors)
      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 digest_auth_example.c
     21  * @brief minimal example for how to use digest auth with libmicrohttpd
     22  * @author Amr Ali
     23  */
     24 
     25 #include "platform.h"
     26 #include <microhttpd.h>
     27 #include <stdlib.h>
     28 
     29 #define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
     30 
     31 #define DENIED "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
     32 
     33 #define MY_OPAQUE_STR "11733b200778ce33060f31c9af70a870ba96ddd4"
     34 
     35 static int
     36 ahc_echo (void *cls,
     37           struct MHD_Connection *connection,
     38           const char *url,
     39           const char *method,
     40           const char *version,
     41           const char *upload_data, size_t *upload_data_size, void **ptr)
     42 {
     43   struct MHD_Response *response;
     44   char *username;
     45   const char *password = "testpass";
     46   const char *realm = "test (at) example.com";
     47   int ret;
     48 
     49   username = MHD_digest_auth_get_username(connection);
     50   if (username == NULL)
     51     {
     52       response = MHD_create_response_from_buffer(strlen (DENIED),
     53 						 DENIED,
     54 						 MHD_RESPMEM_PERSISTENT);
     55       ret = MHD_queue_auth_fail_response(connection, realm,
     56 					 MY_OPAQUE_STR,
     57 					 response,
     58 					 MHD_NO);
     59       MHD_destroy_response(response);
     60       return ret;
     61     }
     62   ret = MHD_digest_auth_check(connection, realm,
     63 			      username,
     64 			      password,
     65 			      300);
     66   free(username);
     67   if ( (ret == MHD_INVALID_NONCE) ||
     68        (ret == MHD_NO) )
     69     {
     70       response = MHD_create_response_from_buffer(strlen (DENIED),
     71 						 DENIED,
     72 						 MHD_RESPMEM_PERSISTENT);
     73       if (NULL == response)
     74 	return MHD_NO;
     75       ret = MHD_queue_auth_fail_response(connection, realm,
     76 					 MY_OPAQUE_STR,
     77 					 response,
     78 					 (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
     79       MHD_destroy_response(response);
     80       return ret;
     81     }
     82   response = MHD_create_response_from_buffer(strlen(PAGE), PAGE,
     83 					     MHD_RESPMEM_PERSISTENT);
     84   ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
     85   MHD_destroy_response(response);
     86   return ret;
     87 }
     88 
     89 int
     90 main (int argc, char *const *argv)
     91 {
     92   int fd;
     93   char rnd[8];
     94   ssize_t len;
     95   size_t off;
     96   struct MHD_Daemon *d;
     97 
     98   if (argc != 2)
     99     {
    100       printf ("%s PORT\n", argv[0]);
    101       return 1;
    102     }
    103   fd = open("/dev/urandom", O_RDONLY);
    104   if (-1 == fd)
    105     {
    106       fprintf (stderr, "Failed to open `%s': %s\n",
    107 	       "/dev/urandom",
    108 	       strerror (errno));
    109       return 1;
    110     }
    111   off = 0;
    112   while (off < 8)
    113     {
    114       len = read(fd, rnd, 8);
    115       if (len == -1)
    116 	{
    117 	  fprintf (stderr, "Failed to read `%s': %s\n",
    118 		   "/dev/urandom",
    119 		   strerror (errno));
    120 	  (void) close (fd);
    121 	  return 1;
    122 	}
    123       off += len;
    124     }
    125   (void) close(fd);
    126   d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
    127                         atoi (argv[1]),
    128                         NULL, NULL, &ahc_echo, PAGE,
    129 			MHD_OPTION_DIGEST_AUTH_RANDOM, sizeof(rnd), rnd,
    130 			MHD_OPTION_NONCE_NC_SIZE, 300,
    131 			MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
    132 			MHD_OPTION_END);
    133   if (d == NULL)
    134     return 1;
    135   (void) getc (stdin);
    136   MHD_stop_daemon (d);
    137   return 0;
    138 }
    139 
    140 /* end of digest_auth_example.c */
    141