#include "unidig.h"
/*
- * \f
+\f
+*/
+/********************************************************/
+/* */
+/* 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;
+ }
+ }
+ }
+ }
+}
+/*
+\f
*/
/********************************************************/
/* */
{
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);
return resp;
}
/*
- * \f
+\f
+*/
+/********************************************************/
+/* */
+/* 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
+}
+/*
+\f
*/
/********************************************************/
/* */
#undef OPEP
}
/*
- * \f
+\f
*/
/********************************************************/
/* */
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;
//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);