summaryrefslogtreecommitdiff
path: root/includes/filetransfer/filetransfer.inc
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2009-08-28 07:51:55 +0000
committerDries Buytaert <dries@buytaert.net>2009-08-28 07:51:55 +0000
commitb8448cac634bdc6d1e4c618a83d8478033734b9f (patch)
tree446b1d8daaf0c2df8c2bd08e50ddb75fd91e149b /includes/filetransfer/filetransfer.inc
parent45da74801a093fe58017cd109bbb14ef0e9e4c21 (diff)
downloadbrdo-b8448cac634bdc6d1e4c618a83d8478033734b9f.tar.gz
brdo-b8448cac634bdc6d1e4c618a83d8478033734b9f.tar.bz2
- Patch #528326 by JacobSingh, cwgordon7: clean-up and bug fixes for the FTP file transfer classes.
Diffstat (limited to 'includes/filetransfer/filetransfer.inc')
-rw-r--r--includes/filetransfer/filetransfer.inc127
1 files changed, 119 insertions, 8 deletions
diff --git a/includes/filetransfer/filetransfer.inc b/includes/filetransfer/filetransfer.inc
index 2b1c18c7e..f0cf9d56a 100644
--- a/includes/filetransfer/filetransfer.inc
+++ b/includes/filetransfer/filetransfer.inc
@@ -20,11 +20,7 @@ abstract class FileTransfer {
* The constructer for the UpdateConnection class. This method is also called
* from the classes that extend this class and override this method.
*/
- function __construct($jail, $username, $password, $hostname, $port) {
- $this->username = $username;
- $this->password = $password;
- $this->hostname = $hostname;
- $this->port = $port;
+ function __construct($jail) {
$this->jail = $jail;
}
@@ -41,6 +37,11 @@ abstract class FileTransfer {
$this->connect();
return $this->connection;
}
+
+ if ($name == 'chroot') {
+ $this->setChroot();
+ return $this->chroot;
+ }
}
/**
@@ -57,17 +58,36 @@ abstract class FileTransfer {
* The destination path.
*/
public final function copyDirectory($source, $destination) {
+ $source = $this->sanitizePath($source);
+ $destination = $this->fixRemotePath($destination);
$this->checkPath($destination);
$this->copyDirectoryJailed($source, $destination);
}
/**
+ * @see http://php.net/chmod
+ *
+ * @param string $path
+ * @param long $mode
+ * @param bool $recursive
+ */
+ public final function chmod($path, $mode, $recursive = FALSE) {
+ $path = $this->sanitizePath($path);
+ $path = $this->fixRemotePath($path);
+ $this->checkPath($path);
+ $this->chmodJailed($path, $mode, $recursive);
+ }
+
+ protected abstract function chmodJailed($path, $mode, $recursive);
+
+ /**
* Creates a directory.
*
* @param $directory
* The directory to be created.
*/
public final function createDirectory($directory) {
+ $directory = $this->fixRemotePath($directory);
$this->checkPath($directory);
$this->createDirectoryJailed($directory);
}
@@ -79,6 +99,7 @@ abstract class FileTransfer {
* The directory to be removed.
*/
public final function removeDirectory($directory) {
+ $directory = $this->fixRemotePath($directory);
$this->checkPath($directory);
$this->removeDirectoryJailed($directory);
}
@@ -92,6 +113,8 @@ abstract class FileTransfer {
* The destination file.
*/
public final function copyFile($source, $destination) {
+ $source = $this->sanitizePath($source);
+ $destination = $this->fixRemotePath($destination);
$this->checkPath($destination);
$this->copyFileJailed($source, $destination);
}
@@ -103,6 +126,7 @@ abstract class FileTransfer {
* The destination file to be removed.
*/
public final function removeFile($destination) {
+ $destination = $this->fixRemotePath($destination);
$this->checkPath($destination);
$this->removeFileJailed($destination);
}
@@ -114,12 +138,51 @@ abstract class FileTransfer {
* A path to check against the jail.
*/
protected final function checkPath($path) {
- if (drupal_realpath(substr($path, 0, strlen($this->jail))) !== $this->jail) {
+ $full_jail = $this->chroot . $this->jail;
+ $full_path = drupal_realpath(substr($this->chroot . $path, 0, strlen($full_jail)));
+ $full_path = $this->fixRemotePath($full_path, FALSE);
+ if ($full_jail !== $full_path) {
throw new FileTransferException('@directory is outside of the @jail', NULL, array('@directory' => $path, '@jail' => $this->jail));
}
}
/**
+ * Returns a modified path suitable for passing to the server.
+ * If a path is a windows path, makes it posix compliant by removing the drive letter.
+ * If $this->chroot has a value, it is stripped from the path to allow for
+ * chroot'd filetransfer systems.
+ *
+ * @param $path
+ * @param $strip_chroot
+ *
+ * @return string;
+ */
+ protected final function fixRemotePath($path, $strip_chroot = TRUE) {
+ $path = $this->sanitizePath($path);
+ $path = preg_replace('|^([a-z]{1}):|i', '', $path); // Strip out windows driveletter if its there.
+ if ($strip_chroot) {
+ if ($this->chroot && strpos($path, $this->chroot) === 0) {
+ $path = ($path == $this->chroot) ? '' : substr($path, strlen($this->chroot));
+ }
+ }
+ return $path;
+ }
+
+ /**
+ * Changes backslahes to slashes, also removes a trailing slash.
+ *
+ * @param string $path
+ * @return string;
+ */
+ function sanitizePath($path) {
+ $path = str_replace('\\', '/', $path); // Windows path sanitiation.
+ if (substr($path, -1) == '/') {
+ $path = substr($path, 0, -1);
+ }
+ return $path;
+ }
+
+ /**
* Copies a directory.
*
* We need a separate method to make the $destination is in the jail.
@@ -178,7 +241,7 @@ abstract class FileTransfer {
* The destination file to be removed.
*/
abstract protected function removeFileJailed($destination);
-
+
/**
* Checks if a particular path is a directory
*
@@ -188,6 +251,54 @@ abstract class FileTransfer {
* @return boolean
*/
abstract public function isDirectory($path);
+
+ /**
+ * Checks if a particular path is a file (not a directory).
+ *
+ * @param $path
+ * The path to check
+ *
+ * @return boolean
+ */
+ abstract public function isFile($path);
+
+ /**
+ * Gets the chroot property for this connection. It does this by moving up
+ * the tree until it finds itself. If successful, it will return a chroot.
+ *
+ * @return string chroot
+ */
+ function findChroot() {
+ // If the file exists as is, there is no chroot.
+ $path = __FILE__;
+ $path = $this->fixRemotePath($path, FALSE);
+ if ($this->isFile($path)) {
+ return FALSE;
+ }
+
+ $path = dirname(__FILE__);
+ $path = $this->fixRemotePath($path, FALSE);
+ $parts = explode('/', $path);
+ $chroot = '';
+ while (count($parts)) {
+ $check = implode($parts, '/');
+ if ($this->isFile($check . '/' . basename(__FILE__))) {
+ // Remove the trailing slash.
+ return substr($chroot,0,-1);
+ }
+ $chroot .= array_shift($parts) . '/';
+ }
+ return FALSE;
+ }
+
+ /**
+ * Sets the chroot and changes the jail to match the correct path scheme
+ *
+ */
+ function setChroot() {
+ $this->chroot = $this->findChroot();
+ $this->jail = $this->fixRemotePath($this->jail);
+ }
}
/**
@@ -200,4 +311,4 @@ class FileTransferException extends Exception {
parent::__construct($message, $code);
$this->arguments = $arguments;
}
-}
+} \ No newline at end of file