contact->logptr=log_closelog(contact->logptr);
contact->recipients=(RCPTYP **)rou_freelist((void **)contact->recipients,
(genfree_t)eml_freerecipient);
+ contact->authname=rou_freestr(contact->authname);
contact->mailfrom=rou_freestr(contact->mailfrom);
contact->mainsesid=rou_freestr(contact->mainsesid);
contact->fqdn=rou_freestr(contact->fqdn);
*/
/********************************************************/
/* */
+/* Procedure to split a plain authentication string*/
+/* Match with the user provided. */
+/* */
+/********************************************************/
+static void split_auth_plain(char *sequence,char *data[3])
+
+{
+char *locdata[3];
+char *dup;
+char *ptr;
+int count;
+
+(void) memset(locdata,'\000',sizeof(locdata));
+dup=strdup(sequence);
+ptr=dup;
+for (count=0;(count<3)&&(ptr!=(char *)0);count++) {
+ char *mark;
+
+ if ((mark=strstr(ptr,IOBNULL))!=(char *)0) {
+ *mark='\000';
+ mark+=strlen(IOBNULL);
+ }
+ locdata[count]=strdup(ptr);
+ ptr=mark;
+ }
+(void) memmove(data,locdata,sizeof(locdata));
+dup=rou_freestr(dup);
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to check if the password submitted */
+/* Match with the user provided. */
+/* */
+/********************************************************/
+static _Bool checklogin(SQLPTR *sqlptr,char *sequence)
+
+{
+#define OPEP "lvleml.c:checklogin,"
+
+_Bool isok;
+char *data[3];
+int phase;
+_Bool proceed;
+
+isok=false;
+(void) memset(data,'\000',sizeof(data));
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //make sure we have data
+ (void) split_auth_plain(sequence,data);
+ if ((data[1]==(char *)0)||(data[2]==(char *)0)) {
+ (void) rou_alert(0,"%s missing data from <%s> (Bug?)",OPEP,sequence);
+ phase=999; //No need to go further
+ }
+ break;
+ case 1 : //do we have valide data?
+ if ((strlen(data[1])==0)||(strlen(data[2])==0)) {
+ (void) rou_alert(0,"%s data[1]=<%s> or data[2]=<%s> missing (Bug?)",
+ OPEP,data[1],data[2]);
+ phase=999; //No need to go further
+ }
+ break;
+ case 2 : { //checking user password
+ USRTYP *usr;
+
+ usr=(USRTYP *)0;
+ if (sql_mngusr(sqlptr,sql_select,data[1],&usr)==true) {
+ char *crypted;
+
+ crypted=data[2];
+ if (usr->passwd[0]=='$')
+ crypted=crypt(data[2],usr->passwd);
+ if ((crypted!=(char *)0)&&(strcmp(crypted,usr->passwd)==0))
+ isok=true; //Passord match
+ usr=sql_freeusr(usr);
+ }
+ }
+ break;
+ default : //SAFE Guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+for (int i=0;i<3;i++)
+ data[i]=rou_freestr(data[i]);
+return isok;
+
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
/* Procedure to manage authentication in "plain" */
/* mode, return "decoded", NULL if not extracted */
/* */
/********************************************************/
-static char *get_auth_plain(CONTYP *contact,char *received)
+static _Bool get_auth_plain(CONTYP *contact,char *received,char **rmtpass)
{
#define OPEP "lvleml.c:get_auth_plain,"
+_Bool goodpass;
char *decoded;
+goodpass=false;
+*rmtpass=(char *)0;
decoded=(char *)0;
if ((received==(char *)0)||(strlen(received)==0)) {
char *line;
line=rou_freestr(line);
}
}
-else
+else
decoded=cnv_getb64(received);
-return decoded;
+if (decoded!=(char *)0) {
+ goodpass=checklogin(contact->sqlptr,decoded);
+ decoded=rou_freestr(decoded);
+ }
+return goodpass;
#undef OPEP
}
*/
/********************************************************/
/* */
+/* Procedure to manage authentication in "login" */
+/* mode, return goodpass true if successful */
+/* */
+/********************************************************/
+static _Bool get_auth_login(CONTYP *contact,char **rmtpass)
+
+{
+static char *logdat[]={"VXNlcm5hbWU6", //Username: in B64
+ "UGFzc3dvcmQ6", //Password: in B64
+ (char *)0};
+_Bool goodpass;
+char local[200];
+
+goodpass=false;
+(void) memset(local,'\000',sizeof(local));
+for (int i=0;i<2;i++) {
+ char *line;
+ char *ptr;
+ int got;
+
+ (void) strcat(local,IOBNULL);
+ (void) transmit(contact,true,"%d %s",SENDB64,logdat[i]);
+ got=tcp_getline(contact->socptr,contact->delay,&line);
+ if (got<=0) {
+ (void) strcpy(local,"");
+ (void) transmit(contact,true,"%d 5.7.2 auth sequence missing",UKNUSER);
+ break; //exiting from loop
+ }
+ (void) log_fprintlog(contact->logptr,false,"%s",line);
+ if ((ptr=cnv_getb64(line))!=(char *)0) {
+ (void) strncat(local,ptr,(sizeof(local)-1)-strlen(ptr));
+ ptr=rou_freestr(ptr);
+ }
+ line=rou_freestr(line);
+ }
+if (strlen(local)>0)
+ goodpass=checklogin(contact->sqlptr,local);
+return goodpass;
+}
+/*
+^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)
+static _Bool get_auth_cram_md5(CONTYP *contact,char **rmtpass)
{
#define OPEP "lvleml.c:get_auth_cram_md5,"
-char *decoded;
+_Bool goodpass;
char challenge[300];
char answer[300];
char name[300];
int phase;
_Bool proceed;
-decoded=(char *)0;
+goodpass=false;
(void) memset(challenge,'\000',sizeof(challenge));
(void) memset(answer,'\000',sizeof(answer));
(void) memset(name,'\000',sizeof(name));
(void) memset(passwd,'\000',sizeof(passwd));
+*rmtpass=strdup("$1(ukn as cram_md5)");
phase=0;
proceed=true;
while (proceed==true) {
hexa=cnv_tohexa(local,strlen(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) strncpy(passwd,"$1(ukn as cram_md5)",sizeof(passwd)-1);
- (void) rou_asprintf(&decoded,"%s%s%s%s",IOBNULL,name,IOBNULL,passwd);
+ goodpass=(strcmp(hexa,answer)==0);
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;
+return goodpass;
#undef OPEP
}
/* */
/* */
/********************************************************/
-static char *get_auth_digest_md5(CONTYP *contact)
+static void get_auth_digest_md5(CONTYP *contact,char **rmtpass)
{
#define OPEP "lvleml.c:get_auth_digest_md5,"
-char *decoded;
+char *tmppass;
char *challenge;
-char *curpass;
RSPTYP *resp;
char answer[300];
int phase;
_Bool proceed;
-decoded=(char *)0;
+tmppass="bigre"; //JMPDBG need to be improved
+*rmtpass=strdup("$1(ukn as digest_md5)");
challenge=(char *)0;
-curpass=(char *)0;
resp=(RSPTYP *)0;
(void) memset(answer,'\000',sizeof(answer));
phase=0;
USRTYP *usr;
if (sql_mngusr(contact->sqlptr,sql_select,resp->username,&usr)==true) {
- if (usr->passwd!=(char *)0)
- curpass=strdup(usr->passwd);
usr=sql_freeusr(usr);
}
- if (curpass==(char *)0)
- phase=999; //No user found
}
break;
case 5 : { //sending the rspauth sequence.
char *HAS;
char *rspauth;
char *b64;
-
- if ((HAS=dig_hashresp(resp,"",curpass))==(char *)0) {
+ if ((HAS=dig_hashresp(resp,"",tmppass))==(char *)0) {
(void) rou_alert(0,"%s Unable to get the hash rspauth (Bug!)",OPEP);
break;
}
case 7 : { //comparing result.
char *HA0;
- if ((HA0=dig_hashresp(resp,"AUTHENTICATE",curpass))==(char *)0) {
+ if ((HA0=dig_hashresp(resp,"AUTHENTICATE",tmppass))==(char *)0) {
(void) rou_alert(0,"%s Unable to get the hash response (Bug!)",OPEP);
break;
}
- if (strcmp(HA0,resp->response)!=0) {
- //user authentication failed
- curpass=rou_freestr(curpass);
- (void) rou_asprintf(&curpass,"$1(ukn as digest_md5)");
- }
+ contact->authenticated=(strcmp(HA0,resp->response)==0);
HA0=rou_freestr(HA0);
}
break;
- case 8 : //comparing answer
- (void) rou_asprintf(&decoded,"%s%s%s%s",IOBNULL,resp->username,
- IOBNULL,curpass);
- break;
default : //SAFE Guard
proceed=false;
break;
phase++;
}
resp=dig_freeresp(resp);
-curpass=rou_freestr(curpass);
challenge=rou_freestr(challenge);
-return decoded;
#undef OPEP
}
*/
/********************************************************/
/* */
-/* Procedure to manage authentication in "login" */
-/* mode, return "decoded", NULL if not extracted */
-/* */
-/********************************************************/
-static char *get_auth_login(CONTYP *contact)
-
-{
-static char *logdat[]={"VXNlcm5hbWU6", //Username: in B64
- "UGFzc3dvcmQ6", //Password: in B64
- (char *)0};
-char *decoded;
-char local[200];
-
-decoded=(char *)0;
-(void) memset(local,'\000',sizeof(local));
-for (int i=0;i<2;i++) {
- char *line;
- char *ptr;
- int got;
-
- (void) strcat(local,IOBNULL);
- (void) transmit(contact,true,"%d %s",SENDB64,logdat[i]);
- got=tcp_getline(contact->socptr,contact->delay,&line);
- if (got<=0) {
- (void) strcpy(local,"");
- (void) transmit(contact,true,"%d 5.7.2 auth sequence missing",UKNUSER);
- break; //exiting from loop
- }
- (void) log_fprintlog(contact->logptr,false,"%s",line);
- if ((ptr=cnv_getb64(line))!=(char *)0) {
- (void) strncat(local,ptr,(sizeof(local)-1)-strlen(ptr));
- ptr=rou_freestr(ptr);
- }
- line=rou_freestr(line);
- }
-if (strlen(local)>0)
- decoded=strdup(local);
-return decoded;
-}
-/*
-^L
-*/
-/********************************************************/
-/* */
-/* Procedure to split a plain authentication string*/
-/* Match with the user provided. */
-/* */
-/********************************************************/
-static void split_auth_plain(char *sequence,char *data[3])
-
-{
-char *locdata[3];
-char *dup;
-char *ptr;
-int count;
-
-(void) memset(locdata,'\000',sizeof(locdata));
-dup=strdup(sequence);
-ptr=dup;
-for (count=0;(count<3)&&(ptr!=(char *)0);count++) {
- char *mark;
-
- if ((mark=strstr(ptr,IOBNULL))!=(char *)0) {
- *mark='\000';
- mark+=strlen(IOBNULL);
- }
- locdata[count]=strdup(ptr);
- ptr=mark;
- }
-(void) memmove(data,locdata,sizeof(locdata));
-dup=rou_freestr(dup);
-}
-/*
-^L
-*/
-/********************************************************/
-/* */
-/* Procedure to check if the password submitted */
-/* Match with the user provided. */
-/* */
-/********************************************************/
-static _Bool checklogin(SQLPTR *sqlptr,char *sequence)
-
-{
-#define OPEP "lvleml.c:checklogin,"
-
-_Bool isok;
-char *data[3];
-int phase;
-_Bool proceed;
-
-isok=false;
-(void) memset(data,'\000',sizeof(data));
-phase=0;
-proceed=true;
-while (proceed==true) {
- switch (phase) {
- case 0 : //make sure we have data
- (void) split_auth_plain(sequence,data);
- if ((data[1]==(char *)0)||(data[2]==(char *)0)) {
- (void) rou_alert(0,"%s missing data from <%s> (Bug?)",OPEP,sequence);
- phase=999; //No need to go further
- }
- break;
- case 1 : //do we have valide data?
- if ((strlen(data[1])==0)||(strlen(data[2])==0)) {
- (void) rou_alert(0,"%s data[1]=<%s> or data[2]=<%s> missing (Bug?)",
- OPEP,data[1],data[2]);
- phase=999; //No need to go further
- }
- break;
- case 2 : { //checking user password
- USRTYP *usr;
-
- usr=(USRTYP *)0;
- if (sql_mngusr(sqlptr,sql_select,data[1],&usr)==true) {
- char *crypted;
-
- crypted=data[2];
- if (usr->passwd[0]=='$')
- crypted=crypt(data[2],usr->passwd);
- if ((crypted!=(char *)0)&&(strcmp(crypted,usr->passwd)==0))
- isok=true; //Passord match
- usr=sql_freeusr(usr);
- }
- }
- break;
- default : //SAFE Guard
- proceed=false;
- break;
- }
- phase++;
- }
-for (int i=0;i<3;i++)
- data[i]=rou_freestr(data[i]);
-return isok;
-
-#undef OPEP
-}
-/*
-^L
-*/
-/********************************************************/
-/* */
/* Procedure to extract authentication info. */
/* return a login sequence as */
/* 'username password' if successful */
static char *vocloc[]={"PLAIN","LOGIN","CRAM-MD5","DIGEST-MD5",(char *)0};
-_Bool isok;
int code;
-char *decoded;
+char *rmtpass;
char local[200];
int phase;
_Bool proceed;
-isok=false;
code=-1;
-decoded=(char *)0;
+rmtpass=(char *)0;
(void) memset(local,'\000',sizeof(memset));
phase=0;
proceed=true;
switch (code) {
case 0 : //AUTH PLAIN
if (soc_iscrypted(contact->socptr)==true)
- decoded=get_auth_plain(contact,local);
+ (void) get_auth_plain(contact,local,&rmtpass);
else
(void) transmit(contact,true,"%d 5.7.3 Unsafe PLAIN auth mode",FAILED);
break;
case 1 : //AUTH LOGIN
if (soc_iscrypted(contact->socptr)==true)
- decoded=get_auth_login(contact);
+ (void) get_auth_login(contact,&rmtpass);
else
- (void) transmit(contact,true,"%d 5.7.3 Unsafe LOGIN auth mode",FAILED);
+ (void) transmit(contact,true,"%d 5.7.4 Unsafe LOGIN auth mode",FAILED);
break;
case 2 : //AUTH CRAM-MD5
- decoded=get_auth_cram_md5(contact);
+ (void) get_auth_cram_md5(contact,&rmtpass);
break;
case 3 : //AUTH DIGEST-MD5
- decoded=get_auth_digest_md5(contact);
+ (void) get_auth_digest_md5(contact,&rmtpass);
break;
default : //not yet implemented
- (void) transmit(contact,true,"%d 5.7.3 Unknown auth mode",FAILED);
+ (void) transmit(contact,true,"%d 5.7.5 Unknown auth mode",FAILED);
(void) rou_alert(0,"%s auth type <%d> not yet implemented",OPEP);
phase=999;
break;
}
break;
- 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;
+ case 4 : { //do we have a decoded sequence??
+ char *fmt;
+ char *auth;
+
+ fmt=" Auth accepted for user=<%s>";
+ auth=contact->authname;
+ if (contact->authenticated==false) {
+ fmt=" Auth Rejected status='%d' for user=<%s> pass=<%s>";
+ (void) log_fprintlog(contact->logptr,true,fmt,BADAUTH,auth,rmtpass);
+ (void) sleep(2);
+ (void) transmit(contact,true,"%d 5.7.4 authentication failed",BADAUTH);
}
- break;
- case 5 : //we have a decoded sequence, check password
- isok=checklogin(contact->sqlptr,decoded);
- contact->authenticated=true;
- break;
- case 6 : //we have login status
- if (strlen(decoded)>0) { //always
- char *data[3];
- const char *fmt;
-
- (void) memset(data,'\000',sizeof(data));
- (void) split_auth_plain(decoded,data);
- fmt=" Auth accepted for user=<%s>";
- if (isok==false) {
- fmt=" Auth Rejected status='%d' for user=<%s> pass=<%s>";
- (void) log_fprintlog(contact->logptr,true,fmt,BADAUTH,data[1],data[2]);
- (void) sleep(2);
- (void) transmit(contact,true,"%d 5.7.4 authentication failed",BADAUTH);
- }
- else {
- (void) log_fprintlog(contact->logptr,true,fmt,data[1]);
- (void) transmit(contact,true,"%d 5.7.5 Authentication successful",IDOK);
- }
- for (int i=0;i<3;i++)
- data[i]=rou_freestr(data[i]);
+ else {
+ (void) log_fprintlog(contact->logptr,true,fmt,auth[1]);
+ (void) transmit(contact,true,"%d 5.7.5 Authentication successful",IDOK);
}
- decoded=rou_freestr(decoded);
+ }
break;
default : //SAFE Guard
proceed=false;
}
phase++;
}
-return isok;
+rmtpass=rou_freestr(rmtpass);
+return contact->authenticated;
#undef OPEP
}
/*