...
 
Commits (2)
  • Rob Swindell's avatar
    Use a more-liberal username matching algorithm · 00c56b2a
    Rob Swindell authored
    - Ignore all non-trailing non-alphanumeric characters when comparing a string against a user's name. Previously, spaces and dots and underscores were mostly-treated as equivalent and white-space was sometimes compressed for comparison purposes (if the user name contained both spaces and dots). This updated algo helps to insure that deliberate or accidental name collisions cannot be created but also aids usability (e.g. users can make some minor cosmetic adjustments to their user name and still be considered the "same user" for most comparison purposes).
    - Terminate the comparison string at an '@' (ignore everything after). This resolves the FAQ of why users can't login with "username@domain" and aides some other username/address matching algorithms (e.g. in the mailserver). '@'s are illegal characters for usernames already.
    
    Expose the new algorithm via new function matchusername().
    Use the algorithm in matchuser() and lookup_user().
    
    Unrelated: don't lower-case the 'localuser' part of email addresses in  usermailaddr() - cosmetic only.
    00c56b2a
  • Rob Swindell's avatar
    Better FTN netmail gating support · 22faceee
    Rob Swindell authored
    Revert the previous change to the mailsrvr (don't try to parse the MS Outlook singled-quoted names in to/from header fields).
    
    Instead, use the new matchusername() to perform a liberal name match against the name portion of the destination email address and if it matches, go ahead and use the quoted-name field. Otherwise, use the name portion of the destination address as the TO field for the FTN netmail message.
    22faceee
......@@ -2719,9 +2719,6 @@ static void parse_mail_address(char* p
if((tp=strchr(p,'"'))!=NULL) { /* name in quotes? */
p=tp+1;
tp=strchr(p,'"');
} else if(*p == '\'') { /* MS Outlook will put names in single-quotes */
p++;
tp=strchr(p, '\'');
} else if((tp=strchr(p,'('))!=NULL) { /* name in parenthesis? */
p=tp+1;
tp=strchr(p,')');
......@@ -3976,6 +3973,10 @@ static void smtp_thread(void* arg)
*tp = 0;
truncsp(rcpt_name);
}
if(!matchusername(&scfg, rcpt_name, rcpt_to)) {
SAFECOPY(rcpt_name, rcpt_to);
truncstr(rcpt_name, "@");
}
}
smb_hfield_str(&newmsg, RECIPIENT, rcpt_name);
if(forward_path[0] != 0)
......@@ -4663,10 +4664,9 @@ static void smtp_thread(void* arg)
faddr.zone = zone;
lprintf(LOG_INFO,"%04d %s %s %s relaying to FidoNet address: %s (%s)"
,socket, client.protocol, client_id, relay_user.alias, tp+1, smb_faddrtoa(&faddr, NULL));
,socket, client.protocol, client_id, relay_user.alias, p, smb_faddrtoa(&faddr, NULL));
fprintf(rcptlst,"[%u]\n",rcpt_count++);
fprintf(rcptlst,"%s=%s\n",smb_hfieldtype(RECIPIENT),rcpt_addr);
fprintf(rcptlst,"%s=%s\n",smb_hfieldtype(RECIPIENT), p);
fprintf(rcptlst,"%s=%u\n",smb_hfieldtype(RECIPIENTNETTYPE),NET_FIDO);
fprintf(rcptlst,"%s=%s\n",smb_hfieldtype(RECIPIENTNETADDR),smb_faddrtoa(&faddr,NULL));
fprintf(rcptlst,"%s=%s\n",smb_hfieldtype(SMTPFORWARDPATH),rcpt_to);
......
......@@ -56,10 +56,8 @@ static const char* strIpFilterExemptConfigFile = "ipfilter_exempt.cfg";
uint matchuser(scfg_t* cfg, const char *name, BOOL sysop_alias)
{
int file,c;
char* p;
char dat[LEN_ALIAS+2];
char str[256];
char tmp[256];
ulong l,length;
FILE* stream;
......@@ -79,42 +77,7 @@ uint matchuser(scfg_t* cfg, const char *name, BOOL sysop_alias)
for(c=0;c<LEN_ALIAS;c++)
if(dat[c]==ETX) break;
dat[c]=0;
if(!stricmp(dat,name))
break;
/* convert dots to spaces */
strcpy(str,dat);
REPLACE_CHARS(str,'.',' ',p);
if(!stricmp(str,name))
break;
/* convert spaces to dots */
strcpy(str,dat);
REPLACE_CHARS(str,' ','.',p);
if(!stricmp(str,name))
break;
/* convert dots to underscores */
strcpy(str,dat);
REPLACE_CHARS(str,'.','_',p);
if(!stricmp(str,name))
break;
/* convert underscores to dots */
strcpy(str,dat);
REPLACE_CHARS(str,'_','.',p);
if(!stricmp(str,name))
break;
/* convert spaces to underscores */
strcpy(str,dat);
REPLACE_CHARS(str,' ','_',p);
if(!stricmp(str,name))
break;
/* convert underscores to spaces */
strcpy(str,dat);
REPLACE_CHARS(str,'_',' ',p);
if(!stricmp(str,name))
break;
/* strip spaces (from both) */
strip_space(dat,str);
strip_space(name,tmp);
if(!stricmp(str,tmp))
if(matchusername(cfg, dat, name))
break;
}
fclose(stream);
......@@ -123,6 +86,33 @@ uint matchuser(scfg_t* cfg, const char *name, BOOL sysop_alias)
return(0);
}
/****************************************************************************/
/* Return TRUE if the user 'name' (or alias) matches with 'comp' */
/* ... ignoring non-alpha-numeric chars in either string */
/* and terminating the comparison string at an '@' */
/****************************************************************************/
BOOL matchusername(scfg_t* cfg, const char* name, const char* comp)
{
(void)cfg; // in case we want this matching logic to be configurable in the future
const char* np = name;
const char* cp = comp;
while(*np != '\0' && *cp != '\0' && *cp != '@') {
if(!isalnum(*np)) {
np++;
continue;
}
if(!isalnum(*cp)) {
cp++;
continue;
}
if(toupper(*np) != toupper(*cp))
break;
np++, cp++;
}
return *np == '\0' && (*cp == '\0' || *cp == '@');
}
/****************************************************************************/
uint total_users(scfg_t* cfg)
{
......@@ -2625,7 +2615,6 @@ char* usermailaddr(scfg_t* cfg, char* addr, const char* name)
for(i=0;addr[i];i++)
if(addr[i]==' ' || addr[i]&0x80)
addr[i]='.';
strlwr(addr);
}
if(VALID_CFG(cfg)) {
strcat(addr,"@");
......@@ -3653,11 +3642,11 @@ int lookup_user(scfg_t* cfg, link_list_t* list, const char *inname)
close(userdat);
}
for(list_node_t* node = listFirstNode(list); node != NULL; node = node->next) {
if(stricmp(((user_t*)node->data)->alias, inname) == 0)
if(matchusername(cfg, ((user_t*)node->data)->alias, inname))
return ((user_t*)node->data)->number;
}
for(list_node_t* node = listFirstNode(list); node != NULL; node = node->next) {
if(stricmp(((user_t*)node->data)->name, inname) == 0)
if(matchusername(cfg, ((user_t*)node->data)->name, inname))
return ((user_t*)node->data)->number;
}
return 0;
......
......@@ -75,6 +75,7 @@ DLLEXPORT int fgetuserdat(scfg_t*, user_t*, int file);
DLLEXPORT int putuserdat(scfg_t*, user_t*); /* Put userdat struct into user file */
DLLEXPORT int newuserdat(scfg_t*, user_t*); /* Create new userdat in user file */
DLLEXPORT uint matchuser(scfg_t*, const char *str, BOOL sysop_alias); /* Checks for a username match */
DLLEXPORT BOOL matchusername(scfg_t*, const char* name, const char* compare);
DLLEXPORT char* alias(scfg_t*, const char* name, char* buf);
DLLEXPORT int putusername(scfg_t*, int number, char * name);
DLLEXPORT uint total_users(scfg_t*);
......