Hello,
I'm having problems with digest auth when the URL has parameters
without values, as long as it is not the last one. Attached a simple
example that shows the issue.
Requests that auth ok:
curl --digest 'http://demo:[email protected]:8080/?cmd'
curl --digest 'http://demo:[email protected]:8080/?cmd=yes&name=value'
curl --digest 'http://demo:[email protected]:8080/?cmd=yes&name'
Requests that fails to auth:
curl --digest 'http://demo:[email protected]:8080/?cmd&name=value'
curl --digest 'http://demo:[email protected]:8080/?cmd=yes&name&valid'
curl --digest 'http://demo:[email protected]:8080/?cmd=yes&name&valid=y'
Tested with libmicrohttpd 0.9.42 (please forgive me if it was fixed
already)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <microhttpd.h>
#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 handle_requests(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 **con_cls)
{
const char *realm = "demo";
const char *password = "12345";
struct MHD_Response *response;
char *username;
int ret;
fprintf(stdout, "Got request\n");
if (strcmp(method, "GET") != 0) {
fprintf(stdout, "Only GET is supported\n");
return MHD_NO;
}
username = MHD_digest_auth_get_username(connection);
if (username == NULL) {
fprintf(stdout, "No username\n");
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, 99);
free(username);
if (ret == MHD_INVALID_NONCE || ret == MHD_NO) {
response = MHD_create_response_from_buffer(strlen(DENIED),
DENIED,
MHD_RESPMEM_PERSISTENT);
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;
}
int main(int argc, char **argv)
{
struct MHD_Daemon *d;
d = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, 8080, NULL, NULL,
handle_requests, NULL, MHD_OPTION_END);
if (d != NULL)
fprintf(stdout, "Service running\n");
getchar();
MHD_stop_daemon(d);
return 0;
}