Previous: , Up: microhttpd-dauth   [Contents][Index]


10.2 Using Digest Authentication

MHD supports MD5 (deprecated by IETF) and SHA-256 hash algorithms for digest authentication. The MHD_DigestAuthAlgorithm enumeration is used to specify which algorithm should be used.

Enumeration: MHD_DigestAuthAlgorithm

Which digest algorithm should be used. Must be used consistently.

MHD_DIGEST_ALG_AUTO

Have MHD pick an algorithm currently considered secure. For now defaults to SHA-256.

MHD_DIGEST_ALG_MD5

Force use of (deprecated, ancient, insecure) MD5.

MHD_DIGEST_ALG_SHA256

Force use of SHA-256.

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 MHD_free()’ed.

Function: int MHD_digest_auth_check2 (struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout, enum MHD_DigestAuthAlgorithm algo)

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.

algo which digest algorithm should we use.

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. Deprecated, use MHD_digest_auth_check2 instead.

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_digest_auth_check_digest2 (struct MHD_Connection *connection, const char *realm, const char *username, const uint8_t *digest, unsigned int nonce_timeout, enum MHD_DigestAuthAlgorithm algo)

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.

digest pointer to the binary MD5 sum for the precalculated hash value “userame:realm:password”. The size must match the selected algo!

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.

algo digest authentication algorithm to use.

Function: int MHD_digest_auth_check_digest (struct MHD_Connection *connection, const char *realm, const char *username, const unsigned char digest[MHD_MD5_DIGEST_SIZE], 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. Deprecated, use MHD_digest_auth_check_digest2 instead.

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.

digest pointer to the binary MD5 sum for the precalculated hash value “userame:realm:password” of MHD_MD5_DIGEST_SIZE bytes.

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: enum MHD_Result MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale, enum MHD_DigestAuthAlgorithm algo)

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.

algo which digest algorithm should we use. The same algorithm must then be selected when checking digests received from clients!

Function: enum MHD_Result 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_response2 (connection,
                                           realm,
					   OPAQUE,
					   response,
					   MHD_NO,
                                           MHD_DIGEST_ALG_SHA256);
      MHD_destroy_response(response);
      return ret;
    }
  ret = MHD_digest_auth_check2 (connection,
                                realm,
			        username,
			        password,
			        300,
                                MHD_DIGEST_ALG_SHA256);
  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_response2 (connection,
                                           realm,
					   OPAQUE,
					   response,
					   (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO,
                                           MHD_DIGEST_ALG_SHA256);
      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;
}

Previous: , Up: microhttpd-dauth   [Contents][Index]