diff --git a/ChangeLog b/ChangeLog index 831aa380..7ae7bb1c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -48,6 +48,9 @@ v0.37.6 10-Aug-2003 Set the EMSI receive failure count to 20 instead of 6, we can now even accept buggy maindoor sessions and still display a 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: In the nodes setup a switch is added to fallback to the wrong diff --git a/TODO b/TODO index 2c18329e..c649eeaa 100644 --- a/TODO +++ b/TODO @@ -113,6 +113,8 @@ mbcico: N: FTS-0001 sessions always are secure, the password check is not good. + N: The FTS-0001 incoming hello packet is not after a session. + mbfile: L: Add a check to see if the magic filenames are (still) valid. diff --git a/lib/common.h b/lib/common.h index 7edebf1e..917574c9 100644 --- a/lib/common.h +++ b/lib/common.h @@ -258,7 +258,7 @@ int chkftnmsgid(char *); /* * 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 */ -FILE *openpkt(FILE *, faddr *, char); +FILE *openpkt(FILE *, faddr *, char, int); void closepkt(void); diff --git a/lib/ftnmsg.c b/lib/ftnmsg.c index 4b7d83c0..402f01ec 100644 --- a/lib/ftnmsg.c +++ b/lib/ftnmsg.c @@ -1,11 +1,11 @@ /***************************************************************************** * + * $Id$ * File ..................: ftnmsg.c * Purpose ...............: Fidonet mailer - * Last modification date : 09-Nov-2000 * ***************************************************************************** - * Copyright (C) 1997-2000 + * Copyright (C) 1997-2003 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -75,7 +75,7 @@ FILE *ftnmsghdr(ftnmsg *fmsg, FILE *pkt, faddr *route, char flavor, char *Pid) if (route == NULL) route = fmsg->to; - pkt = openpkt(pkt, route, flavor); + pkt = openpkt(pkt, route, flavor, FALSE); if (pkt == NULL) return NULL; diff --git a/lib/getheader.c b/lib/getheader.c index 02ead182..248a04c9 100644 --- a/lib/getheader.c +++ b/lib/getheader.c @@ -50,11 +50,15 @@ char pktpwd[9]; * 2 - Read header error * 3 - Not for me * 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]; - 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]; long year, month, day, hour, min, sec; @@ -189,26 +193,44 @@ int getheader(faddr *f, faddr *t, FILE *pkt, char *pname) 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) free(prodn); - if (!tome) + if (!tome) return 3; - else if (!pwdok && nodes.MailPwdCheck) - return 4; - else - return 0; + + if (session) { + /* + * 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; } diff --git a/lib/packet.c b/lib/packet.c index 4ac8bcdf..a999b466 100644 --- a/lib/packet.c +++ b/lib/packet.c @@ -4,7 +4,7 @@ * Purpose ...............: Fidonet mailer * ***************************************************************************** - * Copyright (C) 1997-2002 + * Copyright (C) 1997-2003 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -42,150 +42,160 @@ static FILE *pktfp=NULL; 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; - struct flock fl; - struct stat st; - char *Name; - struct tm *ptm; - time_t t; - int i; - faddr *bestaka; - unsigned char buffer[0x3a]; - char str[9]; + off_t pos; + struct flock fl; + struct stat st; + char *Name; + struct tm *ptm; + time_t t; + int i; + faddr *bestaka; + unsigned char buffer[0x3a]; + char str[9]; - if (pkt == NULL) { - if (pktfp) { - Syslog('P', "packet opened, check address"); - if (metric(addr,&pktroute) == 0) { - if ((CFG.maxpktsize == 0L) || - ((fstat(fileno(pktfp),&st) == 0) && - (st.st_size < CFG.maxpktsize))) { - Syslog('P', "return existing fp"); - return pktfp; - } - Syslog('P', "packet too big, open new"); - closepkt(); - } else { - Syslog('P', "address changed, closing fp"); - closepkt(); - } + if (pkt == NULL) { + if (pktfp) { + Syslog('P', "packet opened, check address"); + if (metric(addr,&pktroute) == 0) { + if ((CFG.maxpktsize == 0L) || ((fstat(fileno(pktfp),&st) == 0) && (st.st_size < CFG.maxpktsize))) { + Syslog('P', "return existing fp"); + return pktfp; } - - Syslog('P', "open new packet file"); - pktroute.zone = addr->zone; - 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); - - 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); + Syslog('P', "packet too big, open new"); + closepkt(); + } else { + Syslog('P', "address changed, closing fp"); + closepkt(); + } } - pos = ftell(pkt); - if (pos <= 0L) { - Syslog('P', "creating new .pkt"); + Syslog('P', "open new packet file"); + pktroute.zone = addr->zone; + 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)); - t = time(NULL); - ptm = localtime(&t); - if (ptm->tm_sec > 59) - ptm->tm_sec = 59; + if ((pktfp = fopen(Name, "r+")) == NULL) + pktfp = fopen(Name,"w"); + if (pktfp == NULL) { + WriteError("$Unable to open packet %s",MBSE_SS(Name)); + return NULL; + } - 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] = 0xfe; + 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; + } - 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)) - sprintf(str, "%s", nodes.Epasswd); - for (i = 0; i < 8; i++) - buffer[0x1a + i] = str[i]; + sprintf(str, "%s", nodes.Spasswd); + } else { + 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[0x23] = (bestaka->zone & 0xff00) >> 8; - buffer[0x24] = (addr->zone & 0x00ff); - buffer[0x25] = (addr->zone & 0xff00) >> 8; - buffer[0x29] = 1; - buffer[0x2c] = 1; - buffer[0x2e] = buffer[0x22]; - buffer[0x2f] = buffer[0x23]; - buffer[0x30] = buffer[0x24]; - buffer[0x31] = buffer[0x25]; - buffer[0x32] = (bestaka->point & 0x00ff); - buffer[0x33] = (bestaka->point & 0xff00) >> 8; - buffer[0x34] = (addr->point & 0x00ff); - buffer[0x35] = (addr->point & 0xff00) >> 8; - buffer[0x36] = 'm'; - buffer[0x37] = 'b'; - buffer[0x38] = 's'; - buffer[0x39] = 'e'; + buffer[0x22] = (bestaka->zone & 0x00ff); + buffer[0x23] = (bestaka->zone & 0xff00) >> 8; + buffer[0x24] = (addr->zone & 0x00ff); + buffer[0x25] = (addr->zone & 0xff00) >> 8; + buffer[0x29] = 1; + buffer[0x2a] = (PRODCODE & 0xff00) >> 8; + buffer[0x2b] = (VERSION_MINOR & 0x00ff); + buffer[0x2c] = 1; + buffer[0x2e] = buffer[0x22]; + buffer[0x2f] = buffer[0x23]; + buffer[0x30] = buffer[0x24]; + buffer[0x31] = buffer[0x25]; + buffer[0x32] = (bestaka->point & 0x00ff); + buffer[0x33] = (bestaka->point & 0xff00) >> 8; + buffer[0x34] = (addr->point & 0x00ff); + buffer[0x35] = (addr->point & 0xff00) >> 8; + buffer[0x36] = 'm'; + buffer[0x37] = 'b'; + buffer[0x38] = 's'; + buffer[0x39] = 'e'; - fseek(pkt, 0L, SEEK_SET); - fwrite(buffer, 1, 0x3a, pkt); - } + fseek(pkt, 0L, SEEK_SET); + fwrite(buffer, 1, 0x3a, pkt); + } - return pkt; + return pkt; } void closepkt(void) { - unsigned char buffer[2]; + unsigned char buffer[2]; - Syslog('P', "closepkt entered"); - memset(&buffer, 0, sizeof(buffer)); + Syslog('P', "closepkt entered"); + memset(&buffer, 0, sizeof(buffer)); - if (pktfp) { - fwrite(buffer, 1, 2, pktfp); - fclose(pktfp); /* close also discards lock */ - } - pktfp = NULL; - if (pktroute.domain) - free(pktroute.domain); + if (pktfp) { + fwrite(buffer, 1, 2, pktfp); + fclose(pktfp); /* close also discards lock */ + } + pktfp = NULL; + if (pktroute.domain) + free(pktroute.domain); } diff --git a/mbcico/filelist.c b/mbcico/filelist.c index 089bbede..83886883 100644 --- a/mbcico/filelist.c +++ b/mbcico/filelist.c @@ -4,7 +4,7 @@ * Purpose ...............: fidonet mailer * ***************************************************************************** - * Copyright (C) 1997-2002 + * Copyright (C) 1997-2003 * * Michiel Broek FIDO: 2:280/2802 * 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))) { 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)); fwrite(buffer, 1, 2, fp); fclose(fp); diff --git a/mbcico/ftsc.c b/mbcico/ftsc.c index e8dbd504..63417519 100644 --- a/mbcico/ftsc.c +++ b/mbcico/ftsc.c @@ -60,6 +60,7 @@ static int recvfiles(void); static file_list *tosend; extern int Loaded; extern pid_t mypid; +extern char *tempinbound; @@ -370,9 +371,9 @@ SM_NAMES (char *)"scan_packet", (char *)"recv_file" SM_EDECL - int rc = 0, protect = FALSE; + int rc = 0, ghc = 0; char recvpktname[16]; - char *fpath; + char *fpath, *tpath; FILE *fp; faddr f, t; fa_list **tmpl; @@ -407,18 +408,21 @@ SM_STATE(scan_packet) fpath = xstrcat(fpath,recvpktname); mkdirs(fpath, 0700); fp = fopen(fpath,"r"); - free(fpath); if (fp == NULL) { WriteError("$cannot open received packet"); + free(fpath); 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)); fclose(fp); + Syslog('s', "Unlink %s rc=%d", fpath, unlink(fpath)); + free(fpath); SM_ERROR; - case 0: Syslog('+', "accepting session"); + case 0: + case 5: Syslog('+', "accepting session"); fclose(fp); - for (tmpl=&remote;*tmpl;tmpl=&((*tmpl)->next)); + for (tmpl = &remote; *tmpl; tmpl = &((*tmpl)->next)); (*tmpl)=(fa_list*)malloc(sizeof(fa_list)); (*tmpl)->next=NULL; (*tmpl)->addr=(faddr*)malloc(sizeof(faddr)); @@ -457,18 +461,26 @@ SM_STATE(scan_packet) if (nlent) rdoptions(Loaded); - /* - * 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) { + if (ghc == 0) { 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); if (rc == 0) { SM_PROCEED(recv_file); @@ -479,6 +491,8 @@ SM_STATE(scan_packet) default: Syslog('+', "received bad packet apparently from",ascfnode(&f,0x1f)); fclose(fp); + Syslog('s', "Unlink %s rc=%d", fpath, unlink(fpath)); + free(fpath); SM_ERROR; } diff --git a/mbfido/tosspkt.c b/mbfido/tosspkt.c index 8ac65314..ac55604d 100644 --- a/mbfido/tosspkt.c +++ b/mbfido/tosspkt.c @@ -279,7 +279,7 @@ int TossPkt(char *fn) memset(&from, 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", (rc == 1)?"wrong header type": (rc == 2)?"bad packet header":