A lot of changes in the binkp driver
This commit is contained in:
parent
1cfa9dac7d
commit
a4123fc91e
@ -58,6 +58,11 @@ v0.37.6 10-Aug-2003
|
|||||||
For FTS-0001 sessions the mail password was used instead of the
|
For FTS-0001 sessions the mail password was used instead of the
|
||||||
session password. Also improved the password check.
|
session password. Also improved the password check.
|
||||||
The product code was not entered in the FTS-0001 packet headers.
|
The product code was not entered in the FTS-0001 packet headers.
|
||||||
|
The binkp driver now always reports 1.0 again.
|
||||||
|
Revised some state tables in the binkp session setup stage.
|
||||||
|
Fixed a possible buffer overflow in the binkp driver.
|
||||||
|
Fixed aborting binkp session when the remote sent a empty CRAM
|
||||||
|
password for unprotected session.
|
||||||
|
|
||||||
mbfido:
|
mbfido:
|
||||||
The rfc to ftn gate now drops the headerlines starting with
|
The rfc to ftn gate now drops the headerlines starting with
|
||||||
|
6
TODO
6
TODO
@ -20,6 +20,8 @@ everything:
|
|||||||
|
|
||||||
L: Implement IPv6.
|
L: Implement IPv6.
|
||||||
|
|
||||||
|
L: Document error return codes in the manual.
|
||||||
|
|
||||||
install:
|
install:
|
||||||
N: On some (unsupported) distro's with xinetd the installation script
|
N: On some (unsupported) distro's with xinetd the installation script
|
||||||
also adds entries to inetd.conf.
|
also adds entries to inetd.conf.
|
||||||
@ -111,6 +113,10 @@ mbcico:
|
|||||||
N: Implement binkp resync when getting files. Transmit works.
|
N: Implement binkp resync when getting files. Transmit works.
|
||||||
Under test now!
|
Under test now!
|
||||||
|
|
||||||
|
N: With binkp, if the other node is a binkp/1.0 mailer without MB
|
||||||
|
mode and we did send a FREQ, a poll must be created after the
|
||||||
|
session to pickup the result of the FREQ.
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
419
mbcico/binkp.c
419
mbcico/binkp.c
@ -62,7 +62,14 @@
|
|||||||
#define BNKCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@&=+%$-_.!()#|"
|
#define BNKCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@&=+%$-_.!()#|"
|
||||||
|
|
||||||
|
|
||||||
static char rbuf[2048];
|
static char rbuf[MAX_BLKSIZE + 1];
|
||||||
|
|
||||||
|
static char *bstate[] = {
|
||||||
|
(char *)"NUL", (char *)"ADR", (char *)"PWD", (char *)"FILE", (char *)"OK",
|
||||||
|
(char *)"EOB", (char *)"GOT", (char *)"ERR", (char *)"BSY", (char *)"GET",
|
||||||
|
(char *)"SKIP"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -71,7 +78,7 @@ static char rbuf[2048];
|
|||||||
char *unix2binkp(char *);
|
char *unix2binkp(char *);
|
||||||
char *binkp2unix(char *);
|
char *binkp2unix(char *);
|
||||||
int binkp_expired(void);
|
int binkp_expired(void);
|
||||||
void b_banner(int);
|
void b_banner(void);
|
||||||
void b_nul(char *);
|
void b_nul(char *);
|
||||||
void fill_binkp_list(binkp_list **, file_list *, off_t);
|
void fill_binkp_list(binkp_list **, file_list *, off_t);
|
||||||
void debug_binkp_list(binkp_list **);
|
void debug_binkp_list(binkp_list **);
|
||||||
@ -89,6 +96,8 @@ extern char *ttystat[];
|
|||||||
extern int Loaded;
|
extern int Loaded;
|
||||||
extern pid_t mypid;
|
extern pid_t mypid;
|
||||||
extern struct sockaddr_in peeraddr;
|
extern struct sockaddr_in peeraddr;
|
||||||
|
extern int most_debug;
|
||||||
|
|
||||||
|
|
||||||
extern unsigned long sentbytes;
|
extern unsigned long sentbytes;
|
||||||
extern unsigned long rcvdbytes;
|
extern unsigned long rcvdbytes;
|
||||||
@ -97,24 +106,25 @@ typedef enum {RxWaitFile, RxAcceptFile, RxReceData, RxWriteData, RxEndOfBatch, R
|
|||||||
typedef enum {TxGetNextFile, TxTryRead, TxReadSend, TxWaitLastAck, TxDone} TxType;
|
typedef enum {TxGetNextFile, TxTryRead, TxReadSend, TxWaitLastAck, TxDone} TxType;
|
||||||
typedef enum {InitTransfer, Switch, Receive, Transmit} TransferType;
|
typedef enum {InitTransfer, Switch, Receive, Transmit} TransferType;
|
||||||
typedef enum {Ok, Failure, Continue} TrType;
|
typedef enum {Ok, Failure, Continue} TrType;
|
||||||
|
typedef enum {No, WeCan, TheyWant, Active} OptionState;
|
||||||
|
|
||||||
static int RxState;
|
static int RxState; /* Receiver state */
|
||||||
static int TxState;
|
static int TxState; /* Transmitter state */
|
||||||
static int TfState;
|
//static int TfState;
|
||||||
static time_t Timer;
|
static time_t Timer;
|
||||||
static int NRflag = FALSE;
|
static int MBflag = WeCan; /* MB option flag */
|
||||||
static int MBflag = FALSE;
|
static int CRAMflag = FALSE; /* CRAM option flag */
|
||||||
static int NDflag = FALSE;
|
static int CRCflag = WeCan; /* CRC option flag */
|
||||||
static int CRYPTflag = FALSE;
|
static int Major = 1; /* Remote major protocol version */
|
||||||
static int CRAMflag = FALSE;
|
static int Minor = 0; /* Remote minor protocol version */
|
||||||
static int CRCflag = FALSE;
|
static int Secure = FALSE; /* Secure session */
|
||||||
static int Remote_1_1 = FALSE;
|
unsigned long nethold, mailhold; /* Trafic for the remote */
|
||||||
unsigned long nethold, mailhold;
|
int transferred = FALSE; /* Anything transferred in batch */
|
||||||
int transferred = FALSE;
|
|
||||||
int batchnr = 0, crc_errors = 0;
|
int batchnr = 0, crc_errors = 0;
|
||||||
unsigned char *MD_challenge = NULL; /* Received CRAM challenge data */
|
unsigned char *MD_challenge = NULL; /* Received CRAM challenge data */
|
||||||
int ext_rand = 0;
|
int ext_rand = 0;
|
||||||
|
|
||||||
|
|
||||||
int binkp(int role)
|
int binkp(int role)
|
||||||
{
|
{
|
||||||
int rc = MBERR_OK;
|
int rc = MBERR_OK;
|
||||||
@ -122,6 +132,7 @@ int binkp(int role)
|
|||||||
file_list *tosend = NULL, *request = NULL, *respond = NULL, *tmpfl;
|
file_list *tosend = NULL, *request = NULL, *respond = NULL, *tmpfl;
|
||||||
char *nonhold_mail;
|
char *nonhold_mail;
|
||||||
|
|
||||||
|
most_debug = TRUE;
|
||||||
if (role == 1) {
|
if (role == 1) {
|
||||||
if (orgbinkp()) {
|
if (orgbinkp()) {
|
||||||
rc = MBERR_SESSION_ERROR;
|
rc = MBERR_SESSION_ERROR;
|
||||||
@ -137,15 +148,9 @@ int binkp(int role)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// if (localoptions & NOFREQS)
|
||||||
* Adjust file requests support. We only send requests to binkp/1.1
|
// session_flags &= ~SESSION_WAZOO;
|
||||||
* systems and if file requests are not forbidden by setup.
|
// else
|
||||||
*/
|
|
||||||
if (Remote_1_1 == FALSE)
|
|
||||||
localoptions |= NOFREQS;
|
|
||||||
if (localoptions & NOFREQS)
|
|
||||||
session_flags &= ~SESSION_WAZOO;
|
|
||||||
else
|
|
||||||
session_flags |= SESSION_WAZOO;
|
session_flags |= SESSION_WAZOO;
|
||||||
|
|
||||||
Syslog('b', "Binkp: WAZOO requests: %s", (session_flags & SESSION_WAZOO) ? "True":"False");
|
Syslog('b', "Binkp: WAZOO requests: %s", (session_flags & SESSION_WAZOO) ? "True":"False");
|
||||||
@ -174,7 +179,7 @@ int binkp(int role)
|
|||||||
tidy_filelist(tosend, (rc == 0));
|
tidy_filelist(tosend, (rc == 0));
|
||||||
tosend = NULL;
|
tosend = NULL;
|
||||||
|
|
||||||
if ((rc == 0) && transferred && MBflag) {
|
if ((rc == 0) && transferred && (MBflag == Active)) {
|
||||||
/*
|
/*
|
||||||
* Running Multiple Batch, only if last batch actually
|
* Running Multiple Batch, only if last batch actually
|
||||||
* did transfer some data.
|
* did transfer some data.
|
||||||
@ -194,10 +199,11 @@ int binkp(int role)
|
|||||||
Syslog('+', "Binkp: end transfer rc=%d", rc);
|
Syslog('+', "Binkp: end transfer rc=%d", rc);
|
||||||
closetcp();
|
closetcp();
|
||||||
|
|
||||||
if (!MBflag) {
|
if (MBflag != Active) {
|
||||||
/*
|
/*
|
||||||
* In singe batch mode we process filerequests after the batch.
|
* In singe batch mode we process filerequests after the batch.
|
||||||
* The results will be put on hold for the calling node.
|
* The results will be put on hold for the calling node.
|
||||||
|
* This method is also known as "dual session mode".
|
||||||
*/
|
*/
|
||||||
respond = respond_wazoo();
|
respond = respond_wazoo();
|
||||||
for (tmpfl = respond; tmpfl; tmpfl = tmpfl->next) {
|
for (tmpfl = respond; tmpfl; tmpfl = tmpfl->next) {
|
||||||
@ -321,6 +327,8 @@ void binkp_send_data(char *buf, int len)
|
|||||||
{
|
{
|
||||||
unsigned short header = 0;
|
unsigned short header = 0;
|
||||||
|
|
||||||
|
Syslog('B', "Binkp: send_data len=%d", len);
|
||||||
|
|
||||||
header = ((BINKP_DATA_BLOCK + len) & 0xffff);
|
header = ((BINKP_DATA_BLOCK + len) & 0xffff);
|
||||||
|
|
||||||
PUTCHAR((header >> 8) & 0x00ff);
|
PUTCHAR((header >> 8) & 0x00ff);
|
||||||
@ -355,6 +363,7 @@ void binkp_send_control(int id,...)
|
|||||||
sz = 1;
|
sz = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Syslog('B', "Binkp: send_ctl %s \"%s\"", bstate[id], buf);
|
||||||
frame.header = ((BINKP_CONTROL_BLOCK + sz) & 0xffff);
|
frame.header = ((BINKP_CONTROL_BLOCK + sz) & 0xffff);
|
||||||
frame.id = (char)id;
|
frame.id = (char)id;
|
||||||
frame.data = buf;
|
frame.data = buf;
|
||||||
@ -386,7 +395,7 @@ int binkp_recv_frame(char *buf, int *len, int *cmd)
|
|||||||
|
|
||||||
*len = *cmd = 0;
|
*len = *cmd = 0;
|
||||||
|
|
||||||
b0 = GETCHAR(180);
|
b0 = GETCHAR(BINKP_TIMEOUT);
|
||||||
if (tty_status)
|
if (tty_status)
|
||||||
goto to;
|
goto to;
|
||||||
if (b0 & 0x80)
|
if (b0 & 0x80)
|
||||||
@ -399,7 +408,7 @@ int binkp_recv_frame(char *buf, int *len, int *cmd)
|
|||||||
*len = (b0 & 0x7f) << 8;
|
*len = (b0 & 0x7f) << 8;
|
||||||
*len += b1;
|
*len += b1;
|
||||||
|
|
||||||
GET(buf, *len, 120);
|
GET(buf, *len, BINKP_TIMEOUT / 2);
|
||||||
buf[*len] = '\0';
|
buf[*len] = '\0';
|
||||||
if (tty_status)
|
if (tty_status)
|
||||||
goto to;
|
goto to;
|
||||||
@ -431,7 +440,7 @@ int binkp_expired(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void b_banner(int Norequests)
|
void b_banner(void)
|
||||||
{
|
{
|
||||||
time_t t;
|
time_t t;
|
||||||
|
|
||||||
@ -441,8 +450,7 @@ void b_banner(int Norequests)
|
|||||||
binkp_send_control(MM_NUL,"NDL %s", CFG.Flags);
|
binkp_send_control(MM_NUL,"NDL %s", CFG.Flags);
|
||||||
t = time(NULL);
|
t = time(NULL);
|
||||||
binkp_send_control(MM_NUL,"TIME %s", rfcdate(t));
|
binkp_send_control(MM_NUL,"TIME %s", rfcdate(t));
|
||||||
Syslog('b', "Binkp: M_NUL VER mbcico/%s/%s-%s binkp/1.%d", VERSION, OsName(), OsCPU(), Norequests ? 0 : 1);
|
binkp_send_control(MM_NUL,"VER mbcico/%s/%s-%s %s/%s", VERSION, OsName(), OsCPU(), PRTCLNAME, PRTCLVER);
|
||||||
binkp_send_control(MM_NUL,"VER mbcico/%s/%s-%s binkp/1.%d", VERSION, OsName(), OsCPU(), Norequests ? 0 : 1);
|
|
||||||
if (strlen(CFG.Phone))
|
if (strlen(CFG.Phone))
|
||||||
binkp_send_control(MM_NUL,"PHN %s", CFG.Phone);
|
binkp_send_control(MM_NUL,"PHN %s", CFG.Phone);
|
||||||
if (strlen(CFG.comment))
|
if (strlen(CFG.comment))
|
||||||
@ -453,6 +461,8 @@ void b_banner(int Norequests)
|
|||||||
|
|
||||||
void b_nul(char *msg)
|
void b_nul(char *msg)
|
||||||
{
|
{
|
||||||
|
char *p, *q;
|
||||||
|
|
||||||
if (strncmp(msg, "SYS ", 4) == 0) {
|
if (strncmp(msg, "SYS ", 4) == 0) {
|
||||||
Syslog('+', "System : %s", msg+4);
|
Syslog('+', "System : %s", msg+4);
|
||||||
strncpy(history.system_name, msg+4, 35);
|
strncpy(history.system_name, msg+4, 35);
|
||||||
@ -468,10 +478,10 @@ void b_nul(char *msg)
|
|||||||
Syslog('+', "Time : %s", msg+5);
|
Syslog('+', "Time : %s", msg+5);
|
||||||
else if (strncmp(msg, "VER ", 4) == 0) {
|
else if (strncmp(msg, "VER ", 4) == 0) {
|
||||||
Syslog('+', "Uses : %s", msg+4);
|
Syslog('+', "Uses : %s", msg+4);
|
||||||
if (strstr(msg+4, "binkp/1.1")) {
|
if ((p = strstr(msg+4, PRTCLNAME "/")) && (q = strstr(p, "."))) {
|
||||||
Remote_1_1 = TRUE;
|
Major = atoi(p + 6);
|
||||||
} else {
|
Minor = atoi(q + 1);
|
||||||
Remote_1_1 = FALSE;
|
Syslog('b', "Remote protocol version %d.%d", Major, Minor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strncmp(msg, "PHN ", 4) == 0)
|
else if (strncmp(msg, "PHN ", 4) == 0)
|
||||||
@ -482,16 +492,8 @@ void b_nul(char *msg)
|
|||||||
Syslog('+', "Binkp: remote has %s mail/files for us", msg+4);
|
Syslog('+', "Binkp: remote has %s mail/files for us", msg+4);
|
||||||
else if (strncmp(msg, "OPT ", 4) == 0) {
|
else if (strncmp(msg, "OPT ", 4) == 0) {
|
||||||
Syslog('+', "Options : %s", msg+4);
|
Syslog('+', "Options : %s", msg+4);
|
||||||
if (strstr(msg, (char *)"NR") != NULL)
|
if ((strstr(msg, (char *)"MB") != NULL) && (MBflag == WeCan))
|
||||||
NRflag = TRUE;
|
MBflag = TheyWant;
|
||||||
if (strstr(msg, (char *)"MB") != NULL)
|
|
||||||
MBflag = TRUE;
|
|
||||||
if (strstr(msg, (char *)"ND") != NULL)
|
|
||||||
NDflag = TRUE;
|
|
||||||
if (strstr(msg, (char *)"CRYPT") != NULL) {
|
|
||||||
CRYPTflag = TRUE;
|
|
||||||
// Syslog('+', "Remote requests CRYPT mode");
|
|
||||||
}
|
|
||||||
if (strstr(msg, (char *)"CRAM-MD5-") != NULL) { /* No SHA-1 support */
|
if (strstr(msg, (char *)"CRAM-MD5-") != NULL) { /* No SHA-1 support */
|
||||||
if (CFG.NoMD5) {
|
if (CFG.NoMD5) {
|
||||||
Syslog('+', "Binkp: Remote supports MD5, but it's turned off here");
|
Syslog('+', "Binkp: Remote supports MD5, but it's turned off here");
|
||||||
@ -501,9 +503,8 @@ void b_nul(char *msg)
|
|||||||
MD_challenge = MD_getChallenge(msg, NULL);
|
MD_challenge = MD_getChallenge(msg, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (strstr(msg, (char *)"CRC") != NULL) {
|
if ((strstr(msg, (char *)"CRC") != NULL) && (CRCflag == WeCan)) {
|
||||||
CRCflag = TRUE;
|
CRCflag = TheyWant;
|
||||||
Syslog('b', "Binkp: remote supports CRC32 mode");
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
Syslog('+', "Binkp: M_NUL \"%s\"", msg);
|
Syslog('+', "Binkp: M_NUL \"%s\"", msg);
|
||||||
@ -516,41 +517,50 @@ void b_nul(char *msg)
|
|||||||
*/
|
*/
|
||||||
SM_DECL(orgbinkp, (char *)"orgbinkp")
|
SM_DECL(orgbinkp, (char *)"orgbinkp")
|
||||||
SM_STATES
|
SM_STATES
|
||||||
waitconn,
|
ConnInit,
|
||||||
sendpass,
|
WaitConn,
|
||||||
waitaddr,
|
SendPasswd,
|
||||||
authremote,
|
WaitAddr,
|
||||||
waitok
|
AuthRemote,
|
||||||
|
IfSecure,
|
||||||
|
WaitOk,
|
||||||
|
Opts
|
||||||
SM_NAMES
|
SM_NAMES
|
||||||
(char *)"waitconn",
|
(char *)"ConnInit",
|
||||||
(char *)"sendpass",
|
(char *)"WaitConn",
|
||||||
(char *)"waitaddr",
|
(char *)"SendPasswd",
|
||||||
(char *)"authremote",
|
(char *)"WaitAddr",
|
||||||
(char *)"waitok"
|
(char *)"AuthRemote",
|
||||||
|
(char *)"IfSecure",
|
||||||
|
(char *)"WaitOk",
|
||||||
|
(char *)"Opts"
|
||||||
SM_EDECL
|
SM_EDECL
|
||||||
faddr *primary;
|
faddr *primary;
|
||||||
char *p, *q;
|
char *p, *q, *pwd;
|
||||||
int i, rc, bufl, cmd, dupe;
|
int i, rc, bufl, cmd, dupe, SendPass = FALSE;
|
||||||
fa_list **tmp, *tmpa;
|
fa_list **tmp, *tmpa;
|
||||||
int SendPass = FALSE;
|
|
||||||
faddr *fa, ra;
|
faddr *fa, ra;
|
||||||
|
|
||||||
SM_START(waitconn)
|
SM_START(ConnInit)
|
||||||
|
|
||||||
SM_STATE(waitconn)
|
SM_STATE(ConnInit)
|
||||||
|
|
||||||
|
SM_PROCEED(WaitConn)
|
||||||
|
|
||||||
|
SM_STATE(WaitConn)
|
||||||
|
|
||||||
Loaded = FALSE;
|
Loaded = FALSE;
|
||||||
Syslog('+', "Binkp: node %s", ascfnode(remote->addr, 0x1f));
|
Syslog('+', "Binkp: node %s", ascfnode(remote->addr, 0x1f));
|
||||||
IsDoing("Connect binkp %s", ascfnode(remote->addr, 0xf));
|
IsDoing("Connect binkp %s", ascfnode(remote->addr, 0xf));
|
||||||
if ((noderecord(remote->addr)) && nodes.CRC32 && !CFG.NoCRC32) {
|
p = xstrcpy((char *)"OPT");
|
||||||
binkp_send_control(MM_NUL,"OPT MB CRC");
|
if (MBflag == WeCan)
|
||||||
} else {
|
p = xstrcat(p, (char *)" MB");
|
||||||
binkp_send_control(MM_NUL,"OPT MB");
|
if ((noderecord(remote->addr)) && nodes.CRC32 && !CFG.NoCRC32)
|
||||||
}
|
p = xstrcat(p, (char *)" CRC");
|
||||||
if (((noderecord(remote->addr)) && nodes.NoFreqs) || CFG.NoFreqs)
|
if (strcmp(p, (char *)"OPT"))
|
||||||
b_banner(TRUE);
|
binkp_send_control(MM_NUL, p);
|
||||||
else
|
free(p);
|
||||||
b_banner(FALSE);
|
b_banner();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build a list of aka's to send, the primary aka first.
|
* Build a list of aka's to send, the primary aka first.
|
||||||
@ -577,9 +587,9 @@ SM_STATE(waitconn)
|
|||||||
binkp_send_control(MM_ADR, "%s", p);
|
binkp_send_control(MM_ADR, "%s", p);
|
||||||
free(p);
|
free(p);
|
||||||
tidy_faddr(primary);
|
tidy_faddr(primary);
|
||||||
SM_PROCEED(waitaddr)
|
SM_PROCEED(WaitAddr)
|
||||||
|
|
||||||
SM_STATE(waitaddr)
|
SM_STATE(WaitAddr)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((rc = binkp_recv_frame(rbuf, &bufl, &cmd))) {
|
if ((rc = binkp_recv_frame(rbuf, &bufl, &cmd))) {
|
||||||
@ -591,22 +601,22 @@ SM_STATE(waitaddr)
|
|||||||
if (rbuf[0] == MM_ADR) {
|
if (rbuf[0] == MM_ADR) {
|
||||||
p = xstrcpy(&rbuf[1]);
|
p = xstrcpy(&rbuf[1]);
|
||||||
tidy_falist(&remote);
|
tidy_falist(&remote);
|
||||||
remote = NULL;
|
remote = NULL;
|
||||||
tmp = &remote;
|
tmp = &remote;
|
||||||
|
|
||||||
for (q = strtok(p, " "); q; q = strtok(NULL, " "))
|
for (q = strtok(p, " "); q; q = strtok(NULL, " ")) {
|
||||||
if ((fa = parsefnode(q))) {
|
if ((fa = parsefnode(q))) {
|
||||||
dupe = FALSE;
|
dupe = FALSE;
|
||||||
for (tmpa = remote; tmpa; tmpa = tmpa->next) {
|
for (tmpa = remote; tmpa; tmpa = tmpa->next) {
|
||||||
if ((tmpa->addr->zone == fa->zone) && (tmpa->addr->net == fa->net) &&
|
if ((tmpa->addr->zone == fa->zone) && (tmpa->addr->net == fa->net) &&
|
||||||
(tmpa->addr->node == fa->node) && (tmpa->addr->point == fa->point) &&
|
(tmpa->addr->node == fa->node) && (tmpa->addr->point == fa->point) &&
|
||||||
(strcmp(tmpa->addr->domain, fa->domain) == 0)) {
|
(strcmp(tmpa->addr->domain, fa->domain) == 0)) {
|
||||||
dupe = TRUE;
|
dupe = TRUE;
|
||||||
Syslog('b', "Binkp: double address %s", ascfnode(tmpa->addr, 0x1f));
|
Syslog('b', "Binkp: double address %s", ascfnode(tmpa->addr, 0x1f));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!dupe) {
|
if (!dupe) {
|
||||||
*tmp = (fa_list*)malloc(sizeof(fa_list));
|
*tmp = (fa_list*)malloc(sizeof(fa_list));
|
||||||
(*tmp)->next = NULL;
|
(*tmp)->next = NULL;
|
||||||
(*tmp)->addr = fa;
|
(*tmp)->addr = fa;
|
||||||
@ -614,14 +624,15 @@ SM_STATE(waitaddr)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Syslog('!', "Binkp: bad remote address: \"%s\"", printable(q, 0));
|
Syslog('!', "Binkp: bad remote address: \"%s\"", printable(q, 0));
|
||||||
binkp_send_control(MM_ERR, "Bad address");
|
binkp_send_control(MM_ERR, "Bad address");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (tmpa = remote; tmpa; tmpa = tmpa->next) {
|
for (tmpa = remote; tmpa; tmpa = tmpa->next) {
|
||||||
Syslog('+', "Address : %s", ascfnode(tmpa->addr, 0x1f));
|
Syslog('+', "Address : %s", ascfnode(tmpa->addr, 0x1f));
|
||||||
if (nodelock(tmpa->addr)) {
|
if (nodelock(tmpa->addr)) {
|
||||||
binkp_send_control(MM_BSY, "Address %s locked", ascfnode(tmpa->addr, 0x1f));
|
binkp_send_control(MM_BSY, "Address %s locked", ascfnode(tmpa->addr, 0x1f));
|
||||||
SM_ERROR;
|
SM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -629,60 +640,64 @@ SM_STATE(waitaddr)
|
|||||||
* when the remote presents us an address we don't know about.
|
* when the remote presents us an address we don't know about.
|
||||||
*/
|
*/
|
||||||
if (!Loaded) {
|
if (!Loaded) {
|
||||||
if (noderecord(tmpa->addr))
|
if (noderecord(tmpa->addr))
|
||||||
Loaded = TRUE;
|
Loaded = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
history.aka.zone = remote->addr->zone;
|
history.aka.zone = remote->addr->zone;
|
||||||
history.aka.net = remote->addr->net;
|
history.aka.net = remote->addr->net;
|
||||||
history.aka.node = remote->addr->node;
|
history.aka.node = remote->addr->node;
|
||||||
history.aka.point = remote->addr->point;
|
history.aka.point = remote->addr->point;
|
||||||
sprintf(history.aka.domain, "%s", remote->addr->domain);
|
sprintf(history.aka.domain, "%s", remote->addr->domain);
|
||||||
|
|
||||||
SM_PROCEED(sendpass)
|
|
||||||
|
|
||||||
|
SM_PROCEED(SendPasswd)
|
||||||
|
|
||||||
} else if (rbuf[0] == MM_BSY) {
|
} else if (rbuf[0] == MM_BSY) {
|
||||||
Syslog('!', "Binkp: M_BSY \"%s\"", printable(&rbuf[1], 0));
|
Syslog('!', "Binkp: M_BSY \"%s\"", printable(&rbuf[1], 0));
|
||||||
SM_ERROR;
|
SM_ERROR;
|
||||||
|
|
||||||
} else if (rbuf[0] == MM_ERR) {
|
} else if (rbuf[0] == MM_ERR) {
|
||||||
Syslog('!', "Binkp: M_ERR \"%s\"", printable(&rbuf[1], 0));
|
Syslog('!', "Binkp: M_ERR \"%s\"", printable(&rbuf[1], 0));
|
||||||
SM_ERROR;
|
SM_ERROR;
|
||||||
|
|
||||||
} else if (rbuf[0] == MM_NUL) {
|
} else if (rbuf[0] == MM_NUL) {
|
||||||
b_nul(&rbuf[1]);
|
b_nul(&rbuf[1]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
binkp_send_control(MM_ERR, "Unexpected frame");
|
||||||
|
SM_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SM_STATE(sendpass)
|
SM_STATE(SendPasswd)
|
||||||
|
|
||||||
if (MD_challenge && strlen(nodes.Spasswd)) {
|
if (Loaded && strlen(nodes.Spasswd)) {
|
||||||
char *pw = NULL, *tp = NULL;
|
pwd = xstrcpy(nodes.Spasswd);
|
||||||
pw = xstrcpy(nodes.Spasswd);
|
SendPass = TRUE;
|
||||||
tp = MD_buildDigest(pw, MD_challenge);
|
} else {
|
||||||
|
pwd = xstrcpy((char *)"-");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MD_challenge) {
|
||||||
|
char *tp = NULL;
|
||||||
|
tp = MD_buildDigest(pwd, MD_challenge);
|
||||||
if (!tp) {
|
if (!tp) {
|
||||||
Syslog('!', "Unable to build MD5 digest");
|
Syslog('!', "Unable to build MD5 digest");
|
||||||
SM_ERROR;
|
SM_ERROR;
|
||||||
}
|
}
|
||||||
SendPass = TRUE;
|
|
||||||
CRAMflag = TRUE;
|
CRAMflag = TRUE;
|
||||||
binkp_send_control(MM_PWD, "%s", tp);
|
binkp_send_control(MM_PWD, "%s", tp);
|
||||||
free(tp);
|
free(tp);
|
||||||
free(pw);
|
|
||||||
} else {
|
} else {
|
||||||
if (strlen(nodes.Spasswd)) {
|
binkp_send_control(MM_PWD, "%s", pwd);
|
||||||
SendPass = TRUE;
|
|
||||||
binkp_send_control(MM_PWD, "%s", nodes.Spasswd);
|
|
||||||
} else {
|
|
||||||
binkp_send_control(MM_PWD, "-");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SM_PROCEED(authremote)
|
free(pwd);
|
||||||
|
SM_PROCEED(AuthRemote)
|
||||||
|
|
||||||
SM_STATE(authremote)
|
SM_STATE(AuthRemote)
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
for (tmpa = remote; tmpa; tmpa = tmpa->next) {
|
for (tmpa = remote; tmpa; tmpa = tmpa->next) {
|
||||||
@ -693,14 +708,18 @@ SM_STATE(authremote)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
SM_PROCEED(waitok)
|
SM_PROCEED(IfSecure)
|
||||||
} else {
|
} else {
|
||||||
Syslog('!', "Binkp: error, the wrong node is reached");
|
Syslog('!', "Binkp: error, the wrong node is reached");
|
||||||
binkp_send_control(MM_ERR, "No AKAs in common or all AKAs busy");
|
binkp_send_control(MM_ERR, "No AKAs in common or all AKAs busy");
|
||||||
SM_ERROR;
|
SM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
SM_STATE(waitok)
|
SM_STATE(IfSecure)
|
||||||
|
|
||||||
|
SM_PROCEED(WaitOk)
|
||||||
|
|
||||||
|
SM_STATE(WaitOk)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((rc = binkp_recv_frame(rbuf, &bufl, &cmd))) {
|
if ((rc = binkp_recv_frame(rbuf, &bufl, &cmd))) {
|
||||||
@ -711,26 +730,38 @@ SM_STATE(waitok)
|
|||||||
if (cmd) {
|
if (cmd) {
|
||||||
if (rbuf[0] == MM_OK) {
|
if (rbuf[0] == MM_OK) {
|
||||||
Syslog('!', "Binkp: M_OK \"%s\"", printable(&rbuf[1], 0));
|
Syslog('!', "Binkp: M_OK \"%s\"", printable(&rbuf[1], 0));
|
||||||
if (SendPass)
|
if (SendPass)
|
||||||
Syslog('+', "Binkp: %spassword protected session", CRAMflag ? "MD5 ":"");
|
Secure = TRUE;
|
||||||
else
|
Syslog('+', "Binkp: %s%sprotected session", CRAMflag ? "MD5 ":"", Secure ? "":"un");
|
||||||
Syslog('+', "Binkp: unprotected session");
|
SM_PROCEED(Opts)
|
||||||
SM_SUCCESS;
|
|
||||||
|
|
||||||
} else if (rbuf[0] == MM_BSY) {
|
} else if (rbuf[0] == MM_BSY) {
|
||||||
Syslog('!', "Binkp: M_BSY \"%s\"", printable(&rbuf[1], 0));
|
Syslog('!', "Binkp: M_BSY \"%s\"", printable(&rbuf[1], 0));
|
||||||
SM_ERROR;
|
SM_ERROR;
|
||||||
|
|
||||||
} else if (rbuf[0] == MM_ERR) {
|
} else if (rbuf[0] == MM_ERR) {
|
||||||
Syslog('!', "Binkp: M_ERR \"%s\"", printable(&rbuf[1], 0));
|
Syslog('!', "Binkp: M_ERR \"%s\"", printable(&rbuf[1], 0));
|
||||||
SM_ERROR;
|
SM_ERROR;
|
||||||
|
|
||||||
} else if (rbuf[0] == MM_NUL) {
|
} else if (rbuf[0] == MM_NUL) {
|
||||||
b_nul(&rbuf[1]);
|
b_nul(&rbuf[1]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
binkp_send_control(MM_ERR, "Unexpected frame");
|
||||||
|
SM_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SM_STATE(Opts)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Room to negotiate more protocol options.
|
||||||
|
* When we are binkp/1.1 and remote is 1.0 we should
|
||||||
|
* negotiate MB mode here.
|
||||||
|
*/
|
||||||
|
SM_SUCCESS;
|
||||||
|
|
||||||
SM_END
|
SM_END
|
||||||
SM_RETURN
|
SM_RETURN
|
||||||
|
|
||||||
@ -741,25 +772,29 @@ SM_RETURN
|
|||||||
*/
|
*/
|
||||||
SM_DECL(ansbinkp, (char *)"ansbinkp")
|
SM_DECL(ansbinkp, (char *)"ansbinkp")
|
||||||
SM_STATES
|
SM_STATES
|
||||||
waitconn,
|
WaitConn,
|
||||||
waitaddr,
|
WaitAddr,
|
||||||
waitpwd,
|
IsPasswd,
|
||||||
pwdack
|
WaitPwd,
|
||||||
|
PwdAck,
|
||||||
|
Opts
|
||||||
SM_NAMES
|
SM_NAMES
|
||||||
(char *)"waitconn",
|
(char *)"WaitConn",
|
||||||
(char *)"waitaddr",
|
(char *)"WaitAddr",
|
||||||
(char *)"waitpwd",
|
(char *)"IsPasswd",
|
||||||
(char *)"pwdack"
|
(char *)"WaitPwd",
|
||||||
|
(char *)"PwdAck",
|
||||||
|
(char *)"Opts"
|
||||||
|
|
||||||
SM_EDECL
|
SM_EDECL
|
||||||
char *p, *q;
|
char *p, *q, *pw;
|
||||||
int i, rc, bufl, cmd, dupe;
|
int i, rc, bufl, cmd, dupe, we_have_pwd = FALSE;
|
||||||
fa_list **tmp, *tmpa;
|
fa_list **tmp, *tmpa;
|
||||||
faddr *fa;
|
faddr *fa;
|
||||||
|
|
||||||
SM_START(waitconn)
|
SM_START(WaitConn)
|
||||||
|
|
||||||
SM_STATE(waitconn)
|
SM_STATE(WaitConn)
|
||||||
|
|
||||||
Loaded = FALSE;
|
Loaded = FALSE;
|
||||||
|
|
||||||
@ -780,7 +815,7 @@ SM_STATE(waitconn)
|
|||||||
Syslog('b', "Binkp: sending \"%s\"", s);
|
Syslog('b', "Binkp: sending \"%s\"", s);
|
||||||
binkp_send_control(MM_NUL, "%s", s);
|
binkp_send_control(MM_NUL, "%s", s);
|
||||||
}
|
}
|
||||||
b_banner(CFG.NoFreqs);
|
b_banner();
|
||||||
p = xstrcpy((char *)"");
|
p = xstrcpy((char *)"");
|
||||||
|
|
||||||
for (i = 0; i < 40; i++)
|
for (i = 0; i < 40; i++)
|
||||||
@ -791,9 +826,9 @@ SM_STATE(waitconn)
|
|||||||
|
|
||||||
binkp_send_control(MM_ADR, "%s", p);
|
binkp_send_control(MM_ADR, "%s", p);
|
||||||
free(p);
|
free(p);
|
||||||
SM_PROCEED(waitaddr)
|
SM_PROCEED(WaitAddr)
|
||||||
|
|
||||||
SM_STATE(waitaddr)
|
SM_STATE(WaitAddr)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((rc = binkp_recv_frame(rbuf, &bufl, &cmd))) {
|
if ((rc = binkp_recv_frame(rbuf, &bufl, &cmd))) {
|
||||||
@ -858,17 +893,19 @@ SM_STATE(waitaddr)
|
|||||||
if (nlent)
|
if (nlent)
|
||||||
rdoptions(Loaded);
|
rdoptions(Loaded);
|
||||||
|
|
||||||
if (MBflag) {
|
if (MBflag == TheyWant) {
|
||||||
Syslog('b', "Binkp: remote supports MB");
|
Syslog('b', "Binkp: remote supports MB");
|
||||||
binkp_send_control(MM_NUL,"OPT MB");
|
binkp_send_control(MM_NUL,"OPT MB");
|
||||||
|
MBflag = Active;
|
||||||
}
|
}
|
||||||
if (CRCflag) {
|
if (CRCflag == TheyWant) {
|
||||||
if (Loaded && nodes.CRC32 && !CFG.NoCRC32) {
|
if (Loaded && nodes.CRC32 && !CFG.NoCRC32) {
|
||||||
binkp_send_control(MM_NUL,"OPT CRC");
|
binkp_send_control(MM_NUL,"OPT CRC");
|
||||||
Syslog('+', "Binkp: using file transfers with CRC32 checking");
|
Syslog('+', "Binkp: using file transfers with CRC32 checking");
|
||||||
|
CRCflag = Active;
|
||||||
} else {
|
} else {
|
||||||
Syslog('b', "Binkp: CRC32 support is diabled here");
|
Syslog('b', "Binkp: CRC32 support is diabled here");
|
||||||
CRCflag = FALSE;
|
CRCflag = No;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -878,7 +915,7 @@ SM_STATE(waitaddr)
|
|||||||
history.aka.point = remote->addr->point;
|
history.aka.point = remote->addr->point;
|
||||||
sprintf(history.aka.domain, "%s", remote->addr->domain);
|
sprintf(history.aka.domain, "%s", remote->addr->domain);
|
||||||
|
|
||||||
SM_PROCEED(waitpwd)
|
SM_PROCEED(IsPasswd)
|
||||||
|
|
||||||
} else if (rbuf[0] == MM_ERR) {
|
} else if (rbuf[0] == MM_ERR) {
|
||||||
Syslog('!', "Binkp: M_ERR \"%s\"", printable(&rbuf[1], 0));
|
Syslog('!', "Binkp: M_ERR \"%s\"", printable(&rbuf[1], 0));
|
||||||
@ -886,11 +923,23 @@ SM_STATE(waitaddr)
|
|||||||
|
|
||||||
} else if (rbuf[0] == MM_NUL) {
|
} else if (rbuf[0] == MM_NUL) {
|
||||||
b_nul(&rbuf[1]);
|
b_nul(&rbuf[1]);
|
||||||
|
} else if (rbuf[0] <= MM_MAX) {
|
||||||
|
binkp_send_control(MM_ERR, "Unexpected frame");
|
||||||
|
SM_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SM_STATE(waitpwd)
|
SM_STATE(IsPasswd)
|
||||||
|
|
||||||
|
if (Loaded && strlen(nodes.Spasswd)) {
|
||||||
|
we_have_pwd = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Syslog('b', "We %s have a password", we_have_pwd ?"do":"don't");
|
||||||
|
SM_PROCEED(WaitPwd)
|
||||||
|
|
||||||
|
SM_STATE(WaitPwd)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((rc = binkp_recv_frame(rbuf, &bufl, &cmd))) {
|
if ((rc = binkp_recv_frame(rbuf, &bufl, &cmd))) {
|
||||||
@ -900,67 +949,71 @@ SM_STATE(waitpwd)
|
|||||||
|
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
if (rbuf[0] == MM_PWD) {
|
if (rbuf[0] == MM_PWD) {
|
||||||
SM_PROCEED(pwdack)
|
SM_PROCEED(PwdAck)
|
||||||
|
|
||||||
} else if (rbuf[0] == MM_ERR) {
|
} else if (rbuf[0] == MM_ERR) {
|
||||||
Syslog('!', "Binkp: M_ERR \"%s\"", printable(&rbuf[1], 0));
|
Syslog('!', "Binkp: M_ERR \"%s\"", printable(&rbuf[1], 0));
|
||||||
SM_ERROR;
|
SM_ERROR;
|
||||||
|
|
||||||
} else if (rbuf[0] == MM_NUL) {
|
} else if (rbuf[0] == MM_NUL) {
|
||||||
b_nul(&rbuf[1]);
|
b_nul(&rbuf[1]);
|
||||||
|
} else if (rbuf[0] <= MM_MAX) {
|
||||||
|
binkp_send_control(MM_ERR, "Unexpected frame");
|
||||||
|
SM_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SM_STATE(pwdack)
|
SM_STATE(PwdAck)
|
||||||
|
|
||||||
tmpa = remote;
|
if (we_have_pwd) {
|
||||||
if ((strncmp(&rbuf[1], "CRAM-", 5) == 0) && CRAMflag && Loaded) {
|
|
||||||
char *sp, *pw;
|
|
||||||
pw = xstrcpy(nodes.Spasswd);
|
pw = xstrcpy(nodes.Spasswd);
|
||||||
|
} else {
|
||||||
|
pw = xstrcpy((char *)"-");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((strncmp(&rbuf[1], "CRAM-", 5) == 0) && CRAMflag) {
|
||||||
|
char *sp;
|
||||||
sp = MD_buildDigest(pw, MD_challenge);
|
sp = MD_buildDigest(pw, MD_challenge);
|
||||||
free(pw);
|
|
||||||
if (sp != NULL) {
|
if (sp != NULL) {
|
||||||
if (strcmp(&rbuf[1], sp)) {
|
if (strcmp(&rbuf[1], sp)) {
|
||||||
Syslog('+', "Binkp: bad MD5 crypted password");
|
Syslog('+', "Binkp: bad MD5 crypted password");
|
||||||
binkp_send_control(MM_ERR, "*** Password error, check setup ***");
|
binkp_send_control(MM_ERR, "Bad password");
|
||||||
free(sp);
|
free(sp);
|
||||||
sp = NULL;
|
sp = NULL;
|
||||||
|
free(pw);
|
||||||
SM_ERROR;
|
SM_ERROR;
|
||||||
} else {
|
} else {
|
||||||
free(sp);
|
free(sp);
|
||||||
sp = NULL;
|
sp = NULL;
|
||||||
Syslog('+', "Binkp: MD5 password OK, protected session");
|
if (we_have_pwd)
|
||||||
inbound_open(tmpa->addr, TRUE);
|
Secure = TRUE;
|
||||||
binkp_send_control(MM_OK, "secure");
|
|
||||||
SM_SUCCESS;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
free(pw);
|
||||||
Syslog('!', "Binkp: could not build MD5 digest");
|
Syslog('!', "Binkp: could not build MD5 digest");
|
||||||
binkp_send_control(MM_ERR, "*** Internal error ***");
|
binkp_send_control(MM_ERR, "*** Internal error ***");
|
||||||
SM_ERROR;
|
SM_ERROR;
|
||||||
}
|
}
|
||||||
} else if ((strcmp(&rbuf[1], "-") == 0) && !Loaded) {
|
} else if ((strcmp(&rbuf[1], pw) == 0)) {
|
||||||
Syslog('+', "Binkp: node not in setup, unprotected session");
|
if (we_have_pwd)
|
||||||
inbound_open(tmpa->addr, FALSE);
|
Secure = TRUE;
|
||||||
binkp_send_control(MM_OK, "");
|
|
||||||
SM_SUCCESS;
|
|
||||||
} else if ((strcmp(&rbuf[1], "-") == 0) && Loaded && !strlen(nodes.Spasswd)) {
|
|
||||||
Syslog('+', "Binkp: node in setup but no session password, unprotected session");
|
|
||||||
inbound_open(tmpa->addr, FALSE);
|
|
||||||
binkp_send_control(MM_OK, "");
|
|
||||||
SM_SUCCESS;
|
|
||||||
} else if ((strcmp(&rbuf[1], nodes.Spasswd) == 0) && Loaded) {
|
|
||||||
Syslog('+', "Binkp: password OK, protected session");
|
|
||||||
inbound_open(tmpa->addr, TRUE);
|
|
||||||
binkp_send_control(MM_OK, "secure");
|
|
||||||
SM_SUCCESS;
|
|
||||||
} else {
|
} else {
|
||||||
|
free(pw);
|
||||||
Syslog('?', "Binkp: password error: expected \"%s\", got \"%s\"", nodes.Spasswd, &rbuf[1]);
|
Syslog('?', "Binkp: password error: expected \"%s\", got \"%s\"", nodes.Spasswd, &rbuf[1]);
|
||||||
binkp_send_control(MM_ERR, "*** Password error, check setup ***");
|
binkp_send_control(MM_ERR, "Bad password");
|
||||||
SM_ERROR;
|
SM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(pw);
|
||||||
|
Syslog('+', "Binkp: %s%sprotected session", CRAMflag ? "MD5 ":"", Secure ? "":"un");
|
||||||
|
inbound_open(remote->addr, Secure);
|
||||||
|
binkp_send_control(MM_OK, "%ssecure", Secure ? "":"non-");
|
||||||
|
SM_PROCEED(Opts)
|
||||||
|
|
||||||
|
SM_STATE(Opts)
|
||||||
|
|
||||||
|
SM_SUCCESS;
|
||||||
|
|
||||||
SM_END
|
SM_END
|
||||||
SM_RETURN
|
SM_RETURN
|
||||||
|
|
||||||
@ -1048,7 +1101,7 @@ int binkp_batch(file_list *to_send, int role)
|
|||||||
rname = calloc(512, sizeof(char));
|
rname = calloc(512, sizeof(char));
|
||||||
lname = calloc(512, sizeof(char));
|
lname = calloc(512, sizeof(char));
|
||||||
gname = calloc(512, sizeof(char));
|
gname = calloc(512, sizeof(char));
|
||||||
TfState = Switch;
|
// TfState = Switch;
|
||||||
RxState = RxWaitFile;
|
RxState = RxWaitFile;
|
||||||
TxState = TxGetNextFile;
|
TxState = TxGetNextFile;
|
||||||
binkp_settimer(BINKP_TIMEOUT);
|
binkp_settimer(BINKP_TIMEOUT);
|
||||||
@ -1141,7 +1194,7 @@ int binkp_batch(file_list *to_send, int role)
|
|||||||
txflock.l_start = 0L;
|
txflock.l_start = 0L;
|
||||||
txflock.l_len = 0L;
|
txflock.l_len = 0L;
|
||||||
|
|
||||||
if (CRCflag)
|
if (CRCflag == Active)
|
||||||
tcrc = file_crc(tmp->local, FALSE);
|
tcrc = file_crc(tmp->local, FALSE);
|
||||||
else
|
else
|
||||||
tcrc = 0;
|
tcrc = 0;
|
||||||
@ -1168,7 +1221,7 @@ int binkp_batch(file_list *to_send, int role)
|
|||||||
|
|
||||||
txpos = stxpos = tmp->offset;
|
txpos = stxpos = tmp->offset;
|
||||||
Syslog('+', "Binkp: send \"%s\" as \"%s\"", MBSE_SS(tmp->local), MBSE_SS(tmp->remote));
|
Syslog('+', "Binkp: send \"%s\" as \"%s\"", MBSE_SS(tmp->local), MBSE_SS(tmp->remote));
|
||||||
if (CRCflag && tcrc) {
|
if ((CRCflag == Active) && tcrc) {
|
||||||
Syslog('+', "Binkp: size %lu bytes, dated %s, crc %lx", (unsigned long)tmp->size, date(tmp->date), tcrc);
|
Syslog('+', "Binkp: size %lu bytes, dated %s, crc %lx", (unsigned long)tmp->size, date(tmp->date), tcrc);
|
||||||
binkp_send_control(MM_FILE, "%s %lu %ld %ld %lx", MBSE_SS(tmp->remote),
|
binkp_send_control(MM_FILE, "%s %lu %ld %ld %lx", MBSE_SS(tmp->remote),
|
||||||
(unsigned long)tmp->size, (long)tmp->date, (unsigned long)tmp->offset, tcrc);
|
(unsigned long)tmp->size, (long)tmp->date, (unsigned long)tmp->offset, tcrc);
|
||||||
@ -1332,7 +1385,7 @@ int binkp_batch(file_list *to_send, int role)
|
|||||||
* Check against buffer overflow
|
* Check against buffer overflow
|
||||||
*/
|
*/
|
||||||
rcrc = 0;
|
rcrc = 0;
|
||||||
if (CRCflag) {
|
if (CRCflag == Active) {
|
||||||
sscanf(rxbuf+1, "%s %ld %ld %ld %lx", rname, &rsize, &rtime, &roffs, &rcrc);
|
sscanf(rxbuf+1, "%s %ld %ld %ld %lx", rname, &rsize, &rtime, &roffs, &rcrc);
|
||||||
} else {
|
} else {
|
||||||
sscanf(rxbuf+1, "%s %ld %ld %ld", rname, &rsize, &rtime, &roffs);
|
sscanf(rxbuf+1, "%s %ld %ld %ld", rname, &rsize, &rtime, &roffs);
|
||||||
@ -1345,13 +1398,13 @@ int binkp_batch(file_list *to_send, int role)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: Syslog('+', "Binkp: Unexpected frame %d", rxbuf[0]);
|
default: Syslog('+', "Binkp: Unexpected frame %d \"%s\"", rxbuf[0], printable(rxbuf+1, 0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (blklen) {
|
if (blklen) {
|
||||||
if (RxState == RxReceData) {
|
if (RxState == RxReceData) {
|
||||||
written = fwrite(rxbuf, 1, blklen, rxfp);
|
written = fwrite(rxbuf, 1, blklen, rxfp);
|
||||||
if (CRCflag)
|
if (CRCflag == Active)
|
||||||
rxcrc = upd_crc32(rxbuf, rxcrc, blklen);
|
rxcrc = upd_crc32(rxbuf, rxcrc, blklen);
|
||||||
if (!written && blklen) {
|
if (!written && blklen) {
|
||||||
Syslog('+', "Binkp: file write error");
|
Syslog('+', "Binkp: file write error");
|
||||||
@ -1360,7 +1413,7 @@ int binkp_batch(file_list *to_send, int role)
|
|||||||
rxpos += written;
|
rxpos += written;
|
||||||
if (rxpos == rsize) {
|
if (rxpos == rsize) {
|
||||||
RxState = RxWaitFile;
|
RxState = RxWaitFile;
|
||||||
if (CRCflag && rcrc) {
|
if ((CRCflag == Active) && rcrc) {
|
||||||
rxcrc = rxcrc ^ 0xffffffff;
|
rxcrc = rxcrc ^ 0xffffffff;
|
||||||
if (rcrc == rxcrc) {
|
if (rcrc == rxcrc) {
|
||||||
binkp_send_control(MM_GOT, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
|
binkp_send_control(MM_GOT, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
|
||||||
@ -1411,7 +1464,7 @@ int binkp_batch(file_list *to_send, int role)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case RxAcceptFile:
|
case RxAcceptFile:
|
||||||
if (CRCflag)
|
if (CRCflag == Active)
|
||||||
Syslog('+', "Binkp: receive file \"%s\" date %s size %ld offset %ld crc %lx",
|
Syslog('+', "Binkp: receive file \"%s\" date %s size %ld offset %ld crc %lx",
|
||||||
rname, date(rtime), rsize, roffs, rcrc);
|
rname, date(rtime), rsize, roffs, rcrc);
|
||||||
else
|
else
|
||||||
@ -1439,7 +1492,7 @@ int binkp_batch(file_list *to_send, int role)
|
|||||||
* be deleted at the remote.
|
* be deleted at the remote.
|
||||||
*/
|
*/
|
||||||
Syslog('+', "Binkp: already got %s, sending GOT", rname);
|
Syslog('+', "Binkp: already got %s, sending GOT", rname);
|
||||||
if (CRCflag && rcrc)
|
if ((CRCflag == Active) && rcrc)
|
||||||
binkp_send_control(MM_GOT, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
|
binkp_send_control(MM_GOT, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
|
||||||
else
|
else
|
||||||
binkp_send_control(MM_GOT, "%s %ld %ld", rname, rsize, rtime);
|
binkp_send_control(MM_GOT, "%s %ld %ld", rname, rsize, rtime);
|
||||||
@ -1450,7 +1503,7 @@ int binkp_batch(file_list *to_send, int role)
|
|||||||
* Some error, request to skip it
|
* Some error, request to skip it
|
||||||
*/
|
*/
|
||||||
Syslog('+', "Binkp: error file %s, sending SKIP", rname);
|
Syslog('+', "Binkp: error file %s, sending SKIP", rname);
|
||||||
if (CRCflag && rcrc)
|
if ((CRCflag == Active) && rcrc)
|
||||||
binkp_send_control(MM_SKIP, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
|
binkp_send_control(MM_SKIP, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
|
||||||
else
|
else
|
||||||
binkp_send_control(MM_SKIP, "%s %ld %ld", rname, rsize, rtime);
|
binkp_send_control(MM_SKIP, "%s %ld %ld", rname, rsize, rtime);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef _BINKP_H
|
#ifndef _BINKP_H
|
||||||
#define _BINKP_H
|
#define _BINKP_H
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
binkp's frames:
|
binkp's frames:
|
||||||
@ -17,7 +19,8 @@
|
|||||||
|
|
||||||
|
|
||||||
/* protocol version */
|
/* protocol version */
|
||||||
#define BINKP_VERSION "1.1"
|
#define PRTCLNAME "binkp"
|
||||||
|
#define PRTCLVER "1.0"
|
||||||
|
|
||||||
#define MAX_BLKSIZE 0x7fff /* Don't change! */
|
#define MAX_BLKSIZE 0x7fff /* Don't change! */
|
||||||
#define BLK_HDR_SIZE 2 /* 2 bytes header */
|
#define BLK_HDR_SIZE 2 /* 2 bytes header */
|
||||||
@ -28,7 +31,7 @@
|
|||||||
#define MM_ADR 1 /* System aka's */
|
#define MM_ADR 1 /* System aka's */
|
||||||
#define MM_PWD 2 /* Password */
|
#define MM_PWD 2 /* Password */
|
||||||
#define MM_FILE 3
|
#define MM_FILE 3
|
||||||
#define MM_OK 4 /* The password is ok (data ignored) */
|
#define MM_OK 4 /* The password is ok */
|
||||||
#define MM_EOB 5 /* End-of-batch (data ignored) */
|
#define MM_EOB 5 /* End-of-batch (data ignored) */
|
||||||
#define MM_GOT 6 /* File received */
|
#define MM_GOT 6 /* File received */
|
||||||
#define MM_ERR 7 /* Misc errors */
|
#define MM_ERR 7 /* Misc errors */
|
||||||
@ -68,17 +71,6 @@ typedef struct _binkp_list {
|
|||||||
} binkp_list;
|
} binkp_list;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* state.NR_flag: state of binkp when in NR mode
|
|
||||||
*/
|
|
||||||
#define NO_NR 0
|
|
||||||
#define WANT_NR 1
|
|
||||||
#define WE_NR 2
|
|
||||||
#define THEY_NR 3
|
|
||||||
|
|
||||||
|
|
||||||
int binkp(int);
|
int binkp(int);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -4,45 +4,50 @@
|
|||||||
#define SM_DECL(proc,name) \
|
#define SM_DECL(proc,name) \
|
||||||
int proc(void)\
|
int proc(void)\
|
||||||
{\
|
{\
|
||||||
int sm_success=0;\
|
int sm_success=0;\
|
||||||
char *sm_name=name;
|
char *sm_name=name;
|
||||||
|
|
||||||
#define SM_STATES \
|
#define SM_STATES \
|
||||||
enum {
|
enum {
|
||||||
|
|
||||||
#define SM_NAMES \
|
#define SM_NAMES \
|
||||||
} sm_state; \
|
} sm_state; \
|
||||||
char * sm_sname[] = {
|
char * sm_sname[] = {
|
||||||
|
|
||||||
#define SM_EDECL \
|
#define SM_EDECL \
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SM_START(x) \
|
#define SM_START(x) \
|
||||||
sm_state=x;\
|
sm_state=x;\
|
||||||
Syslog('S', "Statemachine %s start %s (%d)",sm_name,sm_sname[sm_state],sm_state); \
|
Syslog('S', "SM (%s): Start => %s", sm_name, sm_sname[sm_state]); \
|
||||||
while (!sm_success) switch (sm_state)\
|
while (!sm_success) switch (sm_state)\
|
||||||
{\
|
{\
|
||||||
default: WriteError("Statemachine %s error: state=%d",sm_name,sm_state);\
|
default: WriteError("Statemachine %s error: state=%d",sm_name,sm_state);\
|
||||||
sm_success=-1;
|
sm_success=-1;
|
||||||
|
|
||||||
#define SM_STATE(x) \
|
#define SM_STATE(x) \
|
||||||
break;\
|
break;\
|
||||||
case x:
|
case x:
|
||||||
|
|
||||||
#define SM_END \
|
#define SM_END \
|
||||||
}\
|
}\
|
||||||
|
|
||||||
#define SM_RETURN \
|
#define SM_RETURN \
|
||||||
return (sm_success != 1);\
|
return (sm_success != 1);\
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SM_PROCEED(x) \
|
#define SM_PROCEED(x) \
|
||||||
sm_state=x; break;
|
if (x != sm_state) {\
|
||||||
|
Syslog('S', "SM (%s): %s => %s", sm_name, sm_sname[sm_state], sm_sname[x]);\
|
||||||
|
}\
|
||||||
|
sm_state=x; break;
|
||||||
|
|
||||||
#define SM_SUCCESS \
|
#define SM_SUCCESS \
|
||||||
sm_success=1; break;
|
Syslog('S', "SM (%s): %s => Success", sm_name, sm_sname[sm_state]);\
|
||||||
|
sm_success=1; break;
|
||||||
|
|
||||||
#define SM_ERROR \
|
#define SM_ERROR \
|
||||||
sm_success=-1; break;
|
Syslog('S', "SM (%s): %s => Error", sm_name, sm_sname[sm_state]);\
|
||||||
|
sm_success=-1; break;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user