This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-mbse/lib/getheader.c
2003-08-24 16:27:57 +00:00

237 lines
6.6 KiB
C

/*****************************************************************************
*
* $Id$
* Purpose ...............: Read fidonet .pkt header
*
*****************************************************************************
* Copyright (C) 1997-2003
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
* 1971 BV IJmuiden
* the Netherlands
*
* This file is part of MBSE BBS.
*
* This BBS is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* MBSE BBS is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MBSE BBS; see the file COPYING. If not, write to the Free
* Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*****************************************************************************/
#define DB_NODES
#include "../config.h"
#include "libs.h"
#include "structs.h"
#include "users.h"
#include "records.h"
#include "clcomm.h"
#include "common.h"
faddr pktfrom;
char pktpwd[9];
/*
* Return codes:
* 0 - All Seems Well
* 1 - Invalid type (not 2 or 2+)
* 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 session)
{
unsigned char buffer[0x3a];
int i, capword, prodx, major, minor = 0, tome = FALSE;
char *p, *prodn = NULL, *fa, *ta, buf[5];
long year, month, day, hour, min, sec;
f->domain = NULL;
f->name = NULL;
t->domain = NULL;
t->name = NULL;
/*
* Read type 2+ packet header, see FSC-0039 version 4 and FTS-0001
*/
if (fread(buffer, 1, 0x3a, pkt) != 0x3a) {
WriteError("$Could not read header (%s)", pname);
return 2;
}
if ((buffer[0x12] + (buffer[0x13] << 8)) != 2) {
WriteError("Not a type 2 packet (%s)", pname);
return 1;
}
f->node = (buffer[0x01] << 8) + buffer[0x00];
t->node = (buffer[0x03] << 8) + buffer[0x02];
f->net = (buffer[0x15] << 8) + buffer[0x14];
t->net = (buffer[0x17] << 8) + buffer[0x16];
f->zone = (buffer[0x23] << 8) + buffer[0x22];
t->zone = (buffer[0x25] << 8) + buffer[0x24];
year = (buffer[0x05] << 8) + buffer[0x04];
/*
* Check for Y2K bugs, if there are any this is not important,
* it is just for logging!
*/
if (year < 50)
year = year + 2000;
else if (year < 1900)
year = year + 1900;
month = (buffer[0x07] << 8) + buffer[0x06] + 1;
day = (buffer[0x09] << 8) + buffer[0x08];
hour = (buffer[0x0b] << 8) + buffer[0x0a];
min = (buffer[0x0d] << 8) + buffer[0x0c];
sec = (buffer[0x0f] << 8) + buffer[0x0e];
prodx = buffer[0x18];
major = buffer[0x19];
capword = (buffer[0x2d] << 8) + buffer[0x2c];
if (capword != ((buffer[0x28] << 8) + buffer[0x29]))
capword = 0;
if (capword & 0x0001) {
/*
* FSC-0039 packet type 2+
*/
prodx = prodx + (buffer[0x2a] << 8);
minor = buffer[0x2b];
f->zone = buffer[0x2e] + (buffer[0x2f] << 8);
t->zone = buffer[0x30] + (buffer[0x31] << 8);
f->point = buffer[0x32] + (buffer[0x33] << 8);
t->point = buffer[0x34] + (buffer[0x35] << 8);
} else {
/*
* Stone age @%#$@
*/
f->zone = buffer[0x22] + (buffer[0x23] << 8);
t->zone = buffer[0x24] + (buffer[0x25] << 8);
if ((f->zone == 0) && (t->zone == 0)) {
/*
* No zone info, since the packet should be for us, guess the zone
* against our aka's from the setup using a 2d test.
*/
for (i = 0; i < 40; i++) {
if ((CFG.akavalid[i]) && (t->net == CFG.aka[i].net) && (t->node == CFG.aka[i].node)) {
t->zone = CFG.aka[i].zone;
f->zone = CFG.aka[i].zone;
Syslog('!', "Warning, zone %d assumed", CFG.aka[i].zone);
break;
}
}
}
}
for (i = 0; i < 8; i++)
pktpwd[i] = buffer[0x1a + i];
pktpwd[8]='\0';
for (p = pktpwd + 7; (p >= pktpwd) && (*p == ' '); p--) *p='\0';
if (pktpwd[0])
f->name = pktpwd;
/*
* Fill in a default product code in case it doesn't exist
*/
sprintf(buf, "%04x", prodx);
prodn = xstrcpy((char *)"Unknown 0x");
prodn = xstrcat(prodn, buf);
for (i = 0; ftscprod[i].name; i++)
if (ftscprod[i].code == prodx) {
free(prodn);
prodn = xstrcpy(ftscprod[i].name);
break;
}
pktfrom.name = NULL;
pktfrom.domain = NULL;
pktfrom.zone = f->zone;
pktfrom.net = f->net;
pktfrom.node = f->node;
if (capword & 0x0001)
pktfrom.point = f->point;
else
pktfrom.point = 0;
for (i = 0; i < 40; i++) {
if ((CFG.akavalid[i]) && ((t->zone == 0) || (t->zone == CFG.aka[i].zone)) &&
(t->net == CFG.aka[i].net) && (t->node == CFG.aka[i].node) &&
((!(capword & 0x0001)) || (t->point == CFG.aka[i].point)))
tome = TRUE;
}
fa = xstrcpy(ascfnode(f, 0x1f));
ta = xstrcpy(ascfnode(t, 0x1f));
Syslog('+', "Packet : %s type %s", pname, (capword & 0x0001) ? "2+":"stone-age");
Syslog('+', "From : %s to %s", fa, ta);
Syslog('+', "Dated : %02u-%02u-%u %02u:%02u:%02u", day, month, year, hour, min, sec);
Syslog('+', "Program : %s %d.%d", prodn, major, minor);
free(ta);
free(fa);
if (capword & 0x0001) {
buf[0] = buffer[0x36];
buf[1] = buffer[0x37];
buf[2] = buffer[0x38];
buf[3] = buffer[0x39];
buf[4] = '\0';
}
if (prodn)
free(prodn);
if (!tome)
return 3;
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;
}