diff options
author | Robin Appelman <icewind@owncloud.com> | 2015-08-17 16:31:29 +0200 |
---|---|---|
committer | Robin Appelman <icewind@owncloud.com> | 2015-08-17 16:31:29 +0200 |
commit | 5514a133ded9801f72e9767d8d57ff2fc9ae0065 (patch) | |
tree | 1189474b625091d8e41e83dbf73fdf34b2867074 /apps/files_external/3rdparty/icewind | |
parent | e76fc1cf383e2cde4b32cf9cf51b5f68ef30d7ec (diff) | |
download | nextcloud-server-5514a133ded9801f72e9767d8d57ff2fc9ae0065.tar.gz nextcloud-server-5514a133ded9801f72e9767d8d57ff2fc9ae0065.zip |
update icewind/smb to 1.0.4
Diffstat (limited to 'apps/files_external/3rdparty/icewind')
8 files changed, 86 insertions, 30 deletions
diff --git a/apps/files_external/3rdparty/icewind/smb/src/AbstractShare.php b/apps/files_external/3rdparty/icewind/smb/src/AbstractShare.php new file mode 100644 index 00000000000..a5cfe59a3c4 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/AbstractShare.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\SMB; + +use Icewind\SMB\Exception\InvalidPathException; + +abstract class AbstractShare implements IShare { + private $forbiddenCharacters; + + public function __construct() { + $this->forbiddenCharacters = array('?', '<', '>', ':', '*', '|', '"', chr(0), "\n", "\r"); + } + + protected function verifyPath($path) { + foreach ($this->forbiddenCharacters as $char) { + if (strpos($path, $char) !== false) { + throw new InvalidPathException('Invalid path, "' . $char . '" is not allowed'); + } + } + } +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Connection.php b/apps/files_external/3rdparty/icewind/smb/src/Connection.php index 6191b11ac8e..c857398c327 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Connection.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Connection.php @@ -8,8 +8,10 @@ namespace Icewind\SMB; use Icewind\SMB\Exception\AuthenticationException; +use Icewind\SMB\Exception\ConnectException; use Icewind\SMB\Exception\ConnectionException; use Icewind\SMB\Exception\InvalidHostException; +use Icewind\SMB\Exception\NoLoginServerException; class Connection extends RawConnection { const DELIMITER = 'smb:'; @@ -26,18 +28,25 @@ class Connection extends RawConnection { /** * get all unprocessed output from smbclient until the next prompt * - * @throws ConnectionException * @return string + * @throws AuthenticationException + * @throws ConnectException + * @throws ConnectionException + * @throws InvalidHostException + * @throws NoLoginServerException */ public function read() { if (!$this->isValid()) { - throw new ConnectionException(); + throw new ConnectionException('Connection not valid'); } $line = $this->readLine(); //first line is prompt $this->checkConnectionError($line); $output = array(); $line = $this->readLine(); + if ($line === false) { + throw new ConnectException('Unknown error'); + } $length = mb_strlen(self::DELIMITER); while (mb_substr($line, 0, $length) !== self::DELIMITER) { //next prompt functions as delimiter $output[] .= $line; @@ -52,20 +61,24 @@ class Connection extends RawConnection { * @param $line * @throws AuthenticationException * @throws InvalidHostException + * @throws NoLoginServerException */ private function checkConnectionError($line) { $line = rtrim($line, ')'); if (substr($line, -23) === ErrorCodes::LogonFailure) { - throw new AuthenticationException(); + throw new AuthenticationException('Invalid login'); } if (substr($line, -26) === ErrorCodes::BadHostName) { - throw new InvalidHostException(); + throw new InvalidHostException('Invalid hostname'); } if (substr($line, -22) === ErrorCodes::Unsuccessful) { - throw new InvalidHostException(); + throw new InvalidHostException('Connection unsuccessful'); } if (substr($line, -28) === ErrorCodes::ConnectionRefused) { - throw new InvalidHostException(); + throw new InvalidHostException('Connection refused'); + } + if (substr($line, -26) === ErrorCodes::NoLogonServers) { + throw new NoLoginServerException('No login server'); } } diff --git a/apps/files_external/3rdparty/icewind/smb/src/ErrorCodes.php b/apps/files_external/3rdparty/icewind/smb/src/ErrorCodes.php index d9f2507cba9..03bd574c185 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/ErrorCodes.php +++ b/apps/files_external/3rdparty/icewind/smb/src/ErrorCodes.php @@ -15,6 +15,7 @@ class ErrorCodes { const BadHostName = 'NT_STATUS_BAD_NETWORK_NAME'; const Unsuccessful = 'NT_STATUS_UNSUCCESSFUL'; const ConnectionRefused = 'NT_STATUS_CONNECTION_REFUSED'; + const NoLogonServers = 'NT_STATUS_NO_LOGON_SERVERS'; const PathNotFound = 'NT_STATUS_OBJECT_PATH_NOT_FOUND'; const NoSuchFile = 'NT_STATUS_NO_SUCH_FILE'; diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidPathException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidPathException.php new file mode 100644 index 00000000000..4bba74f269f --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidPathException.php @@ -0,0 +1,10 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\SMB\Exception; + +class InvalidPathException extends InvalidRequestException {} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/NoLoginServerException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/NoLoginServerException.php new file mode 100644 index 00000000000..43f7f9aeff9 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/NoLoginServerException.php @@ -0,0 +1,10 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\SMB\Exception; + +class NoLoginServerException extends ConnectException {} diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php b/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php index ecef8c744c2..1f1d225c00a 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php +++ b/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php @@ -7,7 +7,7 @@ namespace Icewind\SMB; -class NativeShare implements IShare { +class NativeShare extends AbstractShare { /** * @var Server $server */ @@ -28,6 +28,7 @@ class NativeShare implements IShare { * @param string $name */ public function __construct($server, $name) { + parent::__construct(); $this->server = $server; $this->name = $name; $this->state = new NativeState(); @@ -56,6 +57,7 @@ class NativeShare implements IShare { } private function buildUrl($path) { + $this->verifyPath($path); $url = sprintf('smb://%s/%s', $this->server->getHost(), $this->name); if ($path) { $path = trim($path, '/'); diff --git a/apps/files_external/3rdparty/icewind/smb/src/Server.php b/apps/files_external/3rdparty/icewind/smb/src/Server.php index 5c07d1c517d..bbc0475d5e4 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Server.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Server.php @@ -68,7 +68,7 @@ class Server { } elseif (strpos($user, '\\')) { return explode('\\', $user); } else { - return [null, $user]; + return array(null, $user); } } diff --git a/apps/files_external/3rdparty/icewind/smb/src/Share.php b/apps/files_external/3rdparty/icewind/smb/src/Share.php index 8657e698af3..d9ab729025d 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Share.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Share.php @@ -7,17 +7,13 @@ namespace Icewind\SMB; -use Icewind\SMB\Exception\AccessDeniedException; -use Icewind\SMB\Exception\AlreadyExistsException; use Icewind\SMB\Exception\ConnectionException; -use Icewind\SMB\Exception\Exception; use Icewind\SMB\Exception\FileInUseException; use Icewind\SMB\Exception\InvalidTypeException; -use Icewind\SMB\Exception\NotEmptyException; use Icewind\SMB\Exception\NotFoundException; use Icewind\Streams\CallbackWrapper; -class Share implements IShare { +class Share extends AbstractShare { /** * @var Server $server */ @@ -43,6 +39,7 @@ class Share implements IShare { * @param string $name */ public function __construct($server, $name) { + parent::__construct(); $this->server = $server; $this->name = $name; $this->parser = new Parser(new TimeZoneProvider($this->server->getHost())); @@ -58,11 +55,10 @@ class Share implements IShare { return; } $workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : ''; - $command = sprintf('%s %s --authentication-file=/proc/self/fd/3 //%s/%s', + $command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s', Server::CLIENT, $workgroupArgument, - $this->server->getHost(), - $this->name + escapeshellarg('//' . $this->server->getHost() . '/' . $this->name) ); $this->connection = new Connection($command); $this->connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); @@ -258,20 +254,18 @@ class Share implements IShare { */ public function read($source) { $source = $this->escapePath($source); - // close the single quote, open a double quote where we put the single quote... - $source = str_replace('\'', '\'"\'"\'', $source); // since returned stream is closed by the caller we need to create a new instance // since we can't re-use the same file descriptor over multiple calls $workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : ''; - $command = sprintf('%s %s --authentication-file=/proc/self/fd/3 //%s/%s -c \'get %s /proc/self/fd/5\'', + $command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s', Server::CLIENT, $workgroupArgument, - $this->server->getHost(), - $this->name, - $source + escapeshellarg('//' . $this->server->getHost() . '/' . $this->name) ); $connection = new Connection($command); $connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); + $connection->write('get ' . $source . ' /proc/self/fd/5'); + $connection->write('exit'); $fh = $connection->getFileOutputStream(); stream_context_set_option($fh, 'file', 'connection', $connection); return $fh; @@ -288,25 +282,24 @@ class Share implements IShare { */ public function write($target) { $target = $this->escapePath($target); - // close the single quote, open a double quote where we put the single quote... - $target = str_replace('\'', '\'"\'"\'', $target); // since returned stream is closed by the caller we need to create a new instance // since we can't re-use the same file descriptor over multiple calls $workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : ''; - $command = sprintf('%s %s --authentication-file=/proc/self/fd/3 //%s/%s -c \'put /proc/self/fd/4 %s\'', + $command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s', Server::CLIENT, $workgroupArgument, - $this->server->getHost(), - $this->name, - $target + escapeshellarg('//' . $this->server->getHost() . '/' . $this->name) ); - $connection = new RawConnection($command); + $connection = new Connection($command); $connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); $fh = $connection->getFileInputStream(); + $connection->write('put /proc/self/fd/4 ' . $target); + $connection->write('exit'); + // use a close callback to ensure the upload is finished before continuing // this also serves as a way to keep the connection in scope - return CallbackWrapper::wrap($fh, null, null, function () use ($connection) { + return CallbackWrapper::wrap($fh, null, null, function () use ($connection, $target) { $connection->close(false); // dont terminate, give the upload some time }); } @@ -384,6 +377,7 @@ class Share implements IShare { * @return string */ protected function escapePath($path) { + $this->verifyPath($path); if ($path === '/') { $path = ''; } |