Previous: microhttpd-dauth basic, Up: microhttpd-dauth


9.2 Using Digest Authentication

— Function: char * MHD_digest_auth_get_username (struct MHD_Connection *connection)

Find and return a pointer to the username value from the request header. Return NULL if the value is not found or header does not exist. If returned value is not NULL, the value must be free()'ed.

— Function: int MHD_digest_auth_check (struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout)

Checks if the provided values in the WWW-Authenticate header are valid and sound according to RFC2716. If valid return MHD_YES, otherwise return MHD_NO.

realm must reference to a zero-terminated string representing the realm.

username must reference to a zero-terminated string representing the username, it is usually the returned value from MHD_digest_auth_get_username.

password must reference to a zero-terminated string representing the password, most probably it will be the result of a lookup of the username against a local database.

nonce_timeout is the amount of time in seconds for a nonce to be invalid. Most of the time it is sound to specify 300 seconds as its values.

— Function: int MHD_queue_auth_fail_response (struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale)

Queues a response to request authentication from the client, return MHD_YES if successful, otherwise MHD_NO.

realm must reference to a zero-terminated string representing the realm.

opaque must reference to a zero-terminated string representing a value that gets passed to the client and expected to be passed again to the server as-is. This value can be a hexadecimal or base64 string.

response a response structure to specify what shall be presented to the client with a 401 HTTP status.

signal_stale a value that signals "stale=true" in the response header to indicate the invalidity of the nonce and no need to ask for authentication parameters and only a new nonce gets generated. MHD_YES to generate a new nonce, MHD_NO to ask for authentication parameters.

Example: handling digest authentication requests and responses.

     #define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
     #define DENIED "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
     #define OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
     
     static int
     ahc_echo (void *cls,
               struct MHD_Connection *connection,
               const char *url,
               const char *method,
               const char *version,
               const char *upload_data, size_t *upload_data_size, void **ptr)
     {
       struct MHD_Response *response;
       char *username;
       const char *password = "testpass";
       const char *realm = "test@example.com";
       int ret;
     
       username = MHD_digest_auth_get_username(connection);
       if (username == NULL)
         {
           response = MHD_create_response_from_buffer(strlen (DENIED),
     					         DENIED,
     					         MHD_RESPMEM_PERSISTENT);
           ret = MHD_queue_auth_fail_response(connection, realm,
     					 OPAQUE,
     					 response,
     					 MHD_NO);
           MHD_destroy_response(response);
           return ret;
         }
       ret = MHD_digest_auth_check(connection, realm,
     			      username,
     			      password,
     			      300);
       free(username);
       if ( (ret == MHD_INVALID_NONCE) ||
            (ret == MHD_NO) )
         {
           response = MHD_create_response_from_buffer(strlen (DENIED),
     					         DENIED,
     					         MHD_RESPMEM_PERSISTENT);
           if (NULL == response)
     	return MHD_NO;
           ret = MHD_queue_auth_fail_response(connection, realm,
     					 OPAQUE,
     					 response,
     					 (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
           MHD_destroy_response(response);
           return ret;
         }
       response = MHD_create_response_from_buffer (strlen(PAGE), PAGE,
      					      MHD_RESPMEM_PERSISTENT);
       ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
       MHD_destroy_response(response);
       return ret;
     }