function tftpd_authorize_config($s, $sock, $path, $file, &$db) { /* Sanitize path and filename */ $path = preg_replace('/^\\$(.*)\\$$/', '$1', $path); $pass = mysql_real_escape_string($path); $file = mysql_real_escape_string($file); /* Authorize access access * Note that the $db object will keep the query result for use later in * the script. In particular we will retrieve 'device' later. */ /* Check for filename first */ $sql = "SELECT id,filename,password FROM devices WHERE filename='{$file}'"; tftpd_log('25', 'sql query string: "' . $sql . '"'); if ($db->query($sql) != 1) { tftpd_send_nak($s, $sock, TFTP_ENOTFOUND, 'config not found'); return false; } /* Check for filename password match next */ $sql = "SELECT id,filename,password FROM devices WHERE filename='{$file}' AND password='******'"; tftpd_log('25', 'sql query string: "' . $sql . '"'); if ($db->query($sql) != 1) { tftpd_send_nak($s, $sock, TFTP_EACCESS, 'config not found'); return false; } return true; }
function tftpd_connect($sock, $r_buf) { /* Create child socket to communicate with peer */ $c_sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); if (!$c_sock) { tftpd_log('0', 'could not create child socket'); return; } $r = socket_bind($c_sock, $sock['c_addr']); if (!$r) { tftpd_log('0', 'could not bind child socket'); return; } socket_getsockname($c_sock, $sock['c_addr'], $sock['c_port']); tftpd_log('11', 'listen: ' . $sock['c_addr'] . ':' . $sock['c_port']); /* Parse the request */ if (!tftpd_recv_request($r_buf, $opcode, $request, $mode)) { tftpd_log('1', 'disconnect: invalid request'); socket_close($c_sock); return; } tftpd_log('11', 'request: "' . $request . '", mode: "' . $mode . '"'); /* Check mode */ if (strcasecmp($mode, 'netascii') != 0 && strcasecmp($mode, 'binary') != 0 && strcasecmp($mode, 'octet') != 0) { tftpd_send_nak($c_sock, $sock, TFTP_EBADOP, 'unknown mode'); socket_close($c_sock); return; } /* Sanitize request */ tftpd_sanitize_request($request, $path, $file); /* Handle config requests as indicated by a path delimited with $. * Example: $password$ */ if (preg_match('/^\\$.+\\$$/', $path)) { tftpd_handle_config($c_sock, $sock, $opcode, $mode, $path, $file); } else { tftpd_handle_file($c_sock, $sock, $opcode, $mode, $path, $file); } socket_close($c_sock); }
function tftpd_recv_file($s, $sock, $fp) { $block = 0; $xfer_byte = 0; $xfer_time = tftpd_microtime(); do { if (!tftpd_receive_data($s, $sock, $block, $data)) { return false; } $r = fwrite($fp, $data); if ($r != strlen($data)) { tftpd_send_nak($c_sock, $sock, TFTP_ENOSPACE, 'disk full?'); return false; } $block++; if ($block > 65535) { $block = 0; } $xfer_byte += strlen($data); } while (strlen($data) == 512); /* Be a good citizen and churn out one last ACK */ $s_buf = pack('nn', TFTP_ACK, $block); tftpd_send_packet($s, $sock, $s_buf); /* Log our success */ $xfer_time = round(tftpd_microtime() - $xfer_time, 3); tftpd_log('1', 'received ' . $xfer_byte . ' bytes in ' . $xfer_time . ' seconds'); }