Autodetect Telnet IAC modes, and if in binary mode esc 0xff chars
All checks were successful
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 37s
Create Docker Image / Build Docker Image (arm64) (push) Successful in 1m34s
Create Docker Image / Final Docker Image Manifest (push) Successful in 10s

This commit is contained in:
2025-01-30 23:18:49 +11:00
parent 52961e2403
commit b1eaec3271
3 changed files with 167 additions and 5 deletions

View File

@@ -936,6 +936,107 @@ final class EMSI extends BaseProtocol implements CRCInterface,ZmodemInterface
if (static::DEBUG)
Log::debug(sprintf('%s:- Got [%x] (%c)',self::LOGKEY,$ch,$ch));
// Look for Telnet IAC, if binary mode we'll need to handle IAC IAC => IAC
if ($ch === 0xff) {
Log::info(sprintf('%s:- TELNET IAC',self::LOGKEY));
$iaccmd = NULL;
// Peek for the next chars
do {
try {
$iac = $this->client->read(1,1,MSG_PEEK);
if (static::DEBUG)
Log::debug(sprintf('%s: - IAC LOOP',self::LOGKEY),['iac'=>ord($iac),'cmd'=>$iaccmd]);
switch (ord($iac)) {
// Binary Mode
case 0x00:
if ($iaccmd === 0xfb) {
Log::debug(sprintf('%s: - IAC WILL BINARY [%02x]',self::LOGKEY,ord($iac)));
// Config with DO
$this->client->send(chr(0xff).chr(0xfd).$iac,10);
} elseif ($iaccmd === 0xfd) {
Log::debug(sprintf('%s: - IAC DO BINARY [%02x]',self::LOGKEY,ord($iac)));
// Config with WILL
if (! $this->client->iac_bin) {
$this->client->send(chr(0xff).chr(0xfb).$iac,10);
$this->client->iac_bin = true;
}
}
$iaccmd = NULL;
break;
// Suppress Go Ahead
case 0x03:
if ($iaccmd === 0xfb) {
Log::debug(sprintf('%s: - IAC WILL SUPPRESS-GO-AHEAD [%02x]',self::LOGKEY,ord($iac)));
// Config with DO
$this->client->send(chr(0xff).chr(0xfd).$iac,10);
} elseif ($iaccmd === 0xfd) {
Log::debug(sprintf('%s: - IAC DO SUPPRESS-GO-AHEAD [%02x]',self::LOGKEY,ord($iac)));
// Config with WILL
$this->client->send(chr(0xff).chr(0xfb).$iac,10);
}
$iaccmd = NULL;
break;
// Will
case 0xfb:
if (static::DEBUG)
Log::debug(sprintf('%s: - IAC WILL [%02x]',self::LOGKEY,ord($iac)));
$iaccmd = ord($iac);
break;
// Do
case 0xfd:
if (static::DEBUG)
Log::debug(sprintf('%s: - IAC DO [%02x]',self::LOGKEY,ord($iac)));
$iaccmd = ord($iac);
break;
// IAC
case 0xff:
if (static::DEBUG)
Log::debug(sprintf('%s: - IAC [%02x]',self::LOGKEY,ord($iac)));
$iaccmd = ord($iac);
break;
default:
Log::alert(sprintf('%s: - IAC Unhandled [%02x]',self::LOGKEY,ord($iac)),['iac'=>$iac,'iaccmd'=>$iaccmd,'ch'=>ord($iac)]);
$ch = ord($iac);
$iac = NULL;
}
if ($iaccmd) {
$iac = ord($this->client->read_ch(10));
$ch = NULL;
} elseif (is_null($ch)) {
$ch = ord($this->client->read_ch(10));
}
} catch (SocketException $e) {
Log::debug(sprintf('%s:! SocketException: %s',self::LOGKEY,$e->getMessage()),['class'=>get_class($e),'code'=>$e->getCode()]);
$iac = NULL;
}
} while (! is_null($iac));
Log::debug(sprintf('%s:- Leaving IAC with [%02x]',self::LOGKEY,$ch),['ch'=>serialize($ch)]);
}
if (($ch != self::TIMEOUT) && ($ch < 0))
return $ch;

View File

@@ -1147,7 +1147,7 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
private function ls_zrecvdata32(string &$data,int &$len,int $timeout): int
{
if (static::DEBUG)
Log::debug(sprintf('%s:+ ls_zrecvdata32',self::LOGKEY),['d'=>$data]);
Log::debug(sprintf('%s:+ ls_zrecvdata32',self::LOGKEY),['d'=>$data,'len'=>$len,'timeout'=>$timeout]);
$got = 0; /* Bytes total got */
$crc = 0; /* Received CRC */
@@ -1165,6 +1165,9 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
return self::LSZ_BADCRC;
} else {
if (static::DEBUG)
Log::debug(sprintf('%s:- ls_zrecvdata32 c>32 [%x] (%c)',self::LOGKEY,$c,($c<31 ? 32 : $c)),['c'=>serialize($c)]);
switch ($c) {
case self::LSZ_CRCE:
case self::LSZ_CRCG:
@@ -1277,6 +1280,8 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
break;
case self::LSZ_BADCRC:
$this->rxbuf = '';
case self::TIMEOUT:
if ($this->ls_rxAttnStr) {
$this->client->buffer_add($this->ls_rxAttnStr);
@@ -1305,6 +1310,9 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
$needzdata = 1;
}
if (static::DEBUG)
Log::debug(sprintf('%s:- ls_zrecvfile RC [%s]',self::LOGKEY,$rc),['needzdata'=>$needzdata]);
/* We need new position -- ZDATA (and may be ZEOF) */
} else {
Log::debug(sprintf('%s:- ls_zrecvfile Want ZDATA/ZEOF at [%d]',self::LOGKEY,$rxpos));
@@ -1335,7 +1343,7 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
return self::OK;
}
Log::debug(sprintf('%s:- ls_zrecvfile ZDATA',self::LOGKEY));
Log::debug(sprintf('%s:- ls_zrecvfile ZDATA',self::LOGKEY),['newpos'=>$newpos]);
$needzdata = 0;
}
}
@@ -1928,6 +1936,9 @@ final class Zmodem extends Protocol implements CRCInterface,ZmodemInterface
$this->ls_zsendhhdr(self::ZNAK,$this->ls_storelong(0));
}
// sleep between tries
sleep(5);
} while (++$trys < 10);
Log::error(sprintf('%s:? ls_zrecvnewpos Something strange or timeout [%d]',self::LOGKEY,$rc));