Fixed FTS-0001 password check

This commit is contained in:
Michiel Broek 2003-08-24 16:27:57 +00:00
parent 1442a4babc
commit b3dbbdbb6c
9 changed files with 217 additions and 163 deletions

View File

@ -48,6 +48,9 @@ v0.37.6 10-Aug-2003
Set the EMSI receive failure count to 20 instead of 6, we can Set the EMSI receive failure count to 20 instead of 6, we can
now even accept buggy maindoor sessions and still display a now even accept buggy maindoor sessions and still display a
banner. banner.
For FTS-0001 sessions the mail password was used instead of the
session password. Also improved the password check.
The product code was not entered in the FTS-0001 packet headers.
mbsetup: mbsetup:
In the nodes setup a switch is added to fallback to the wrong In the nodes setup a switch is added to fallback to the wrong

2
TODO
View File

@ -113,6 +113,8 @@ mbcico:
N: FTS-0001 sessions always are secure, the password check is not N: FTS-0001 sessions always are secure, the password check is not
good. good.
N: The FTS-0001 incoming hello packet is not after a session.
mbfile: mbfile:
L: Add a check to see if the magic filenames are (still) valid. L: Add a check to see if the magic filenames are (still) valid.

View File

@ -258,7 +258,7 @@ int chkftnmsgid(char *);
/* /*
* From getheader.c * From getheader.c
*/ */
int getheader(faddr *, faddr *, FILE *, char *); int getheader(faddr *, faddr *, FILE *, char *, int);
@ -384,7 +384,7 @@ int getarchiver(char *);
/* /*
* From packet.c * From packet.c
*/ */
FILE *openpkt(FILE *, faddr *, char); FILE *openpkt(FILE *, faddr *, char, int);
void closepkt(void); void closepkt(void);

View File

@ -1,11 +1,11 @@
/***************************************************************************** /*****************************************************************************
* *
* $Id$
* File ..................: ftnmsg.c * File ..................: ftnmsg.c
* Purpose ...............: Fidonet mailer * Purpose ...............: Fidonet mailer
* Last modification date : 09-Nov-2000
* *
***************************************************************************** *****************************************************************************
* Copyright (C) 1997-2000 * Copyright (C) 1997-2003
* *
* Michiel Broek FIDO: 2:280/2802 * Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10 * Beekmansbos 10
@ -75,7 +75,7 @@ FILE *ftnmsghdr(ftnmsg *fmsg, FILE *pkt, faddr *route, char flavor, char *Pid)
if (route == NULL) if (route == NULL)
route = fmsg->to; route = fmsg->to;
pkt = openpkt(pkt, route, flavor); pkt = openpkt(pkt, route, flavor, FALSE);
if (pkt == NULL) if (pkt == NULL)
return NULL; return NULL;

View File

@ -50,11 +50,15 @@ char pktpwd[9];
* 2 - Read header error * 2 - Read header error
* 3 - Not for me * 3 - Not for me
* 4 - Password error * 4 - Password error
* 5 - Unsecure session
*
* If session is TRUE, the password is checked as being the session password,
* otherwise it is checked as the mail password.
*/ */
int getheader(faddr *f, faddr *t, FILE *pkt, char *pname) int getheader(faddr *f, faddr *t, FILE *pkt, char *pname, int session)
{ {
unsigned char buffer[0x3a]; unsigned char buffer[0x3a];
int i, pwdok, capword, prodx, major, minor = 0, tome = FALSE; int i, capword, prodx, major, minor = 0, tome = FALSE;
char *p, *prodn = NULL, *fa, *ta, buf[5]; char *p, *prodn = NULL, *fa, *ta, buf[5];
long year, month, day, hour, min, sec; long year, month, day, hour, min, sec;
@ -189,26 +193,44 @@ int getheader(faddr *f, faddr *t, FILE *pkt, char *pname)
buf[4] = '\0'; buf[4] = '\0';
} }
pwdok = TRUE;
if (noderecord(f)) {
if (strcasecmp(nodes.Epasswd, pktpwd) != 0) {
pwdok = FALSE;
if (strlen(pktpwd))
Syslog('!', "Password : got \"%s\", expected \"%s\"", pktpwd, nodes.Epasswd);
}
} else {
Syslog('+', "Node not in setup");
}
if (prodn) if (prodn)
free(prodn); free(prodn);
if (!tome) if (!tome)
return 3; return 3;
else if (!pwdok && nodes.MailPwdCheck)
return 4; if (session) {
else /*
return 0; * FTS-0001 session setup mode.
*/
if (noderecord(f) && strlen(nodes.Spasswd)) {
if (strcasecmp(nodes.Spasswd, pktpwd) == 0) {
return 0; /* Secure session */
} else {
Syslog('!', "Password : got \"%s\", expected \"%s\"", pktpwd, nodes.Spasswd);
return 4; /* Bad password */
}
} else {
Syslog('+', "Node not in setup or no password set");
return 5; /* Unsecure session */
}
} else {
/*
* Mail password check
*/
if (noderecord(f) && nodes.MailPwdCheck && strlen(nodes.Epasswd)) {
if (strcasecmp(nodes.Epasswd, pktpwd) == 0) {
return 0; /* Password Ok */
} else {
Syslog('!', "Password : got \"%s\", expected \"%s\"", pktpwd, nodes.Epasswd);
return 4; /* Bad password */
}
} else {
return 0; /* Not checked, still Ok */
}
}
return 0;
} }

View File

@ -4,7 +4,7 @@
* Purpose ...............: Fidonet mailer * Purpose ...............: Fidonet mailer
* *
***************************************************************************** *****************************************************************************
* Copyright (C) 1997-2002 * Copyright (C) 1997-2003
* *
* Michiel Broek FIDO: 2:280/2802 * Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10 * Beekmansbos 10
@ -42,150 +42,160 @@
static FILE *pktfp=NULL; static FILE *pktfp=NULL;
static faddr pktroute = static faddr pktroute =
{ {
NULL,0,0,0,0,NULL NULL,0,0,0,0,NULL
}; };
FILE *openpkt(FILE *pkt, faddr *addr, char flavor) FILE *openpkt(FILE *pkt, faddr *addr, char flavor, int session)
{ {
off_t pos; off_t pos;
struct flock fl; struct flock fl;
struct stat st; struct stat st;
char *Name; char *Name;
struct tm *ptm; struct tm *ptm;
time_t t; time_t t;
int i; int i;
faddr *bestaka; faddr *bestaka;
unsigned char buffer[0x3a]; unsigned char buffer[0x3a];
char str[9]; char str[9];
if (pkt == NULL) { if (pkt == NULL) {
if (pktfp) { if (pktfp) {
Syslog('P', "packet opened, check address"); Syslog('P', "packet opened, check address");
if (metric(addr,&pktroute) == 0) { if (metric(addr,&pktroute) == 0) {
if ((CFG.maxpktsize == 0L) || if ((CFG.maxpktsize == 0L) || ((fstat(fileno(pktfp),&st) == 0) && (st.st_size < CFG.maxpktsize))) {
((fstat(fileno(pktfp),&st) == 0) && Syslog('P', "return existing fp");
(st.st_size < CFG.maxpktsize))) { return pktfp;
Syslog('P', "return existing fp");
return pktfp;
}
Syslog('P', "packet too big, open new");
closepkt();
} else {
Syslog('P', "address changed, closing fp");
closepkt();
}
} }
Syslog('P', "packet too big, open new");
Syslog('P', "open new packet file"); closepkt();
pktroute.zone = addr->zone; } else {
pktroute.net = addr->net; Syslog('P', "address changed, closing fp");
pktroute.node = addr->node; closepkt();
pktroute.point = addr->point; }
pktroute.domain = xstrcpy(addr->domain);
pktroute.name = NULL;
Name = pktname(addr,flavor);
mkdirs(Name, 0770);
if ((pktfp = fopen(Name, "r+")) == NULL)
pktfp = fopen(Name,"w");
if (pktfp == NULL) {
WriteError("$Unable to open packet %s",MBSE_SS(Name));
return NULL;
}
fl.l_type = F_WRLCK;
fl.l_whence = 0;
fl.l_start = 0L;
fl.l_len = 0L;
if (fcntl(fileno(pktfp), F_SETLKW, &fl) < 0) {
WriteError("$Unable to lock packet %s", MBSE_SS(Name));
fclose(pktfp);
return NULL;
}
pkt = pktfp;
pos = fseek(pkt, -2L, SEEK_END);
} }
pos = ftell(pkt); Syslog('P', "open new packet file");
if (pos <= 0L) { pktroute.zone = addr->zone;
Syslog('P', "creating new .pkt"); pktroute.net = addr->net;
pktroute.node = addr->node;
pktroute.point = addr->point;
pktroute.domain = xstrcpy(addr->domain);
pktroute.name = NULL;
Name = pktname(addr,flavor);
mkdirs(Name, 0770);
memset(&buffer, 0, sizeof(buffer)); if ((pktfp = fopen(Name, "r+")) == NULL)
t = time(NULL); pktfp = fopen(Name,"w");
ptm = localtime(&t); if (pktfp == NULL) {
if (ptm->tm_sec > 59) WriteError("$Unable to open packet %s",MBSE_SS(Name));
ptm->tm_sec = 59; return NULL;
}
bestaka = bestaka_s(addr); fl.l_type = F_WRLCK;
buffer[0x00] = (bestaka->node & 0x00ff); fl.l_whence = 0;
buffer[0x01] = (bestaka->node & 0xff00) >> 8; fl.l_start = 0L;
buffer[0x02] = (addr->node & 0x00ff); fl.l_len = 0L;
buffer[0x03] = (addr->node & 0xff00) >> 8; if (fcntl(fileno(pktfp), F_SETLKW, &fl) < 0) {
buffer[0x04] = ((ptm->tm_year + 1900) & 0x00ff); WriteError("$Unable to lock packet %s", MBSE_SS(Name));
buffer[0x05] = ((ptm->tm_year + 1900) & 0xff00) >> 8; fclose(pktfp);
buffer[0x06] = ptm->tm_mon; return NULL;
buffer[0x08] = ptm->tm_mday; }
buffer[0x0a] = ptm->tm_hour;
buffer[0x0c] = ptm->tm_min;
buffer[0x0e] = ptm->tm_sec;
buffer[0x12] = 2;
buffer[0x14] = (bestaka->net & 0x00ff);
buffer[0x15] = (bestaka->net & 0xff00) >> 8;
buffer[0x16] = (addr->net & 0x00ff);
buffer[0x17] = (addr->net & 0xff00) >> 8;
buffer[0x18] = 0xfe;
memset(&str, 0, 8); pkt = pktfp;
pos = fseek(pkt, -2L, SEEK_END);
}
pos = ftell(pkt);
if (pos <= 0L) {
Syslog('P', "creating new .pkt");
Syslog('s', "openpkt() create .pkt in %s mode", session?"session":"mail");
/*
* Write .PKT header, see FSC-0039 rev. 4
*/
memset(&buffer, 0, sizeof(buffer));
t = time(NULL);
ptm = localtime(&t);
if (ptm->tm_sec > 59)
ptm->tm_sec = 59;
bestaka = bestaka_s(addr);
buffer[0x00] = (bestaka->node & 0x00ff);
buffer[0x01] = (bestaka->node & 0xff00) >> 8;
buffer[0x02] = (addr->node & 0x00ff);
buffer[0x03] = (addr->node & 0xff00) >> 8;
buffer[0x04] = ((ptm->tm_year + 1900) & 0x00ff);
buffer[0x05] = ((ptm->tm_year + 1900) & 0xff00) >> 8;
buffer[0x06] = ptm->tm_mon;
buffer[0x08] = ptm->tm_mday;
buffer[0x0a] = ptm->tm_hour;
buffer[0x0c] = ptm->tm_min;
buffer[0x0e] = ptm->tm_sec;
buffer[0x12] = 2;
buffer[0x14] = (bestaka->net & 0x00ff);
buffer[0x15] = (bestaka->net & 0xff00) >> 8;
buffer[0x16] = (addr->net & 0x00ff);
buffer[0x17] = (addr->net & 0xff00) >> 8;
buffer[0x18] = (PRODCODE & 0x00ff);
buffer[0x19] = (VERSION_MAJOR & 0x00ff);
memset(&str, 0, 8);
if (session) {
if (noderecord(addr) && strlen(nodes.Epasswd)) if (noderecord(addr) && strlen(nodes.Epasswd))
sprintf(str, "%s", nodes.Epasswd); sprintf(str, "%s", nodes.Spasswd);
for (i = 0; i < 8; i++) } else {
buffer[0x1a + i] = str[i]; if (noderecord(addr) && strlen(nodes.Epasswd))
sprintf(str, "%s", nodes.Epasswd);
}
for (i = 0; i < 8; i++)
buffer[0x1a + i] = toupper(str[i]); /* FSC-0039 only talks about A-Z, 0-9, so force uppercase */
buffer[0x22] = (bestaka->zone & 0x00ff); buffer[0x22] = (bestaka->zone & 0x00ff);
buffer[0x23] = (bestaka->zone & 0xff00) >> 8; buffer[0x23] = (bestaka->zone & 0xff00) >> 8;
buffer[0x24] = (addr->zone & 0x00ff); buffer[0x24] = (addr->zone & 0x00ff);
buffer[0x25] = (addr->zone & 0xff00) >> 8; buffer[0x25] = (addr->zone & 0xff00) >> 8;
buffer[0x29] = 1; buffer[0x29] = 1;
buffer[0x2c] = 1; buffer[0x2a] = (PRODCODE & 0xff00) >> 8;
buffer[0x2e] = buffer[0x22]; buffer[0x2b] = (VERSION_MINOR & 0x00ff);
buffer[0x2f] = buffer[0x23]; buffer[0x2c] = 1;
buffer[0x30] = buffer[0x24]; buffer[0x2e] = buffer[0x22];
buffer[0x31] = buffer[0x25]; buffer[0x2f] = buffer[0x23];
buffer[0x32] = (bestaka->point & 0x00ff); buffer[0x30] = buffer[0x24];
buffer[0x33] = (bestaka->point & 0xff00) >> 8; buffer[0x31] = buffer[0x25];
buffer[0x34] = (addr->point & 0x00ff); buffer[0x32] = (bestaka->point & 0x00ff);
buffer[0x35] = (addr->point & 0xff00) >> 8; buffer[0x33] = (bestaka->point & 0xff00) >> 8;
buffer[0x36] = 'm'; buffer[0x34] = (addr->point & 0x00ff);
buffer[0x37] = 'b'; buffer[0x35] = (addr->point & 0xff00) >> 8;
buffer[0x38] = 's'; buffer[0x36] = 'm';
buffer[0x39] = 'e'; buffer[0x37] = 'b';
buffer[0x38] = 's';
buffer[0x39] = 'e';
fseek(pkt, 0L, SEEK_SET); fseek(pkt, 0L, SEEK_SET);
fwrite(buffer, 1, 0x3a, pkt); fwrite(buffer, 1, 0x3a, pkt);
} }
return pkt; return pkt;
} }
void closepkt(void) void closepkt(void)
{ {
unsigned char buffer[2]; unsigned char buffer[2];
Syslog('P', "closepkt entered"); Syslog('P', "closepkt entered");
memset(&buffer, 0, sizeof(buffer)); memset(&buffer, 0, sizeof(buffer));
if (pktfp) { if (pktfp) {
fwrite(buffer, 1, 2, pktfp); fwrite(buffer, 1, 2, pktfp);
fclose(pktfp); /* close also discards lock */ fclose(pktfp); /* close also discards lock */
} }
pktfp = NULL; pktfp = NULL;
if (pktroute.domain) if (pktroute.domain)
free(pktroute.domain); free(pktroute.domain);
} }

View File

@ -4,7 +4,7 @@
* Purpose ...............: fidonet mailer * Purpose ...............: fidonet mailer
* *
***************************************************************************** *****************************************************************************
* Copyright (C) 1997-2002 * Copyright (C) 1997-2003
* *
* Michiel Broek FIDO: 2:280/2802 * Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10 * Beekmansbos 10
@ -358,9 +358,12 @@ file_list *create_filelist(fa_list *al, char *fl, int create)
} }
} }
/*
* For FTS-0001 we need to create at least one packet.
*/
if (((st == NULL) && (create > 1)) || ((st != NULL) && (packets == 0) && (create > 0))) { if (((st == NULL) && (create > 1)) || ((st != NULL) && (packets == 0) && (create > 0))) {
Syslog('o', "Create packet for %s", ascfnode(al->addr,0x1f)); Syslog('o', "Create packet for %s", ascfnode(al->addr,0x1f));
if ((fp = openpkt(NULL, al->addr, 'o'))) { if ((fp = openpkt(NULL, al->addr, 'o', TRUE))) {
memset(&buffer, 0, sizeof(buffer)); memset(&buffer, 0, sizeof(buffer));
fwrite(buffer, 1, 2, fp); fwrite(buffer, 1, 2, fp);
fclose(fp); fclose(fp);

View File

@ -60,6 +60,7 @@ static int recvfiles(void);
static file_list *tosend; static file_list *tosend;
extern int Loaded; extern int Loaded;
extern pid_t mypid; extern pid_t mypid;
extern char *tempinbound;
@ -370,9 +371,9 @@ SM_NAMES
(char *)"scan_packet", (char *)"scan_packet",
(char *)"recv_file" (char *)"recv_file"
SM_EDECL SM_EDECL
int rc = 0, protect = FALSE; int rc = 0, ghc = 0;
char recvpktname[16]; char recvpktname[16];
char *fpath; char *fpath, *tpath;
FILE *fp; FILE *fp;
faddr f, t; faddr f, t;
fa_list **tmpl; fa_list **tmpl;
@ -407,18 +408,21 @@ SM_STATE(scan_packet)
fpath = xstrcat(fpath,recvpktname); fpath = xstrcat(fpath,recvpktname);
mkdirs(fpath, 0700); mkdirs(fpath, 0700);
fp = fopen(fpath,"r"); fp = fopen(fpath,"r");
free(fpath);
if (fp == NULL) { if (fp == NULL) {
WriteError("$cannot open received packet"); WriteError("$cannot open received packet");
free(fpath);
SM_ERROR; SM_ERROR;
} }
switch (getheader(&f , &t, fp, recvpktname)) { switch ((ghc = getheader(&f , &t, fp, recvpktname, TRUE))) {
case 3: Syslog('+', "remote mistook us for %s",ascfnode(&t,0x1f)); case 3: Syslog('+', "remote mistook us for %s",ascfnode(&t,0x1f));
fclose(fp); fclose(fp);
Syslog('s', "Unlink %s rc=%d", fpath, unlink(fpath));
free(fpath);
SM_ERROR; SM_ERROR;
case 0: Syslog('+', "accepting session"); case 0:
case 5: Syslog('+', "accepting session");
fclose(fp); fclose(fp);
for (tmpl=&remote;*tmpl;tmpl=&((*tmpl)->next)); for (tmpl = &remote; *tmpl; tmpl = &((*tmpl)->next));
(*tmpl)=(fa_list*)malloc(sizeof(fa_list)); (*tmpl)=(fa_list*)malloc(sizeof(fa_list));
(*tmpl)->next=NULL; (*tmpl)->next=NULL;
(*tmpl)->addr=(faddr*)malloc(sizeof(faddr)); (*tmpl)->addr=(faddr*)malloc(sizeof(faddr));
@ -457,18 +461,26 @@ SM_STATE(scan_packet)
if (nlent) if (nlent)
rdoptions(Loaded); rdoptions(Loaded);
/* if (ghc == 0) {
* It appears that if the remote gave no password, the
* getheader function fills in a password itself. Maybe
* that's the reason why E.C did not switch to protected
* inbound, because of the failing password check. MB.
*/
if (f.name) {
Syslog('+', "Password correct, protected FTS-0001 session"); Syslog('+', "Password correct, protected FTS-0001 session");
protect = TRUE; inbound_open(remote->addr, TRUE);
} else {
Syslog('+', "Unsecure FTS-0001 session");
inbound_open(remote->addr, FALSE);
} }
inbound_open(remote->addr, protect); /*
* Move the packet to the temp inbound so the we can later
* move it to the final inbound.
*/
tpath = xstrcpy(tempinbound);
tpath = xstrcat(tpath,(char *)"/");
tpath = xstrcat(tpath,recvpktname);
Syslog('s', "Move %s to %s rc=%d", fpath, tpath, file_mv(fpath, tpath));
free(fpath);
free(tpath);
tosend = create_filelist(remote,(char *)ALL_MAIL,1); tosend = create_filelist(remote,(char *)ALL_MAIL,1);
if (rc == 0) { if (rc == 0) {
SM_PROCEED(recv_file); SM_PROCEED(recv_file);
@ -479,6 +491,8 @@ SM_STATE(scan_packet)
default: default:
Syslog('+', "received bad packet apparently from",ascfnode(&f,0x1f)); Syslog('+', "received bad packet apparently from",ascfnode(&f,0x1f));
fclose(fp); fclose(fp);
Syslog('s', "Unlink %s rc=%d", fpath, unlink(fpath));
free(fpath);
SM_ERROR; SM_ERROR;
} }

View File

@ -279,7 +279,7 @@ int TossPkt(char *fn)
memset(&from, 0, sizeof(faddr)); memset(&from, 0, sizeof(faddr));
memset(&to, 0, sizeof(faddr)); memset(&to, 0, sizeof(faddr));
if (((rc = getheader(&from, &to, pkt, fn)) != 0)) { if (((rc = getheader(&from, &to, pkt, fn, FALSE)) != 0)) {
WriteError("%s, aborting", WriteError("%s, aborting",
(rc == 1)?"wrong header type": (rc == 1)?"wrong header type":
(rc == 2)?"bad packet header": (rc == 2)?"bad packet header":