decoded=cnv_getb64(local);
return decoded;
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to manage authentication in */
+/* cram_md5 mode. */
+/* Return a builded "decoded" string from */
+/* the exchange with the remote sereur */
+/* */
+/********************************************************/
+static char *get_auth_cram_md5(CONTYP *contact,int delay)
+
+{
+#define OPEP "lvleml.c:get_auth_cram_md5,"
+
+char *decoded;
+char challenge[300];
+char answer[300];
+char name[100];
+char passwd[100];
+int phase;
+_Bool proceed;
+
+decoded=(char *)0;
+(void) memset(challenge,'\000',sizeof(challenge));
+(void) memset(answer,'\000',sizeof(answer));
+(void) memset(name,'\000',sizeof(name));
+(void) memset(passwd,'\000',sizeof(passwd));
+phase=0;
+proceed=true;
+while (proceed==true) {
+ (void) rou_alert(0,"%s JMPDBG phase='%d'",OPEP,phase);
+ switch (phase) {
+ case 0 : { //Building the challenge sequence
+ TIMESPEC cur;
+ char *sessid;
+
+ (void) clock_gettime(CLOCK_REALTIME,&cur);
+ cur.tv_nsec/=10000; //100 millisec
+ sessid=contact->session->sessid;
+ (void) snprintf(challenge,sizeof(challenge),"%05lu-%s",cur.tv_nsec,sessid);
+ }
+ break;
+ case 1 : { //sending challenge to remote
+ char *b64;
+
+ b64=cnv_setb64(challenge);
+ (void) transmit(contact,true,"%d %s",SENDB64,b64);
+ b64=rou_freestr(b64);
+ }
+ break;
+ case 2 : { //getting the challenge answer
+ char *line;
+
+ if (tcp_getline(contact->socptr,delay,&line)>0) {
+ char *res;
+
+ res=cnv_getb64(line);
+ (void) snprintf(answer,sizeof(answer),"%s",res);
+ res=rou_freestr(res);
+ (void) rou_alert(0,"%s JMPDBG challenge answer=<%s>",OPEP,answer);
+ line=rou_freestr(line);
+ }
+ if (strlen(answer)==0)
+ phase=999; //no need to go further
+ }
+ break;
+ case 3 : { //working with challenge answer
+ char *ptr;
+
+ if ((ptr=strchr(answer,' '))!=(char *)0) {
+ *ptr='\000';
+ ptr++;
+ (void) strncpy(name,answer,sizeof(name));
+ (void) memmove(answer,ptr,strlen(ptr)+1);
+ (void) rou_alert(0,"%s JMPDBG user name=<%s> answer=<%s>",
+ OPEP,name,answer);
+ }
+ if (strlen(name)==0)
+ phase=999; //no need to go further
+ }
+ break;
+ case 4 : { //extracting user information
+ USRTYP *usr;
+
+ if (sql_mngusr(contact->sqlptr,sql_select,name,&usr)==true) {
+ (void) snprintf(passwd,sizeof(passwd),"%s",usr->passwd);
+ usr=sql_freeusr(usr);
+ }
+ if (strlen(passwd)==0)
+ phase=999; //no need to go further
+ }
+ break;
+ case 5 : { //comparing challange answer
+ char *local;
+ char *hexa;
+
+ (void) rou_alert(0,"%s passwd=<%s>",OPEP,passwd);
+ local=cnv_hashmd5(passwd,(unsigned char *)challenge);
+ hexa=cnv_tohexa(local);
+ (void) rou_alert(0,"%s anwr=<%s>",OPEP,answer);
+ (void) rou_alert(0,"%s hexa=<%s>",OPEP,hexa);
+ if (strcmp(hexa,answer)==0) {
+ (void) rou_asprintf(&decoded,"%s%s%s%s",
+ IOBNULL,name,IOBNULL,passwd);
+ (void) rou_alert(0,"JMPDBG decoded=<%s>",decoded);
+ }
+ hexa=rou_freestr(hexa);
+ local=rou_freestr(local);
+ }
+ default : //SAFE Guard
+ (void) memset(passwd,'\000',sizeof(passwd));
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+(void) rou_alert(0,"%s JMPDBG decoded=<%s>",OPEP,decoded);
+return decoded;
+
#undef OPEP
}
/*
case 3 : //getting "username password" accorind login type
switch (code) {
case 0 : //AUTH PLAIN
- if ((decoded=get_auth_plain(contact,delay,local))==(char *)0)
- phase=999;
+ decoded=get_auth_plain(contact,delay,local);
break;
case 1 : //AUTH LOGIN
- if ((decoded=get_auth_login(contact,delay))==(char *)0)
- phase=999;
+ decoded=get_auth_login(contact,delay);
break;
case 2 : //AUTH CRAM-MD5
+ decoded=get_auth_cram_md5(contact,delay);
+ break;
case 3 : //AUTH DIGEST-MD5
- if ((decoded=get_auth_md5(contact,delay))==(char *)0)
- phase=999;
+ decoded=get_auth_md5(contact,delay);
break;
default : //not yet implemented
(void) transmit(contact,true,"%d 5.7.3 Unknown auth mode",FAILED);
break;
}
break;
- case 4 : //we have a decoded sequence, check password
+ case 4 : //do we have a decoded sequence??
+ if (decoded==(char *)0) {
+ (void) transmit(contact,true,"%d 5.7.4 empty auth sequence",FAILED);
+ phase=999;
+ }
+ break;
+ case 5 : //we have a decoded sequence, check password
isok=checklogin(contact->sqlptr,decoded);
break;
- case 5 : //we have login status
+ case 6 : //we have login status
if (strlen(decoded)>0) { //always
char *data[3];
const char *fmt;