Hi,
I spoke too soon, I still have issues authenticating with certain
clients.
The attached wireshark shows, at the very end, it fails to authenticate
an HTTP GET of an image file (/mjpg/image.cgi) when the username, nonce
and realm all seem to be correct.
It actually fails in digestauth.c with the message "Authentication
failed, arguments do no match". Any ideas? Regards David
On 2020-11-09 2:51 pm, DJM-Avalesta wrote:

Many thanks, Christian, As you say, I had the rnd array allocated on the stack. I moved it to global storage and voila, it works. I should have read the manual more closely. On the con_cls issue, I guess I'm completing each request so the handler never gets called with a non-zero value. Best regards David
On 2020-11-08 5:14 pm, Christian Grothoff wrote:

Hi David,

Looking at the pcap, it seems the 'nonce' of the server keeps changing,
which it must not. I don't know what you are doing, maybe you called
MHD_OPTION_DIGEST_AUTH_RANDOM with a pointer to a location in RAM that
keeps changing.

Anyway, to debug this, I would begin by looking
at the digestauth.c::calculate_nonce() function. Check in particular if
the arguments 'rnd'/rnd_size, or 'uri' or 'realm' change between calls,
they should not (at least not for the same page!).

Again, without reference code from you exhibiting the problematic
behavior, diagnosis help is difficult...

Happy hacking!

-Christian

On 2020-11-07 1:24 pm, DJM-Avalesta wrote: Hi, I desperately need to solve issue this for a Client, I attach a wireshark capture of the problem but basically, I have two problems:- 1. Around 50% of the calls to MHD_digest_auth_check() fail returning INVALID_NONCE. This seems to be random, sometimes it passes and sometimes not. Some clients (eg ONVIF Conformance Tool) don't seem to re-send the response with a different nonce when they receive a MHD_queue_auth_fail_response(). 2. The *con_cls parameter to the access handler is always null, even though I change it when I get an authentication pass. This means that I'm authenticating every call into the access handler which does not seem right. I must be doing something wrong as I'm sure this has been tested many times over. Best regards David On 2020-10-31 5:36 pm, Christian Grothoff wrote: Hi David,

I don't see anything _obviously_ wrong with the snippet you provided. I
would suggest you to use wireshark to log a transcript of the
interaction and/or to provide a stand-alone minimal C implementation
based on your code for testing by others.

Happy hacking!

Christian On 2020-10-29 4:10 pm, DJM-Avalesta wrote: Hi, I'm trying to update my 8 year old code to use digest authentication where previously it only supported basic. I'm trying to use *con_cls (*ptr in my code) to determine when to authenticate but it's not working, *con_cls always seems to be null, even after I've set it, so it's authenticating every time. I mostly get MHD_digest_auth_check() failures returning INVALID_NONCE and the Client never stops asking for credentials even when the authentication passes, which it does occasionally. I'm missing something crucial but I can't see it. The authentication part of my access_handler is shown below Many thanks David
static int aptr;
if (bDigestAuth)
{
printf("URL:%s, con_cls:%p\r\n", url, *ptr);
//HACK to see if digest authentication works and allows ONVIF snapshorUri test 
to pass
//Only works for Admin-Admin
if (&aptr != *ptr)
{
/* Only authenticate on first call of session*/
char *username;
const char *password = "Admin"; g_CameraData->GetRealmName(g_szRealm, sizeof(g_szRealm));
username = MHD_digest_auth_get_username(connection);
if (username == NULL)
{
response = MHD_create_response_from_data (strlen (NOTAUTH_RESPONSE),
(void *) NOTAUTH_RESPONSE,
MHD_NO, MHD_NO);
ret = MHD_queue_auth_fail_response(connection, g_szRealm,
OPAQUE,
response,
MHD_NO);
MHD_destroy_response(response);
pthread_mutex_unlock (&m_AuthMutex); //unlock after authorization
// printf("Failed digest auth, no username\r\n");
return ret;
}
printf("Applying digest auth to user: %s, realm:%s, con_cls:%p\r\n", username, 
g_szRealm, *ptr);
*ptr = &aptr; //set this for session
ret = MHD_digest_auth_check(connection, g_szRealm,
username,
password,
300);
printf("Checking digest auth for username: %s, password: %s, realm:%s\r\n", 
username, password, g_szRealm);
free(username);
if ( (ret == MHD_INVALID_NONCE) ||
(ret == MHD_NO) )
{
printf("Failed digest auth, invalid nonce, ret:%d\r\n", ret);
response = MHD_create_response_from_data (strlen (NOTAUTH_RESPONSE),
(void *) NOTAUTH_RESPONSE,
MHD_NO, MHD_NO);
if (NULL == response)
return MHD_NO;
ret = MHD_queue_auth_fail_response(connection, g_szRealm,
OPAQUE,
response,
(ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
MHD_destroy_response(response);
pthread_mutex_unlock (&m_AuthMutex); //unlock after authorization
return ret;
}
//PASSED
printf("PASSED digest auth\r\n");
}
else
{
printf("No digest auth required\r\n");
}
}

Attachment: ODM-SnapshotURI-fail-01.pcapng
Description: Binary data

Reply via email to