]> SAFE projects GIT repository - jmp/mailleur/commitdiff
Checking password against the hash function
authorJean-Marc Pigeon (Delson) <jmp@safe.ca>
Wed, 9 Jul 2025 11:09:08 +0000 (07:09 -0400)
committerJean-Marc Pigeon (Delson) <jmp@safe.ca>
Wed, 9 Jul 2025 11:09:08 +0000 (07:09 -0400)
lib/devsql.c
lib/lvleml.c
lib/subrou.c
lib/subrou.h
lib/unisql.c
lib/unisql.h

index 80e0bf9372c92fded76c4975a325f2c223d60148..d1c678874dd58ce994e1229893baeb03be6554a8 100644 (file)
@@ -41,17 +41,6 @@ typedef struct  {
         char *name;     //field name;
         }FLDTYP;
 
-//field available in table "emails"
-const FLDTYP usrfield[]={
-          {1,"email"},
-          {2,"password"},
-          {3,"space"},
-          {4,"mxspace"},
-          {5,"locked"},
-          {6,"hash"},
-          {0,(char *)0}
-          };
-
 //field available in table "sessions"
 const char *sesfield[]={
           "sessid",
@@ -319,6 +308,16 @@ static USRTYP *select_user(SQLTYP *sql,char *email)
 #define OPEP    "devsql.c:select_user,"
 #define SELUSR  "SELECT * FROM "EMAILS" WHERE email=%s"
 
+//field available in table "emails"
+static const FLDTYP usrfield[]={
+          {1,"email"},
+          {2,"hash"},
+          {3,"space"},
+          {4,"mxspace"},
+          {5,"locked"},
+          {0,(char *)0}
+          };
+
 USRTYP *usr;
 SQLRES *rs;
 char cmd[300];
@@ -367,8 +366,8 @@ while (proceed==true) {
           case 1        :       //user email
             usr->email=strdup(locval);
             break;
-          case 2        :       //user passwd
-            usr->passwd=strdup(locval);
+          case 2        :       //'email:realm:password' MD5
+            usr->hash=strdup(locval);
             break;
           case 3        :       //user used space
             usr->space=atoi(locval);
@@ -379,9 +378,6 @@ while (proceed==true) {
           case 5        :       //lock status
             usr->lock=atoi(locval);
             break;
-          case 6        :       //'email:realm:password' MD5
-            usr->hash=strdup(locval);
-            break;
           default       :
             (void) rou_alert(0,"%s field <%d:%s> not implemented (Bug?)",
                                    OPEP,usrfield[i].num,usrfield[i].name);
index 810f8309fbfdea897900a294178ab9863a35dad2..7f8aa288ef80c02b16c806a8f52d51607b35eb93 100644 (file)
@@ -359,11 +359,13 @@ static _Bool checklogin(CONTYP *contact,char **rmtpass,char *sequence)
 
 _Bool isok;
 char *data[3];
+char *givenhash;
 int phase;
 _Bool proceed;
 
 isok=false;
 (void) memset(data,'\000',sizeof(data));
+givenhash=(char *)0;
 phase=0;
 proceed=true;
 while (proceed==true) {
@@ -382,42 +384,37 @@ while (proceed==true) {
         phase=999;      //No need to go further
         }
       break;
-    case 2      :  {    //checking user password
+    case 2      :  {    //computing the given md5
+      char *seq;
+      MD5TYP *givenmd5;
+
+      (void) rou_asprintf(&seq,"%s:%s:%s",data[1],rou_getrealm(),data[2]);
+      givenmd5=dig_hashmd5((unsigned char *)seq,strlen(seq));
+      if (givenmd5!=(MD5TYP *)0) {
+        givenhash=cnv_tohexa((char *)givenmd5,sizeof(MD5TYP));
+        (void) free(givenmd5);
+        }
+      if (givenhash==(char *)0) {
+        (void) rou_alert(0,"%s Unable to have md5 for <%s> (Bug?)",seq);
+        phase=999;      //trouble trouble
+        }
+      seq=rou_freestr(seq);
+      }
+      break;
+    case 3      :  {    //checking user password
       USRTYP *usr;
 
       usr=(USRTYP *)0;
       contact->authname=rou_freestr(contact->authname);
       contact->authname=strdup(data[1]);
+      *rmtpass=strdup(data[2]);
       if (sql_mngusr(contact->sqlptr,sql_select,data[1],&usr)==true) {
-        char *givenpass;
-  
-        givenpass=data[2];
-        if (usr->passwd==(char *)0) {
-          (void) rou_alert(0,"%s usr=<%s> password empty, assigning one",
+        if (usr->hash==(char *)0) {
+          usr->hash=cnv_getrndstr(10);
+          (void) rou_alert(0,"%s usr=<%s> password empty, using random hash",
                               OPEP,data[1]);
-          usr->passwd=cnv_getrndstr(10);
           }
-        if (givenpass!=(char *)0) 
-          *rmtpass=strdup(givenpass);
-        if (usr->passwd[0]=='$') {
-          char *ptr;
-          char idsalt[100];
-         
-          (void) memset(idsalt,'\000',sizeof(idsalt));
-          (void) strncpy(idsalt,usr->passwd,sizeof(idsalt)-1);
-          if ((ptr=strrchr(idsalt,'$'))!=(char *)0) {
-            ptr++;
-            *ptr='\000';
-            }
-          if ((ptr=crypt(givenpass,idsalt))==(char *)0) {
-            (void) rou_alert(0,"%s Trouble to crypt (Bug?) givenpass=<%s> "
-                               "salt=<%s> (error=<%s>)",
-                                OPEP,givenpass,idsalt,strerror(errno));
-            ptr=data[2]; //trying to overcome
-            }
-          givenpass=ptr;
-          }
-        isok=(strcmp(givenpass,usr->passwd)==0);
+        isok=(strcmp(givenhash,usr->hash)==0);
         usr=sql_freeusr(usr);
         }
       }
@@ -428,6 +425,7 @@ while (proceed==true) {
     }
   phase++;
   }
+givenhash=rou_freestr(givenhash); 
 for (int i=0;i<3;i++) 
   data[i]=rou_freestr(data[i]);
 return isok;
@@ -521,126 +519,6 @@ if (strlen(local)>0)
 /********************************************************/
 /*                                                      */
 /*     Procedure to manage authentication in           */
-/*      cram_md5 mode.                                  */
-/*      Return a builded "decoded" string from          */
-/*      the exchange with the remote sereur             */
-/*                                                      */
-/********************************************************/
-static void get_auth_cram_md5(CONTYP *contact,char **rmtpass)
-
-{
-#define OPEP    "lvleml.c:get_auth_cram_md5,"
-
-char challenge[300];
-char answer[300];
-char name[300];
-char passwd[300];
-int phase;
-_Bool proceed;
-
-(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) {
-  //(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,contact->delay,&line)>0) {
-        char *res;
-
-        res=cnv_getb64(line);
-        (void) snprintf(answer,sizeof(answer),"%s",res);
-        res=rou_freestr(res);
-        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);
-        }
-      if (strlen(name)==0)
-        phase=999;      //no need to go further
-      }
-      break;
-    case 4      :  {    //extracting user information
-      USRTYP *usr;
-
-      contact->authname=rou_freestr(contact->authname);
-      contact->authname=strdup(name);
-      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      :       //check if password is in clear text
-      if (passwd[0]=='$') {       //local password crypted?
-        (void) transmit(contact,true,"%d-5.8.1 password is crypted",BADPAR);
-        phase=999;      //no need to go further
-        }
-     break;                 //exiting from loop
-    case 6      :  {    //comparing challenge answer
-      char *local;
-      char *hexa;
-
-      local=dig_cryptmd5(passwd,(unsigned char *)challenge); 
-      hexa=cnv_tohexa(local,strlen(local));
-      //(void) rou_alert(0,"%s anwr=<%s>",OPEP,answer);
-      //(void) rou_alert(0,"%s hexa=<%s>",OPEP,hexa);
-      contact->authenticated=(strcmp(hexa,answer)==0);
-      hexa=rou_freestr(hexa);
-      local=rou_freestr(local);
-      }
-      break;
-    default     :       //SAFE Guard
-      proceed=false;
-      break;
-    }
-  phase++;
-  }
-
-#undef  OPEP
-}
-/*
-^L
-*/
-/********************************************************/
-/*                                                      */
-/*     Procedure to manage authentication in           */
 /*      digest-md5 mode.                                */
 /*      Return a builded "decoded" string from          */
 /*      the exchange with the remote sereur             */
@@ -804,7 +682,7 @@ static _Bool getauth(CONTYP *contact,char *buffer)
 {
 #define OPEP    "lvleml.c:getauth,"
 
-static char *vocloc[]={"PLAIN","LOGIN","CRAM-MD5","DIGEST-MD5",(char *)0};
+static char *vocloc[]={"PLAIN","LOGIN","DIGEST-MD5",(char *)0};
 
 int code;
 char *rmtpass;
@@ -866,10 +744,7 @@ while (proceed==true) {
           else
             (void) transmit(contact,true,"%d 5.7.4 Unsafe LOGIN auth mode",FAILED);
           break;
-        case 2          :       //AUTH CRAM-MD5
-          (void) get_auth_cram_md5(contact,&rmtpass);
-          break;
-        case 3          :       //AUTH DIGEST-MD5
+        case 2          :       //AUTH DIGEST-MD5
           (void) get_auth_digest_md5(contact,&rmtpass);
           break;
         default         :       //not yet implemented
@@ -1320,8 +1195,8 @@ static struct   {
       char *str;        //the message to display
       }ehlo[]={
         {1,"STARTTLS"},
-        {1,"AUTH CRAM-MD5 DIGEST-MD5"},
-        {2,"AUTH PLAIN LOGIN CRAM-MD5 DIGEST-MD5"},
+        {1,"AUTH DIGEST-MD5"},
+        {2,"AUTH PLAIN LOGIN DIGEST-MD5"},
         {0,"SIZE "MXMSIZE},
         {0,"8BITMIME"},
         {0,"ENHANCEDSTATUSCODES"},
index 749198d6b3bf25a9788c1a0a2420753dcc384d74..6b8421ba6f6da7e03139c473c198ab2bcf0db875 100644 (file)
@@ -108,7 +108,7 @@ if ((debug>2)&&(current!=onoff)) {
 /*                                                      */
 /*     Procedure to assign enough memory to format     */
 /*      a string with va_list parameter.                */
-/*      Known as vasprintf in GNU_SOURCE.                */
+/*      Known as vasprintf in GNU_SOURCE.               */
 /*                                                      */
 /********************************************************/
 PUBLIC int rou_vasprintf(char **str,const char *fmt,va_list ap)
@@ -130,6 +130,24 @@ return taille;
 */
 /********************************************************/
 /*                                                      */
+/*     Procedure to return the current application     */
+/*      working realm                                   */
+/*                                                      */
+/********************************************************/
+PUBLIC const char *rou_getrealm()
+
+{
+const char *realm;
+
+if ((realm=getenv("REALM"))==(const char *)0)
+   realm=REALM;
+return realm; 
+}
+/*
+\f
+*/
+/********************************************************/
+/*                                                      */
 /*     Procedure to assign enough memory to format     */
 /*      a string.                                       */
 /*      Known as asprintf in GNU_SOURCE.                */
index 1a3c78602ca5bb0d6ce4c253f926ee86f6c2d2d0..298d7a8c17fdab720b546bda628ea49abfe21587 100644 (file)
@@ -45,6 +45,9 @@ extern int rou_vasprintf(char **str,const char *fmt,va_list ap);
 //procedure to assign memory according a format and parameter list
 extern int rou_asprintf(char **str,const char *fmt,...);
 
+//procedure to return the application working realm
+extern const char *rou_getrealm();
+
 //procedure to create needed subdirectory
 extern _Bool rou_do_mkpdir(char *dirpath);
 
index 909a356fc345ca2b5b09719630f01d85a4fcee35..76a1d2885e9ee2f256ece7592e859fbceb64f006 100644 (file)
@@ -107,7 +107,6 @@ PUBLIC USRTYP *sql_freeusr(USRTYP *usr)
 {
 if (usr!=(USRTYP *)0) {
   usr->hash=rou_freestr(usr->hash);
-  usr->passwd=rou_freestr(usr->passwd);
   usr->email=rou_freestr(usr->email);
   (void) free(usr);
   usr=(USRTYP *)0;
index e0dcab8e2ca6edec8772e40e23c8ca4ebe2a61e6..4dcf5535804bba4d63c5031e968dc184ab7444d0 100644 (file)
@@ -20,11 +20,10 @@ typedef enum    {
 //structure about user within the database
 typedef struct  {
         char *email;    //user emails
-        char *passwd;   //user password
+        char *hash;     //'email:realm:password' MD5
         u_int  lock;    //account is lock
         u_long space;   //user space used
         u_long mxspace; //user maximun space
-        char *hash;     //'email:realm:password' MD5
         }USRTYP;
 
 //structure about an email session