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: DigestAuth_Fail_then_pass_02.pcapng
Description: Binary data

Reply via email to