From 2aa21444797be31f299b3580e9e8a9cd25f45a0a Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Sat, 5 Jul 2025 20:57:46 -0400 Subject: [PATCH] unidig.c parsing response seems to be working fine --- lib/unidig.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++-- lib/unidig.h | 8 ++- tools/digmd5.c | 11 +++- 3 files changed, 148 insertions(+), 7 deletions(-) diff --git a/lib/unidig.c b/lib/unidig.c index 064d019..a5f0ba1 100644 --- a/lib/unidig.c +++ b/lib/unidig.c @@ -14,7 +14,94 @@ #include "unidig.h" /* - * + +*/ +/********************************************************/ +/* */ +/* Procedure to scan ONE entry from the challenge */ +/* response. */ +/* */ +/********************************************************/ +static void scanfield(RSPTYP *resp,char *entry) + +{ +static char *voc[]={ + "charset", + "cnonce", + "digest-uri", + "nc", + "nonce", + "qpop", + "realm", + "response", + "username", + (char*)0 + }; + +if (strlen(entry)>0) { + char *ptr; + + if ((ptr=strchr(entry,'='))!=(char *)0) { + int num; + + *ptr='\000'; + ptr++; + if (*ptr=='"') { + char *end; + + (void) memmove(ptr,ptr+1,strlen(ptr)+1); + if ((end=strrchr(ptr,'"'))!=(char *)0) + *end='\000'; //removonge '"' at then end + } + for (num=0;voc[num]!=(char *)0;num++) { + if (strcasecmp(voc[num],entry)!=0) + continue; + switch (num) { + case 0 : //charset + resp->charset=rou_freestr(resp->charset); + resp->charset=strdup(ptr); + break; + case 1 : //cnonce + resp->cnonce=rou_freestr(resp->cnonce); + resp->cnonce=strdup(ptr); + break; + case 2 : //digest-uri + resp->digesturi=rou_freestr(resp->digesturi); + resp->digesturi=strdup(ptr); + break; + case 3 : //nc (unsigned long) + (void) sscanf(ptr,"%lx",&(resp->nc)); + break; + case 4 : //nonce + resp->nonce=rou_freestr(resp->nonce); + resp->nonce=strdup(ptr); + break; + case 5 : //qpop + resp->qpop=rou_freestr(resp->qpop); + resp->qpop=strdup(ptr); + break; + case 6 : //realm + resp->realm=rou_freestr(resp->realm); + resp->realm=strdup(ptr); + break; + case 7 : //response + resp->response=rou_freestr(resp->response); + resp->response=strdup(ptr); + break; + case 8 : //username + resp->username=rou_freestr(resp->username); + resp->username=strdup(ptr); + break; + default : + (void) rou_alert(0,"name=<%s> field=<%s>",entry,ptr); + break; + } + } + } + } +} +/* + */ /********************************************************/ /* */ @@ -27,10 +114,11 @@ PUBLIC RSPTYP *dig_freeresp(RSPTYP *resp) { if (resp!=(RSPTYP *)0) { resp->response=rou_freestr(resp->response); + resp->charset=rou_freestr(resp->charset); resp->qpop=rou_freestr(resp->qpop); - resp->nc=rou_freestr(resp->nc); resp->cnonce=rou_freestr(resp->cnonce); resp->nonce=rou_freestr(resp->nonce); + resp->digesturi=rou_freestr(resp->digesturi); resp->realm=rou_freestr(resp->realm); resp->username=rou_freestr(resp->username); (void) free(resp); @@ -39,7 +127,47 @@ if (resp!=(RSPTYP *)0) { return resp; } /* - * + +*/ +/********************************************************/ +/* */ +/* Procedure to parse the challenge structure and */ +/* return an RSPTYP pointer structure */ +/* */ +/********************************************************/ +PUBLIC RSPTYP *dig_parseresp(char *response) + +{ +#define OPEP "unidig.c:dig_parseresp," + +RSPTYP *resp; + +resp=(RSPTYP *)0; +if ((response!=(char *)0)&&(strlen(response)>0)) { + char *cpy; + char *next; + + resp=calloc(1,sizeof(RSPTYP)); + cpy=strdup(response); + next=cpy; + while (next!=(char *)0) { + char *ptr; + + if ((ptr=strchr(next,','))!=(char *)0) { + *ptr='\000'; + ptr++; + } + (void) scanfield(resp,next); + next=ptr; + } + cpy=rou_freestr(cpy); + } +return resp; + +#undef OPEP +} +/* + */ /********************************************************/ /* */ @@ -95,7 +223,7 @@ return md5; #undef OPEP } /* - * + */ /********************************************************/ /* */ diff --git a/lib/unidig.h b/lib/unidig.h index 9d7eef1..a43a66e 100644 --- a/lib/unidig.h +++ b/lib/unidig.h @@ -11,10 +11,12 @@ typedef struct { //DIGEST-MD5 challange response structure char *username; //username requesting authentication char *realm; //Challenge realm + char *digesturi;//Type of digest char *nonce; //server nonce char *cnonce; //client nonce - char *nc; //nonce count + u_long nc; //nonce count char *qpop; //protection quality (authentication) + char *charset; //used carset char *response; //Challenge md5 response }RSPTYP; @@ -24,6 +26,10 @@ typedef unsigned char MD5TYP[17]; //procedure to free the response structure extern RSPTYP *dig_freeresp(RSPTYP *resp); +//procedure to parse a challenge answer and return +//the structure +extern RSPTYP *dig_parseresp(char *response); + //procedure to convert a string to a 128 Bit sequence //as a string extern MD5TYP *dig_hashmd5(unsigned char *seq); diff --git a/tools/digmd5.c b/tools/digmd5.c index 5958bca..9674b46 100644 --- a/tools/digmd5.c +++ b/tools/digmd5.c @@ -35,6 +35,7 @@ static int chkresponse(int argc,char *argv[]) int status; char *cleartext; +RSPTYP *resp; int phase; _Bool proceed; @@ -44,8 +45,14 @@ phase=0; proceed=(cleartext!=(char *)0); while (proceed==true) { switch (phase) { - case 0 : // - (void) rou_alert(0,"%s cleartext=<%s>",OPEP,cleartext); + case 0 : //extracting data + (void) rou_alert(0,"cleartext=<%s>",cleartext); + resp=dig_parseresp(cleartext); + break; + case 1 : //checking + break; + case 2 : //free memory + resp=dig_freeresp(resp); break; default : //SAFE Guard proceed=false; -- 2.47.3