Tighten TFTP read controls

Avoid hanging if no data received by setting timeout. Thanks to @dkgroot  for soulution
This commit is contained in:
steve-lad 2021-06-28 07:17:51 +02:00
parent ee419ae193
commit f882a66eb4
2 changed files with 15 additions and 20 deletions

View file

@ -973,7 +973,7 @@ function getConfigMetaData($segment) {
$sysConfiguration[$valueArray['Name']] = $valueArray; $sysConfiguration[$valueArray['Name']] = $valueArray;
if (array_key_exists($valueArray['Name'],$settingsFromDb)) { if (array_key_exists($valueArray['Name'],$settingsFromDb)) {
if (!empty($sysConfiguration[$valueArray['Name']]['DefaultValue'])) { if (!empty($sysConfiguration[$valueArray['Name']]['DefaultValue'])) {
$sql = "UPDATE sccpsettings SET systemdefault = {$valueArray['DefaultValue']} WHERE keyword like '{($valueArray['Name']}'" $sql = "UPDATE sccpsettings SET systemdefault = '{$valueArray['DefaultValue']}' WHERE keyword = '{$valueArray['Name']}'";
$results = $db->query($sql); $results = $db->query($sql);
} }
} }

View file

@ -161,13 +161,15 @@ trait helperfunctions {
return $result; return $result;
} }
function tftpReadTestFile($remoteFileName) function tftpReadTestFile($remoteFileName, $host = "127.0.0.1";)
{ {
// https://datatracker.ietf.org/doc/html/rfc1350 // https://datatracker.ietf.org/doc/html/rfc1350
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
// Set timeout so that do not hang if no data received.
socket_set_option($socket,SOL_SOCKET, SO_RCVTIMEO, array('sec'=>1, 'usec'=>0));
if ($socket) { if ($socket) {
$host = "127.0.0.1"; // TODO: Should consider remote TFT Servers in future $port = 69; // Initial TFTP port. Changed in received packet.
$port = 69;
// create the RRQ request packet // create the RRQ request packet
$packet = chr(0) . chr(1) . $remoteFileName . chr(0) . 'netascii' . chr(0); $packet = chr(0) . chr(1) . $remoteFileName . chr(0) . 'netascii' . chr(0);
@ -177,24 +179,17 @@ trait helperfunctions {
$buffer = null; $buffer = null;
$port = ""; $port = "";
$ret = ""; $ret = "";
// MSG_WAITALL is blocking but socket has timeout set to 1 sec.
$numbytes = socket_recvfrom($socket, $buffer, 84, MSG_WAITALL, $host, $port);
// fetch file content if ($numbytes < 2) {
$count = 0; // socket has timed out before data received.
while ( 0 == $numbytes = socket_recvfrom($socket, $buffer, 84, MSG_DONTWAIT, $host, $port)) { return false;
sleep(1);
$count ++;
if ($count > 5) {
break;
} }
}; // unpack the returned buffer and discard the first two bytes.
// unpack the returned buffer and discard the first two bytes
try {
$pkt = unpack("nopcode/nblockno/a*data", $buffer); $pkt = unpack("nopcode/nblockno/a*data", $buffer);
} catch (\Exception $e) {
die_freepbx("TFTP server is not responding. Check that it is running and then reload this page \n"); // send ack and close socket.
}
// send ack
$packet = chr(4) . chr($pkt["blockno"]); $packet = chr(4) . chr($pkt["blockno"]);
socket_sendto($socket, $packet, strlen($packet), MSG_EOR, $host, $port); socket_sendto($socket, $packet, strlen($packet), MSG_EOR, $host, $port);