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;
}

Reply via email to