mirror of
https://codeberg.org/icewind/SMB.git
synced 2026-06-03 17:24:07 +02:00
allow setting protocol levels
This commit is contained in:
parent
b69c20d21a
commit
61012e6196
9 changed files with 149 additions and 60 deletions
11
README.md
11
README.md
|
|
@ -125,6 +125,17 @@ $options->setTimeout(5);
|
|||
$serverFactory = new ServerFactory($options);
|
||||
```
|
||||
|
||||
### Setting protocol version
|
||||
|
||||
```php
|
||||
$options = new Options();
|
||||
$options->setMinProtocol(IOptions::PROTOCOL_SMB2);
|
||||
$options->setMaxProtocol(IOptions::PROTOCOL_SMB3);
|
||||
$serverFactory = new ServerFactory($options);
|
||||
```
|
||||
|
||||
Note, setting the protocol version is not supported with php-smbclient version 1.0.1 or lower.
|
||||
|
||||
### Customizing system integration
|
||||
|
||||
The `smbclient` backend needs to get various information about the system it's running on to function
|
||||
|
|
|
|||
|
|
@ -22,8 +22,20 @@
|
|||
namespace Icewind\SMB;
|
||||
|
||||
interface IOptions {
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTimeout();
|
||||
const PROTOCOL_NT1 = 'NT1';
|
||||
const PROTOCOL_SMB2 = 'SMB2';
|
||||
const PROTOCOL_SMB2_02 = 'SMB2_02';
|
||||
const PROTOCOL_SMB2_22 = 'SMB2_22';
|
||||
const PROTOCOL_SMB2_24 = 'SMB2_24';
|
||||
const PROTOCOL_SMB3 = 'SMB3';
|
||||
const PROTOCOL_SMB3_00 = 'SMB3_00';
|
||||
const PROTOCOL_SMB3_02 = 'SMB3_02';
|
||||
const PROTOCOL_SMB3_10 = 'SMB3_10';
|
||||
const PROTOCOL_SMB3_11 = 'SMB3_11';
|
||||
|
||||
public function getTimeout(): int;
|
||||
|
||||
public function getMinProtocol(): ?string;
|
||||
|
||||
public function getMaxProtocol(): ?string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,6 +91,14 @@ class NativeState {
|
|||
$this->state = smbclient_state_new();
|
||||
smbclient_option_set($this->state, SMBCLIENT_OPT_AUTO_ANONYMOUS_LOGIN, false);
|
||||
smbclient_option_set($this->state, SMBCLIENT_OPT_TIMEOUT, $options->getTimeout() * 1000);
|
||||
|
||||
if (function_exists('smbclient_client_protocols')) {
|
||||
$maxProtocol = $options->getMaxProtocol();
|
||||
$minProtocol = $options->getMinProtocol();
|
||||
|
||||
smbclient_client_protocols($this->state, $minProtocol, $maxProtocol);
|
||||
}
|
||||
|
||||
$auth->setExtraSmbClientOptions($this->state);
|
||||
$result = @smbclient_state_init($this->state, $auth->getWorkgroup(), $auth->getUsername(), $auth->getPassword());
|
||||
|
||||
|
|
|
|||
|
|
@ -25,11 +25,32 @@ class Options implements IOptions {
|
|||
/** @var int */
|
||||
private $timeout = 20;
|
||||
|
||||
public function getTimeout() {
|
||||
/** @var string|null */
|
||||
private $minProtocol;
|
||||
/** @var string|null */
|
||||
private $maxProtocol;
|
||||
|
||||
public function getTimeout(): int {
|
||||
return $this->timeout;
|
||||
}
|
||||
|
||||
public function setTimeout($timeout) {
|
||||
public function setTimeout(int $timeout) {
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
public function getMinProtocol(): ?string {
|
||||
return $this->minProtocol;
|
||||
}
|
||||
|
||||
public function setMinProtocol(?string $minProtocol): void {
|
||||
$this->minProtocol = $minProtocol;
|
||||
}
|
||||
|
||||
public function getMaxProtocol(): ?string {
|
||||
return $this->maxProtocol;
|
||||
}
|
||||
|
||||
public function setMaxProtocol(?string $maxProtocol): void {
|
||||
$this->maxProtocol = $maxProtocol;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 Robin Appelman <robin@icewind.nl>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Icewind\SMB;
|
||||
|
||||
|
||||
class ProtocolLevel {
|
||||
/** @var string */
|
||||
private $level;
|
||||
|
||||
private function __construct(string $level) {
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
public function getLevel(): string {
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
public static function NT1(): self {
|
||||
return new ProtocolLevel("NT1");
|
||||
}
|
||||
|
||||
public static function SMB2(): self {
|
||||
return new ProtocolLevel("SMB2");
|
||||
}
|
||||
|
||||
public static function SMB3(): self {
|
||||
return new ProtocolLevel("SMB3");
|
||||
}
|
||||
}
|
||||
|
|
@ -43,11 +43,15 @@ class Server extends AbstractServer {
|
|||
* @throws ConnectException
|
||||
*/
|
||||
public function listShares() {
|
||||
$maxProtocol = $this->options->getMaxProtocol();
|
||||
$minProtocol = $this->options->getMinProtocol();
|
||||
$command = sprintf(
|
||||
'%s %s %s -L %s',
|
||||
'%s %s %s %s %s -L %s',
|
||||
$this->system->getSmbclientPath(),
|
||||
$this->getAuthFileArgument(),
|
||||
$this->getAuth()->getExtraCommandLineArguments(),
|
||||
$maxProtocol ? "--option='client max protocol=" . $maxProtocol . "'" : "",
|
||||
$minProtocol ? "--option='client min protocol=" . $minProtocol . "'" : "",
|
||||
escapeshellarg('//' . $this->getHost())
|
||||
);
|
||||
$connection = new RawConnection($command);
|
||||
|
|
|
|||
|
|
@ -80,14 +80,18 @@ class Share extends AbstractShare {
|
|||
}
|
||||
|
||||
protected function getConnection() {
|
||||
$maxProtocol = $this->server->getOptions()->getMaxProtocol();
|
||||
$minProtocol = $this->server->getOptions()->getMinProtocol();
|
||||
$command = sprintf(
|
||||
'%s %s%s -t %s %s %s %s',
|
||||
'%s %s%s -t %s %s %s %s %s %s',
|
||||
self::EXEC_CMD,
|
||||
$this->system->getStdBufPath() ? $this->system->getStdBufPath() . ' -o0 ' : '',
|
||||
$this->system->getSmbclientPath(),
|
||||
$this->server->getOptions()->getTimeout(),
|
||||
$this->getAuthFileArgument(),
|
||||
$this->server->getAuth()->getExtraCommandLineArguments(),
|
||||
$maxProtocol ? "--option='client max protocol=" . $maxProtocol . "'" : "",
|
||||
$minProtocol ? "--option='client min protocol=" . $minProtocol . "'" : "",
|
||||
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
|
||||
);
|
||||
$connection = new Connection($command, $this->parser);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
namespace Icewind\SMB\Test;
|
||||
|
||||
use Icewind\SMB\BasicAuth;
|
||||
use Icewind\SMB\Exception\InvalidArgumentException;
|
||||
use Icewind\SMB\IOptions;
|
||||
use Icewind\SMB\Native\NativeServer;
|
||||
use Icewind\SMB\Options;
|
||||
use Icewind\SMB\System;
|
||||
|
|
@ -20,6 +22,9 @@ class NativeShareTest extends AbstractShareTest {
|
|||
$this->markTestSkipped('libsmbclient php extension not installed');
|
||||
}
|
||||
$this->config = json_decode(file_get_contents(__DIR__ . '/config.json'));
|
||||
$options = new Options();
|
||||
$options->setMinProtocol(IOptions::PROTOCOL_SMB2);
|
||||
$options->setMaxProtocol(IOptions::PROTOCOL_SMB3);
|
||||
$this->server = new NativeServer(
|
||||
$this->config->host,
|
||||
new BasicAuth(
|
||||
|
|
@ -29,7 +34,7 @@ class NativeShareTest extends AbstractShareTest {
|
|||
),
|
||||
new System(),
|
||||
new TimeZoneProvider(new System()),
|
||||
new Options()
|
||||
$options
|
||||
);
|
||||
$this->share = $this->server->getShare($this->config->share);
|
||||
if ($this->config->root) {
|
||||
|
|
@ -39,4 +44,41 @@ class NativeShareTest extends AbstractShareTest {
|
|||
}
|
||||
$this->share->mkdir($this->root);
|
||||
}
|
||||
|
||||
public function testProtocolMatch() {
|
||||
$options = new Options();
|
||||
$options->setMinProtocol(IOptions::PROTOCOL_SMB2);
|
||||
$options->setMaxProtocol(IOptions::PROTOCOL_SMB3);
|
||||
$server = new NativeServer(
|
||||
$this->config->host,
|
||||
new BasicAuth(
|
||||
$this->config->user,
|
||||
'test',
|
||||
$this->config->password
|
||||
),
|
||||
new System(),
|
||||
new TimeZoneProvider(new System()),
|
||||
$options
|
||||
);
|
||||
$server->listShares();
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testToLowMaxProtocol() {
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$options = new Options();
|
||||
$options->setMaxProtocol(IOptions::PROTOCOL_NT1);
|
||||
$server = new NativeServer(
|
||||
$this->config->host,
|
||||
new BasicAuth(
|
||||
$this->config->user,
|
||||
'test',
|
||||
$this->config->password
|
||||
),
|
||||
new System(),
|
||||
new TimeZoneProvider(new System()),
|
||||
$options
|
||||
);
|
||||
$server->listShares();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Icewind\SMB\Test;
|
|||
use Icewind\SMB\BasicAuth;
|
||||
use Icewind\SMB\Exception\AuthenticationException;
|
||||
use Icewind\SMB\Exception\ConnectionRefusedException;
|
||||
use Icewind\SMB\Exception\InvalidHostException;
|
||||
use Icewind\SMB\IOptions;
|
||||
use Icewind\SMB\IShare;
|
||||
use Icewind\SMB\Options;
|
||||
use Icewind\SMB\System;
|
||||
|
|
@ -114,4 +114,41 @@ class ServerTest extends TestCase {
|
|||
);
|
||||
$server->listShares();
|
||||
}
|
||||
|
||||
public function testProtocolMatch() {
|
||||
$options = new Options();
|
||||
$options->setMinProtocol(IOptions::PROTOCOL_SMB2);
|
||||
$options->setMaxProtocol(IOptions::PROTOCOL_SMB3);
|
||||
$server = new Server(
|
||||
$this->config->host,
|
||||
new BasicAuth(
|
||||
$this->config->user,
|
||||
'test',
|
||||
$this->config->password
|
||||
),
|
||||
new System(),
|
||||
new TimeZoneProvider(new System()),
|
||||
$options
|
||||
);
|
||||
$server->listShares();
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testToLowMaxProtocol() {
|
||||
$this->expectException(ConnectionRefusedException::class);
|
||||
$options = new Options();
|
||||
$options->setMaxProtocol(IOptions::PROTOCOL_NT1);
|
||||
$server = new Server(
|
||||
$this->config->host,
|
||||
new BasicAuth(
|
||||
$this->config->user,
|
||||
'test',
|
||||
$this->config->password
|
||||
),
|
||||
new System(),
|
||||
new TimeZoneProvider(new System()),
|
||||
$options
|
||||
);
|
||||
$server->listShares();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue