From 36ee32b38b9cbfb04f26267cd34017c258e1a39b Mon Sep 17 00:00:00 2001 From: Savetheinternet Date: Sat, 4 Jun 2011 18:55:05 +1000 Subject: [PATCH] remote servers -- writing to another server via SSH --- inc/config.php | 3 ++- inc/functions.php | 48 ++++++++++++++++++++++++++++-------------------- inc/remote.php | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 21 deletions(-) create mode 100644 inc/remote.php diff --git a/inc/config.php b/inc/config.php index 27618944..f1fc3d65 100644 --- a/inc/config.php +++ b/inc/config.php @@ -30,7 +30,8 @@ 'wordfilters' => Array(), 'custom_capcode' => Array(), 'custom_tripcode' => Array(), - 'dnsbl' => Array() + 'dnsbl' => Array(), + 'remote' => Array() ); // Database stuff diff --git a/inc/functions.php b/inc/functions.php index 4eabcd84..895d1f2c 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -250,38 +250,46 @@ } } - function file_write($path, $data) { + function file_write($path, $data, $simple = false, $skip_purge = false) { global $config; - if(preg_match('/^scp:\/\/(.+)$/', $path, $m)) { - // Experimental: secure copy... - $file = tempnam($config['tmp'], 'tinyboard-scp'); - // Write to temp file - file_write($file, $data); - // Call `scp` (yes, this is horrible) - $command = 'scp ' . escapeshellarg($file) . ' ' . escapeshellarg($m[1]); - system($command); - // Delete temporary file - file_unlink($file); - return; + + if(preg_match('/^remote:\/\/(.+)\:(.+)$/', $path, $m)) { + if(isset($config['remote'][$m[1]])) { + require_once 'inc/remote.php'; + + $remote = new Remote($config['remote'][$m[1]]); + $remote->write($data, $m[2]); + return; + } else { + error('Invalid remote server: ' . $m[1]); + } } - if(!$fp = fopen($path, 'c')) + if(!$fp = fopen($path, $simple ? 'w' : 'c')) error('Unable to open file for writing: ' . $path); // File locking - if(!flock($fp, LOCK_EX)) { + if(!$simple && !flock($fp, LOCK_EX)) { error('Unable to lock file: ' . $path); } // Truncate file - ftruncate($fp, 0); + if(!$simple && !ftruncate($fp, 0)) + error('Unable to truncate file: ' . $path); + // Write data - fwrite($fp, $data); - flock($fp, LOCK_UN); - - fclose($fp); + if(fwrite($fp, $data) === false) + error('Unable to write to file: ' . $path); - if(isset($config['purge']) && isset($_SERVER['HTTP_HOST'])) { + // Unlock + if(!$simple) + flock($fp, LOCK_UN); + + // Close + if(!fclose($fp)) + error('Unable to close file: ' . $path); + + if(!$skip_purge && isset($config['purge']) && isset($_SERVER['HTTP_HOST'])) { // Purge cache if(basename($path) == $config['file_index']) { // Index file (/index.html); purge "/" as well diff --git a/inc/remote.php b/inc/remote.php new file mode 100644 index 00000000..a4c9e68a --- /dev/null +++ b/inc/remote.php @@ -0,0 +1,47 @@ + $value) { + $this->{$name} = $value; + } + + $methods = Array(); + + if(!isset($this->auth['method'])) + error('Unspecified authentication method.'); + + // Connect + $this->connection = ssh2_connect($this->host, isset($this->port) ? $this->port : 22, $methods); + + switch($this->auth['method']) { + case 'plain': + if(!ssh2_auth_password($this->connection, $this->auth['username'], $this->auth['password'])) + error('Plain-text authentication failed.'); + break; + default: + error('Unknown authentication method.'); + } + + } + + public function write($data, $remote_path) { + global $config; + + switch($this->type) { + case 'sftp': + $sftp = ssh2_sftp($this->connection); + file_write('ssh2.sftp://' . $sftp . $remote_path, $data, true); + break; + case 'scp': + $file = tempnam($config['tmp'], 'tinyboard-scp'); + // Write to temp file + file_write($file, $data); + + ssh2_scp_send($this->connection, $file, $remote_path, 0755); + break; + default: + error('Unknown send method.'); + } + } + }; +?> \ No newline at end of file