Hi Evgeny,

Simple setup to reproduce the nonce generation issue is available at 
https://github.com/akermen/digest-nonce-test 
<https://github.com/akermen/digest-nonce-test>. Hoping this helps to easily 
identify the issue and can be used for testing.

To make values unique, I experimented with basic "mutex wrapped counter 
mechanism" which appears to working for very limited test scope, but not sure 
about performance and effect on other parts of the library:

/* global scope */
static int make_digest_unique = 1;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

/* at "MHD_queue_auth_fail_response" function */
/*…*/
pthread_mutex_lock(&mutex);
make_digest_unique = make_digest_unique + 1;
pthread_mutex_unlock(&mutex);
/*…*/
calculate_nonce ((uint32_t) MHD_monotonic_sec_counter() + make_digest_unique,
    connection->method,
    connection->daemon->digest_auth_random,
    connection->daemon->digest_auth_rand_size,
    connection->url,
    realm,
    nonce);
/*…*/


Best regards,
Ahmet Kermen



> On 13 Jan 2022, at 20:43, Evgeny Grin <k...@yandex.ru> wrote:
> 
> Hi Ahmet,
> 
> Thank for the report.
> I see some mistakes in our example (related to API complexity that should be 
> improved soon), but these mistakes shouldn't break the example.
> nonce should be unique and it will be fixed.
> 
> I'll check it deeper.
> 
> In the meantime, any additional information and patches are welcome. :)
> 
> -- 
> Evgeny
> 
> On 10.01.2022 18:56, Ahmet Kermen wrote:
>> Hi all,
>> Trying to implement digest authentication by following the sample code 
>> “digest_auth_example.c” from 
>> "https://git.gnunet.org/libmicrohttpd.git/tree/src/examples/digest_auth_example.c
>>  
>> <https://git.gnunet.org/libmicrohttpd.git/tree/src/examples/digest_auth_example.c>”.
>> For simple requests everything works fine without any issue.
>> When I try to send requests concurrently, some of them always fail, even two 
>> concurrent requests.
>> Still not sure exact reason why concurrent handling is not working, but at 
>> this point only clue I have for the issue appears to be “nonce” value of the 
>> authentication header being not unqiue for each (independent) request. This 
>> behaviour seems to be not compliant with RFC2617 
>> https://datatracker.ietf.org/doc/html/rfc2617#section-3.2.1 
>> <https://datatracker.ietf.org/doc/html/rfc2617#section-3.2.1> and RFC7616 
>> https://datatracker.ietf.org/doc/html/rfc7616#section-3.2 
>> <https://datatracker.ietf.org/doc/html/rfc7616#section-3.2> both state 
>> “nonce" values should be uniquely generated each time a 401 response is made 
>> while the values generated by libmicrohttpd are only unique for each second 
>> (by the “MHD_monotonic_sec_counter" function).
>> By the way the NONCE_NC_SIZE value is set to very large value to eliminate 
>> hash collisions.
>> When same concurrent test run with digest authentication implementation for 
>> popular frameworks (for Flask from 
>> https://flask-httpauth.readthedocs.io/en/latest 
>> <https://flask-httpauth.readthedocs.io/en/latest>, for Node.js from 
>> https://www.npmjs.com/package/http-auth 
>> <https://www.npmjs.com/package/http-auth>, for httbin from 
>> https://hub.docker.com/r/kennethreitz/httpbin 
>> <https://hub.docker.com/r/kennethreitz/httpbin>) they all seem to produce 
>> unique “nonce” values and handle concurrent requests wihtout any issue.
>> Please correct me If I’m wrong and missing something about the "nonce” value 
>> handling or it being source of the isssue.
>> Best regards,
>> Ahmet Kermen

Reply via email to