From 28101237e87b920c3b848f366c0532b12bc26146 Mon Sep 17 00:00:00 2001 From: Deon George Date: Wed, 12 Jul 2023 23:34:01 +1000 Subject: [PATCH] Fixes for CRYPT, NOREL and MULTIBATCH when responding in server mode --- app/Classes/Protocol/Binkp.php | 72 ++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/app/Classes/Protocol/Binkp.php b/app/Classes/Protocol/Binkp.php index 0dd1ac1..fa48227 100644 --- a/app/Classes/Protocol/Binkp.php +++ b/app/Classes/Protocol/Binkp.php @@ -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();