Fixes for CRYPT, NOREL and MULTIBATCH when responding in server mode

This commit is contained in:
Deon George 2023-07-12 23:34:01 +10:00
parent b37c6407fb
commit 28101237e8
1 changed files with 39 additions and 33 deletions

View File

@ -217,8 +217,10 @@ final class Binkp extends BaseProtocol
Log::debug(sprintf('%s:+ BINKP handshake complete',self::LOGKEY));
// If the remote doesnt provide a password, or in MD5 mode, then we cant use CRYPT
if (! $this->optionGet(self::O_PWD) || (! $this->capGet(self::F_MD,self::O_WE)))
if (! $this->optionGet(self::O_PWD) && (! $this->capGet(self::F_MD,self::O_WE))) {
Log::notice(sprintf('%s:= CRYPT disabled, since we have no password or not MD5',self::LOGKEY));
$this->capSet(self::F_CRYPT,self::O_NO);
}
if ($this->capGet(self::F_CRYPT,self::O_WE)) {
$this->capSet(self::F_CRYPT,self::O_YES);
@ -252,9 +254,12 @@ final class Binkp extends BaseProtocol
$this->capSet(self::F_NOREL,self::O_YES);
}
$this->capSet(self::F_MULTIBATCH,(($this->node->get_versionint() > 100) || $this->capGet(self::F_MULTIBATCH,self::O_WE)) ? self::O_YES : self::O_NO);
if ((($this->node->get_versionint() > 100) && $this->capGet(self::F_MULTIBATCH,self::O_WANT)) || $this->capGet(self::F_MULTIBATCH,self::O_WE)) {
Log::debug(sprintf('%s:/ MB mode enabled, because we agree to MB mode, or I want MB and the remote is version [%d]',self::LOGKEY,$this->node->get_versionint()));
$this->capSet(self::F_MULTIBATCH,self::O_YES);
}
if ($this->node->get_versionint() > 100)
if (($this->node->get_versionint() > 100) && (! $this->capGet(self::F_MULTIBATCH,self::O_YES)))
$this->sessionClear(self::SE_DELAYEOB);
$this->mib = 0;
@ -264,12 +269,12 @@ final class Binkp extends BaseProtocol
self::LOGKEY,
$this->node->ver_major,
$this->node->ver_minor,
$this->capGet(self::F_NOREL,self::O_WE),
$this->capGet(self::F_NOREL,self::O_YES),
$this->capGet(self::F_NODUPE,self::O_WE),
$this->capGet(self::F_NODUPEA,self::O_WE),
$this->capGet(self::F_MD,self::O_WE),
$this->capGet(self::F_MULTIBATCH,self::O_WE),
$this->capGet(self::F_CRYPT,self::O_WE),
$this->capGet(self::F_MULTIBATCH,self::O_YES),
$this->capGet(self::F_CRYPT,self::O_YES),
$this->capGet(self::F_COMP,self::O_WE),
$this->capGet(self::F_CHAT,self::O_WE),
));
@ -374,7 +379,13 @@ final class Binkp extends BaseProtocol
return FALSE;
}
$this->rx_buf .= ($this->capGet(self::F_CRYPT,self::O_YES)) ? $this->crypt_in->decrypt($rx_buf) : $rx_buf;
if ($this->capGet(self::F_CRYPT,self::O_YES)) {
Log::debug(sprintf('%s:%% Decrypting data from remote.',self::LOGKEY));
$this->rx_buf .= $this->crypt_in->decrypt($rx_buf);
} else {
$this->rx_buf .= $rx_buf;
}
}
Log::debug(sprintf('%s:- Read buffer has [%d] chars to process.',self::LOGKEY,strlen($this->rx_buf)));
@ -797,7 +808,7 @@ final class Binkp extends BaseProtocol
$this->sessionSet(self::SE_RECVEOB);
$this->sessionClear(self::SE_DELAYEOB);
if (! $this->send->total_count && $this->sessionGet(self::SE_NOFILES) && $this->capGet(self::F_MULTIBATCH,self::O_WE)) {
if (! $this->send->total_count && $this->sessionGet(self::SE_NOFILES) && $this->capGet(self::F_MULTIBATCH,self::O_YES)) {
// Add our mail to the queue if we have authenticated
if ($this->node->aka_authed)
foreach ($this->node->aka_remote_authed as $ao) {
@ -897,13 +908,14 @@ final class Binkp extends BaseProtocol
case self::FOP_OK:
Log::debug(sprintf('%s:- Getting file from offset [%ld]',self::LOGKEY,$file['offs']));
if (((int)$file['offs'] === -1) && (! $this->capGet(self::F_NOREL,self::O_THEY))) {
if (((int)$file['offs'] === -1) && $this->capGet(self::F_NOREL,self::O_WANT)) {
Log::debug(sprintf('%s:- Assuming the remote wants NR mode, since offset is [%d] and they didnt specify an OPT with it',self::LOGKEY,$file['offs']));
$this->capSet(self::F_NOREL,self::O_THEY);
$this->capSet(self::F_NOREL,self::O_YES);
}
if ($this->capGet(self::F_NOREL,self::O_YES))
$this->msgs(self::BPM_GET,sprintf('%s %ld',$this->recv->name_size_time,($file['offs'] < 0) ? 0 : $file['offs']));
break;
}
@ -967,7 +979,7 @@ final class Binkp extends BaseProtocol
*/
private function M_gotskip(string $buf): bool
{
Log::debug(sprintf('%s:+ M_gotskip [%s]',self::LOGKEY,$buf));
Log::debug(sprintf('%s:+ Remote confirms receipt for file [%s]',self::LOGKEY,$buf));
if ($file = $this->file_parse($buf)) {
if ($this->send->sendas
@ -975,22 +987,13 @@ final class Binkp extends BaseProtocol
&& $this->send->mtime === Arr::get($file,'file.mtime')
&& $this->send->size === Arr::get($file,'file.size'))
{
// @todo Commit our mail transaction if the remote end confirmed receipt of the file.
if ($this->sessionGet(self::SE_SENDFILE)) {
Log::info(sprintf('%s:= Packet/File [%s] sent.',self::LOGKEY,$this->send->name));
$this->sessionClear(self::SE_SENDFILE);
$this->send->close(TRUE);
return TRUE;
}
if ($this->sessionGet(self::SE_WAITGOT)) {
Log::info(sprintf('%s:= Packet/File [%s] sent.',self::LOGKEY,$this->send->name));
$this->sessionClear(self::SE_WAITGOT);
$this->send->close(TRUE);
if ((! $this->sessionGet(self::SE_SENDFILE)) && (! $this->sessionGet(self::SE_WAITGOT))) {
Log::error(sprintf('%s:! M_got[skip] for unknown file [%s]',self::LOGKEY,$buf));
} else {
Log::error(sprintf('%s:! M_got[skip] for unknown file [%s]',self::LOGKEY,$buf));
Log::info(sprintf('%s:= Packet/File [%s] sent.',self::LOGKEY,$this->send->name));
$this->sessionClear(self::SE_WAITGOT|self::SE_SENDFILE);
$this->send->close(TRUE);
}
}
@ -1298,9 +1301,6 @@ final class Binkp extends BaseProtocol
$this->binkp_hs();
while (TRUE) {
if ($this->DEBUG)
Log::debug(sprintf('%s: - protocol_session LOOP',self::LOGKEY));
if ((! $this->sessionGet(self::SE_INIT))
&& (! $this->sessionGet(self::SE_SENDFILE))
&& (! $this->sessionGet(self::SE_SENTEOB))
@ -1308,8 +1308,10 @@ final class Binkp extends BaseProtocol
&& (! $this->send->fd))
{
// Open our next file to send
if ($this->send->total_count && ! $this->send->fd)
if ($this->send->total_count && ! $this->send->fd) {
Log::info(sprintf('%s:- Opening next file to send',self::LOGKEY));
$this->send->open();
}
// We have an open file descriptor, set our mode to send
if ($this->send->fd) {
@ -1334,6 +1336,7 @@ final class Binkp extends BaseProtocol
// We dont have anything to send
} else {
Log::info(sprintf('%s:- Nothing else to send',self::LOGKEY));
$this->sessionSet(self::SE_NOFILES);
}
}
@ -1344,6 +1347,7 @@ final class Binkp extends BaseProtocol
&& (! $this->sessionGet(self::SE_DELAYEOB))
&& $this->sessionGet(self::SE_NOFILES))
{
Log::info(sprintf('%s:- Sending EOB',self::LOGKEY));
$this->msgs(self::BPM_EOB,'');
$this->sessionSet(self::SE_SENTEOB);
}
@ -1351,10 +1355,14 @@ final class Binkp extends BaseProtocol
$this->rc = self::S_OK;
if ($this->sessionGet(self::SE_SENTEOB) && $this->sessionGet(self::SE_RECVEOB)) {
Log::info(sprintf('%s:- EOBs sent and received',self::LOGKEY),['m'=>$this->mib,'remote_version'=>$this->node->get_versionint()]);
if ($this->mib < 3 || $this->node->get_versionint() <= 100) {
break;
}
Log::info(sprintf('%s:- EOBs sent and received CLEARED',self::LOGKEY));
$this->mib = 0;
$this->sessionClear(self::SE_RECVEOB|self::SE_SENTEOB);
}
@ -1363,14 +1371,12 @@ final class Binkp extends BaseProtocol
$rd = TRUE;
try {
if ($this->DEBUG)
Log::debug(sprintf('%s: - Checking if there more data (ttySelect), timeout [%d]',self::LOGKEY,self::TIMEOUT_TIME));
Log::debug(sprintf('%s:- Checking if there more data (ttySelect), timeout [%d]',self::LOGKEY,self::TIMEOUT_TIME));
// @todo we need to catch a timeout if there are no reads/writes
$rc = $this->client->ttySelect($rd,$wd,self::TIMEOUT_TIME);
if ($this->DEBUG)
Log::debug(sprintf('%s: - ttySelect returned [%d]',self::LOGKEY,$rc));
Log::debug(sprintf('%s:- ttySelect returned [%d]',self::LOGKEY,$rc));
} catch (\Exception) {
$this->error_close();