From e44073ed1efb847dd459cded7fa5e51dd69795e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 10:39:40 +0000 Subject: [PATCH 1/2] Bump icewind/smb from 3.5.4 to 3.6.0 in /apps/files_external/3rdparty Bumps [icewind/smb](https://github.com/icewind1991/SMB) from 3.5.4 to 3.6.0. - [Release notes](https://github.com/icewind1991/SMB/releases) - [Commits](https://github.com/icewind1991/SMB/compare/v3.5.4...v3.6.0) --- updated-dependencies: - dependency-name: icewind/smb dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- apps/files_external/3rdparty/composer.json | 2 +- apps/files_external/3rdparty/composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/files_external/3rdparty/composer.json b/apps/files_external/3rdparty/composer.json index e17e80eddfdb..c8cc675057eb 100644 --- a/apps/files_external/3rdparty/composer.json +++ b/apps/files_external/3rdparty/composer.json @@ -18,7 +18,7 @@ }, "require": { "php": ">=7.4", - "icewind/smb": "3.5.4", + "icewind/smb": "3.6.0", "icewind/streams": "0.7.7", "google/apiclient": "2.15.0" }, diff --git a/apps/files_external/3rdparty/composer.lock b/apps/files_external/3rdparty/composer.lock index 85cadd9c6e1f..2aaacae6175f 100644 --- a/apps/files_external/3rdparty/composer.lock +++ b/apps/files_external/3rdparty/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d22b629a187afc4dc9bba24a11dd5c5b", + "content-hash": "84c6816bd744d7858e84c5d47f76b794", "packages": [ { "name": "google/apiclient", @@ -179,16 +179,16 @@ }, { "name": "icewind/smb", - "version": "v3.5.4", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/icewind1991/SMB.git", - "reference": "76995aa11c14e39bccd0f2370ed63b2f8f623a6d" + "reference": "e0e86b16640f5892dd00408ed50ad18357dac6c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/SMB/zipball/76995aa11c14e39bccd0f2370ed63b2f8f623a6d", - "reference": "76995aa11c14e39bccd0f2370ed63b2f8f623a6d", + "url": "https://api.github.com/repos/icewind1991/SMB/zipball/e0e86b16640f5892dd00408ed50ad18357dac6c1", + "reference": "e0e86b16640f5892dd00408ed50ad18357dac6c1", "shasum": "" }, "require": { @@ -220,9 +220,9 @@ "description": "php wrapper for smbclient and libsmbclient-php", "support": { "issues": "https://github.com/icewind1991/SMB/issues", - "source": "https://github.com/icewind1991/SMB/tree/v3.5.4" + "source": "https://github.com/icewind1991/SMB/tree/v3.6.0" }, - "time": "2022-05-30T15:18:19+00:00" + "time": "2023-08-10T13:17:39+00:00" }, { "name": "icewind/streams", From b752dc97294d4bc839c45efe06ee60018746fdcc Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Wed, 30 Aug 2023 16:33:27 +0545 Subject: [PATCH 2/2] changelog and files for icewind/smb 3.6.0 --- .../3rdparty/composer/autoload_classmap.php | 2 + .../3rdparty/composer/autoload_static.php | 2 + .../3rdparty/composer/installed.json | 14 +-- .../3rdparty/composer/installed.php | 10 +- .../icewind/smb/.github/workflows/ci.yaml | 31 +++--- .../3rdparty/icewind/smb/README.md | 7 +- ...-kerberos.php => example-sso-kerberos.php} | 5 +- .../3rdparty/icewind/smb/psalm.xml | 4 + .../smb/src/Exception/InvalidTicket.php | 28 +++++ .../icewind/smb/src/KerberosApacheAuth.php | 102 +++--------------- .../3rdparty/icewind/smb/src/KerberosAuth.php | 25 +++++ .../icewind/smb/src/KerberosTicket.php | 100 +++++++++++++++++ .../icewind/smb/src/Native/NativeState.php | 93 ++++++++++++---- .../unreleased/PHPdependencies20230822onward | 2 + 14 files changed, 290 insertions(+), 135 deletions(-) rename apps/files_external/3rdparty/icewind/smb/{example-apache-kerberos.php => example-sso-kerberos.php} (80%) create mode 100644 apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidTicket.php create mode 100644 apps/files_external/3rdparty/icewind/smb/src/KerberosTicket.php diff --git a/apps/files_external/3rdparty/composer/autoload_classmap.php b/apps/files_external/3rdparty/composer/autoload_classmap.php index 1219339e5dba..8094fe46b582 100644 --- a/apps/files_external/3rdparty/composer/autoload_classmap.php +++ b/apps/files_external/3rdparty/composer/autoload_classmap.php @@ -169,6 +169,7 @@ 'Icewind\\SMB\\Exception\\InvalidPathException' => $vendorDir . '/icewind/smb/src/Exception/InvalidPathException.php', 'Icewind\\SMB\\Exception\\InvalidRequestException' => $vendorDir . '/icewind/smb/src/Exception/InvalidRequestException.php', 'Icewind\\SMB\\Exception\\InvalidResourceException' => $vendorDir . '/icewind/smb/src/Exception/InvalidResourceException.php', + 'Icewind\\SMB\\Exception\\InvalidTicket' => $vendorDir . '/icewind/smb/src/Exception/InvalidTicket.php', 'Icewind\\SMB\\Exception\\InvalidTypeException' => $vendorDir . '/icewind/smb/src/Exception/InvalidTypeException.php', 'Icewind\\SMB\\Exception\\NoLoginServerException' => $vendorDir . '/icewind/smb/src/Exception/NoLoginServerException.php', 'Icewind\\SMB\\Exception\\NoRouteToHostException' => $vendorDir . '/icewind/smb/src/Exception/NoRouteToHostException.php', @@ -187,6 +188,7 @@ 'Icewind\\SMB\\ITimeZoneProvider' => $vendorDir . '/icewind/smb/src/ITimeZoneProvider.php', 'Icewind\\SMB\\KerberosApacheAuth' => $vendorDir . '/icewind/smb/src/KerberosApacheAuth.php', 'Icewind\\SMB\\KerberosAuth' => $vendorDir . '/icewind/smb/src/KerberosAuth.php', + 'Icewind\\SMB\\KerberosTicket' => $vendorDir . '/icewind/smb/src/KerberosTicket.php', 'Icewind\\SMB\\Native\\NativeFileInfo' => $vendorDir . '/icewind/smb/src/Native/NativeFileInfo.php', 'Icewind\\SMB\\Native\\NativeReadStream' => $vendorDir . '/icewind/smb/src/Native/NativeReadStream.php', 'Icewind\\SMB\\Native\\NativeServer' => $vendorDir . '/icewind/smb/src/Native/NativeServer.php', diff --git a/apps/files_external/3rdparty/composer/autoload_static.php b/apps/files_external/3rdparty/composer/autoload_static.php index e1a3bcfc4ca4..b885e8c414f2 100644 --- a/apps/files_external/3rdparty/composer/autoload_static.php +++ b/apps/files_external/3rdparty/composer/autoload_static.php @@ -239,6 +239,7 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 'Icewind\\SMB\\Exception\\InvalidPathException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/InvalidPathException.php', 'Icewind\\SMB\\Exception\\InvalidRequestException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/InvalidRequestException.php', 'Icewind\\SMB\\Exception\\InvalidResourceException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/InvalidResourceException.php', + 'Icewind\\SMB\\Exception\\InvalidTicket' => __DIR__ . '/..' . '/icewind/smb/src/Exception/InvalidTicket.php', 'Icewind\\SMB\\Exception\\InvalidTypeException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/InvalidTypeException.php', 'Icewind\\SMB\\Exception\\NoLoginServerException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/NoLoginServerException.php', 'Icewind\\SMB\\Exception\\NoRouteToHostException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/NoRouteToHostException.php', @@ -257,6 +258,7 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 'Icewind\\SMB\\ITimeZoneProvider' => __DIR__ . '/..' . '/icewind/smb/src/ITimeZoneProvider.php', 'Icewind\\SMB\\KerberosApacheAuth' => __DIR__ . '/..' . '/icewind/smb/src/KerberosApacheAuth.php', 'Icewind\\SMB\\KerberosAuth' => __DIR__ . '/..' . '/icewind/smb/src/KerberosAuth.php', + 'Icewind\\SMB\\KerberosTicket' => __DIR__ . '/..' . '/icewind/smb/src/KerberosTicket.php', 'Icewind\\SMB\\Native\\NativeFileInfo' => __DIR__ . '/..' . '/icewind/smb/src/Native/NativeFileInfo.php', 'Icewind\\SMB\\Native\\NativeReadStream' => __DIR__ . '/..' . '/icewind/smb/src/Native/NativeReadStream.php', 'Icewind\\SMB\\Native\\NativeServer' => __DIR__ . '/..' . '/icewind/smb/src/Native/NativeServer.php', diff --git a/apps/files_external/3rdparty/composer/installed.json b/apps/files_external/3rdparty/composer/installed.json index 451703ed15ec..fa33f2d87578 100644 --- a/apps/files_external/3rdparty/composer/installed.json +++ b/apps/files_external/3rdparty/composer/installed.json @@ -182,17 +182,17 @@ }, { "name": "icewind/smb", - "version": "v3.5.4", - "version_normalized": "3.5.4.0", + "version": "v3.6.0", + "version_normalized": "3.6.0.0", "source": { "type": "git", "url": "https://github.com/icewind1991/SMB.git", - "reference": "76995aa11c14e39bccd0f2370ed63b2f8f623a6d" + "reference": "e0e86b16640f5892dd00408ed50ad18357dac6c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/SMB/zipball/76995aa11c14e39bccd0f2370ed63b2f8f623a6d", - "reference": "76995aa11c14e39bccd0f2370ed63b2f8f623a6d", + "url": "https://api.github.com/repos/icewind1991/SMB/zipball/e0e86b16640f5892dd00408ed50ad18357dac6c1", + "reference": "e0e86b16640f5892dd00408ed50ad18357dac6c1", "shasum": "" }, "require": { @@ -205,7 +205,7 @@ "phpunit/phpunit": "^8.5|^9.3.8", "psalm/phar": "^4.3" }, - "time": "2022-05-30T15:18:19+00:00", + "time": "2023-08-10T13:17:39+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -226,7 +226,7 @@ "description": "php wrapper for smbclient and libsmbclient-php", "support": { "issues": "https://github.com/icewind1991/SMB/issues", - "source": "https://github.com/icewind1991/SMB/tree/v3.5.4" + "source": "https://github.com/icewind1991/SMB/tree/v3.6.0" }, "install-path": "../icewind/smb" }, diff --git a/apps/files_external/3rdparty/composer/installed.php b/apps/files_external/3rdparty/composer/installed.php index f4775c194347..0408afe577fd 100644 --- a/apps/files_external/3rdparty/composer/installed.php +++ b/apps/files_external/3rdparty/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'files_external/3rdparty', 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '79d2d94bd16ca97a2738cb1e18241c9290e55248', + 'reference' => 'e44073ed1efb847dd459cded7fa5e51dd69795e8', 'type' => 'library', 'install_path' => __DIR__ . '/../', 'aliases' => array(), @@ -13,7 +13,7 @@ 'files_external/3rdparty' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => '79d2d94bd16ca97a2738cb1e18241c9290e55248', + 'reference' => 'e44073ed1efb847dd459cded7fa5e51dd69795e8', 'type' => 'library', 'install_path' => __DIR__ . '/../', 'aliases' => array(), @@ -65,9 +65,9 @@ ), ), 'icewind/smb' => array( - 'pretty_version' => 'v3.5.4', - 'version' => '3.5.4.0', - 'reference' => '76995aa11c14e39bccd0f2370ed63b2f8f623a6d', + 'pretty_version' => 'v3.6.0', + 'version' => '3.6.0.0', + 'reference' => 'e0e86b16640f5892dd00408ed50ad18357dac6c1', 'type' => 'library', 'install_path' => __DIR__ . '/../icewind/smb', 'aliases' => array(), diff --git a/apps/files_external/3rdparty/icewind/smb/.github/workflows/ci.yaml b/apps/files_external/3rdparty/icewind/smb/.github/workflows/ci.yaml index cc23e91cf8bc..bf4aa67793eb 100644 --- a/apps/files_external/3rdparty/icewind/smb/.github/workflows/ci.yaml +++ b/apps/files_external/3rdparty/icewind/smb/.github/workflows/ci.yaml @@ -7,7 +7,7 @@ jobs: name: PHP-CS-Fixer runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@master + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 with: @@ -49,7 +49,7 @@ jobs: - name: Install packages run: | sudo apt-get install smbclient - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 with: @@ -70,7 +70,7 @@ jobs: command: php ./vendor/bin/phpunit tests -c tests/phpunit.xml --coverage-clover=coverage.xml env: BACKEND: ${{ matrix.backend }} - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v3 with: files: ./coverage.xml @@ -82,7 +82,10 @@ jobs: fail-fast: false matrix: client-version: - - "4.15.1" + - "4.18.1" + - "4.17.7" + - "4.16.10" + - "4.15.13" - "4.14.9" - "4.11.17" - "4.10.18" @@ -111,9 +114,9 @@ jobs: sudo apt install libjansson4 libcap2 libbsd0 libreadline8 libicu66 sudo mkdir -p /etc/samba /var/lib/samba/private echo "[global]\nclient min protocol = SMB2\nclient max protocol = SMB3" | sudo tee /etc/samba/smb.conf - sudo wget "https://github.com/icewind1991/smbclient-builder/releases/download/v0.1.0/smbclient-${{ matrix.client-version }}" -O /usr/local/bin/smbclient + sudo wget "https://github.com/icewind1991/smbclient-builder/releases/download/v0.1.2/smbclient-${{ matrix.client-version }}" -O /usr/local/bin/smbclient sudo chmod +x /usr/local/bin/smbclient - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 with: @@ -134,7 +137,7 @@ jobs: command: php ./vendor/bin/phpunit tests -c tests/phpunit.xml --coverage-clover=coverage.xml env: BACKEND: smbclient - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v3 with: files: ./coverage.xml @@ -154,7 +157,7 @@ jobs: - 445:445 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 with: @@ -175,7 +178,7 @@ jobs: runs-on: ubuntu-20.04 name: Kerberos SSO tests steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 with: @@ -194,7 +197,7 @@ jobs: run: | DC_IP=$(docker inspect dc --format '{{.NetworkSettings.IPAddress}}') LIST=$(docker run --rm --name client -v /tmp/shared:/shared --dns $DC_IP --hostname client.domain.test icewind1991/samba-krb-test-client \ - curl -s --negotiate -u testuser@DOMAIN.TEST: --delegation always http://httpd.domain.test/example-apache-kerberos.php) + curl -s --negotiate -u testuser@DOMAIN.TEST: --delegation always http://httpd.domain.test/example-sso-kerberos.php) echo $LIST LIST=$(echo $LIST | tr -d '[:space:]') [[ $LIST == "test.txt" ]] @@ -204,7 +207,7 @@ jobs: docker logs apache static-psalm-analysis: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 name: Psalm static analysis strategy: @@ -215,12 +218,14 @@ jobs: - "7.3" - "7.4" - "8.0" + - "8.1" + - "8.2" steps: - name: krb5-dev run: sudo apt-get install -y libkrb5-dev - name: Checkout - uses: actions/checkout@master + uses: actions/checkout@v3 - name: Set up php uses: shivammathur/setup-php@master with: @@ -242,7 +247,7 @@ jobs: steps: - name: krb5-dev run: sudo apt-get install -y libkrb5-dev - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 with: diff --git a/apps/files_external/3rdparty/icewind/smb/README.md b/apps/files_external/3rdparty/icewind/smb/README.md index fec1faefbadb..ed1d54e323c3 100644 --- a/apps/files_external/3rdparty/icewind/smb/README.md +++ b/apps/files_external/3rdparty/icewind/smb/README.md @@ -65,19 +65,20 @@ $server = $serverFactory->createServer('localhost', $auth); By re-using a client ticket you can create a single sign-on setup where the user authenticates against the web service using kerberos. And the web server can forward that ticket to the smb server, allowing it -to act on the behalf of the user without requiring the user to enter his passord. +to act on the behalf of the user without requiring the user to enter his password. The setup for such a system is fairly involved and requires roughly the following this - The web server is authenticated against kerberos with a machine account - Delegation is enabled for the web server's machine account -- Apache is setup to perform kerberos authentication and save the ticket in it's environment +- The web server is setup to perform kerberos authentication and save the ticket in it's environment - Php has the krb5 extension installed - The client authenticates using a ticket with forwarding enabled ```php $serverFactory = new ServerFactory(); -$auth = new KerberosApacheAuth(); +$auth = new KerberosAuth(); +$auth->setTicket(KerberosTicket::fromEnv()); $server = $serverFactory->createServer('localhost', $auth); ``` diff --git a/apps/files_external/3rdparty/icewind/smb/example-apache-kerberos.php b/apps/files_external/3rdparty/icewind/smb/example-sso-kerberos.php similarity index 80% rename from apps/files_external/3rdparty/icewind/smb/example-apache-kerberos.php rename to apps/files_external/3rdparty/icewind/smb/example-sso-kerberos.php index ddbeeecdb705..ca1055bf3749 100644 --- a/apps/files_external/3rdparty/icewind/smb/example-apache-kerberos.php +++ b/apps/files_external/3rdparty/icewind/smb/example-sso-kerberos.php @@ -1,5 +1,7 @@ setTicket(KerberosTicket::fromEnv()); $serverFactory = new \Icewind\SMB\ServerFactory(); $server = $serverFactory->createServer($host, $auth); diff --git a/apps/files_external/3rdparty/icewind/smb/psalm.xml b/apps/files_external/3rdparty/icewind/smb/psalm.xml index 32408861d98f..f841e92fc39e 100644 --- a/apps/files_external/3rdparty/icewind/smb/psalm.xml +++ b/apps/files_external/3rdparty/icewind/smb/psalm.xml @@ -6,6 +6,10 @@ xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" > + + + + diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidTicket.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidTicket.php new file mode 100644 index 000000000000..9021346aba6b --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidTicket.php @@ -0,0 +1,28 @@ + + * + * @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 . + * + */ + +namespace Icewind\SMB\Exception; + +class InvalidTicket extends Exception { + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/icewind/smb/src/KerberosApacheAuth.php b/apps/files_external/3rdparty/icewind/smb/src/KerberosApacheAuth.php index c49918be114a..c8de5555b31a 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/KerberosApacheAuth.php +++ b/apps/files_external/3rdparty/icewind/smb/src/KerberosApacheAuth.php @@ -23,114 +23,40 @@ use Icewind\SMB\Exception\DependencyException; use Icewind\SMB\Exception\Exception; +use Icewind\SMB\Exception\InvalidTicket; /** * Use existing kerberos ticket to authenticate and reuse the apache ticket cache (mod_auth_kerb) + * + * @deprecated Use `KerberosAuth` with `$auth->setTicket(KerberosTicket::fromEnv())` instead */ class KerberosApacheAuth extends KerberosAuth implements IAuth { - /** @var string */ - private $ticketPath = ""; - - /** @var bool */ - private $init = false; - - /** @var string|false */ - private $ticketName; - - public function __construct() { - $this->ticketName = getenv("KRB5CCNAME"); + public function getTicket(): KerberosTicket { + if ($this->ticket === null) { + $ticket = KerberosTicket::fromEnv(); + if ($ticket === null) { + throw new InvalidTicket("No ticket found in environment"); + } + $this->ticket = $ticket; + } + return $this->ticket; } - /** * Copy the ticket to a temporary location and use that ticket for authentication * * @return void */ public function copyTicket(): void { - if (!$this->checkTicket()) { - return; - } - $krb5 = new \KRB5CCache(); - $krb5->open($this->ticketName); - $tmpFilename = tempnam("/tmp", "krb5cc_php_"); - $tmpCacheFile = "FILE:" . $tmpFilename; - $krb5->save($tmpCacheFile); - $this->ticketPath = $tmpFilename; - $this->ticketName = $tmpCacheFile; - } - - /** - * Pass the ticket to smbclient by memory instead of path - * - * @return void - */ - public function passTicketFromMemory(): void { - if (!$this->checkTicket()) { - return; - } - $krb5 = new \KRB5CCache(); - $krb5->open($this->ticketName); - $this->ticketName = (string)$krb5->getName(); + $this->ticket = KerberosTicket::load($this->getTicket()->save()); } /** * Check if a valid kerberos ticket is present * * @return bool - * @psalm-assert-if-true string $this->ticketName */ public function checkTicket(): bool { - //read apache kerberos ticket cache - if (!$this->ticketName) { - return false; - } - - $krb5 = new \KRB5CCache(); - $krb5->open($this->ticketName); - /** @psalm-suppress MixedArgument */ - return count($krb5->getEntries()) > 0; - } - - private function init(): void { - if ($this->init) { - return; - } - $this->init = true; - // inspired by https://git.typo3.org/TYPO3CMS/Extensions/fal_cifs.git - - if (!extension_loaded("krb5")) { - // https://pecl.php.net/package/krb5 - throw new DependencyException('Ensure php-krb5 is installed.'); - } - - //read apache kerberos ticket cache - if (!$this->checkTicket()) { - throw new Exception('No kerberos ticket cache environment variable (KRB5CCNAME) found.'); - } - - // note that even if the ticketname is the value we got from `getenv("KRB5CCNAME")` we still need to set the env variable ourselves - // this is because `getenv` also reads the variables passed from the SAPI (apache-php) and we need to set the variable in the OS's env - putenv("KRB5CCNAME=" . $this->ticketName); - } - - public function getExtraCommandLineArguments(): string { - $this->init(); - return parent::getExtraCommandLineArguments(); - } - - public function setExtraSmbClientOptions($smbClientState): void { - $this->init(); - try { - parent::setExtraSmbClientOptions($smbClientState); - } catch (Exception $e) { - // suppress - } - } - - public function __destruct() { - if (!empty($this->ticketPath) && file_exists($this->ticketPath) && is_file($this->ticketPath)) { - unlink($this->ticketPath); - } + return $this->getTicket()->isValid(); } } diff --git a/apps/files_external/3rdparty/icewind/smb/src/KerberosAuth.php b/apps/files_external/3rdparty/icewind/smb/src/KerberosAuth.php index 68fb74ff9abd..d827cfcaf322 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/KerberosAuth.php +++ b/apps/files_external/3rdparty/icewind/smb/src/KerberosAuth.php @@ -27,6 +27,17 @@ * Use existing kerberos ticket to authenticate */ class KerberosAuth implements IAuth { + /** @var ?KerberosTicket */ + protected $ticket = null; + + public function getTicket(): ?KerberosTicket { + return $this->ticket; + } + + public function setTicket(?KerberosTicket $ticket): void { + $this->ticket = $ticket; + } + public function getUsername(): ?string { return 'dummy'; } @@ -39,11 +50,25 @@ public function getPassword(): ?string { return null; } + private function setEnv():void { + $ticket = $this->getTicket(); + if ($ticket) { + $ticket->validate(); + + // note that even if the ticket name is the value we got from `getenv("KRB5CCNAME")` we still need to set the env variable ourselves + // this is because `getenv` also reads the variables passed from the SAPI (apache-php) and we need to set the variable in the OS's env + putenv("KRB5CCNAME=" . $ticket->getCacheName()); + } + } + public function getExtraCommandLineArguments(): string { + $this->setEnv(); return '-k'; } public function setExtraSmbClientOptions($smbClientState): void { + $this->setEnv(); + $success = (bool)smbclient_option_set($smbClientState, SMBCLIENT_OPT_USE_KERBEROS, true); $success = $success && smbclient_option_set($smbClientState, SMBCLIENT_OPT_FALLBACK_AFTER_KERBEROS, false); diff --git a/apps/files_external/3rdparty/icewind/smb/src/KerberosTicket.php b/apps/files_external/3rdparty/icewind/smb/src/KerberosTicket.php new file mode 100644 index 000000000000..ea074501e684 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/KerberosTicket.php @@ -0,0 +1,100 @@ + + * + * @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 . + * + */ + +namespace Icewind\SMB; + +use Icewind\SMB\Exception\InvalidTicket; +use KRB5CCache; + +class KerberosTicket { + /** @var KRB5CCache */ + private $krb5; + /** @var string */ + private $cacheName; + + public function __construct(KRB5CCache $krb5, string $cacheName) { + $this->krb5 = $krb5; + $this->cacheName = $cacheName; + } + + public function getCacheName(): string { + return $this->cacheName; + } + + public function getName(): string{ + return $this->krb5->getName(); + } + + public function isValid(): bool { + return count($this->krb5->getEntries()) > 0; + } + + public function validate(): void { + if (!$this->isValid()) { + throw new InvalidTicket("No kerberos ticket found."); + } + } + + /** + * Load the ticket from the cache specified by the KRB5CCNAME variable. + * + * @return KerberosTicket|null + */ + public static function fromEnv(): ?KerberosTicket { + $ticketName = getenv("KRB5CCNAME"); + if (!$ticketName) { + return null; + } + $krb5 = new KRB5CCache(); + $krb5->open($ticketName); + return new KerberosTicket($krb5, $ticketName); + } + + public static function load(string $ticket): KerberosTicket { + $tmpFilename = tempnam(sys_get_temp_dir(), "krb5cc_php_"); + file_put_contents($tmpFilename, $ticket); + register_shutdown_function(function () use ($tmpFilename) { + if (file_exists($tmpFilename)) { + unlink($tmpFilename); + } + }); + + $ticketName = "FILE:" . $tmpFilename; + $krb5 = new KRB5CCache(); + $krb5->open($ticketName); + return new KerberosTicket($krb5, $ticketName); + } + + public function save(): string { + if (substr($this->cacheName, 0, 5) === 'FILE:') { + $ticket = file_get_contents(substr($this->cacheName, 5)); + } else { + $tmpFilename = tempnam(sys_get_temp_dir(), "krb5cc_php_"); + $tmpCacheFile = "FILE:" . $tmpFilename; + $this->krb5->save($tmpCacheFile); + $ticket = file_get_contents($tmpFilename); + unlink($tmpFilename); + } + return $ticket; + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeState.php b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeState.php index 088e6f733d12..acbfef141983 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeState.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeState.php @@ -8,6 +8,7 @@ namespace Icewind\SMB\Native; use Icewind\SMB\Exception\AlreadyExistsException; +use Icewind\SMB\Exception\ConnectionException; use Icewind\SMB\Exception\ConnectionRefusedException; use Icewind\SMB\Exception\ConnectionResetException; use Icewind\SMB\Exception\Exception; @@ -32,9 +33,6 @@ class NativeState { /** @var resource|null */ protected $state = null; - /** @var bool */ - protected $handlerSet = false; - /** @var bool */ protected $connected = false; @@ -67,7 +65,9 @@ class NativeState { ]; protected function handleError(?string $path): void { - /** @var int $error */ + if (!$this->state) { + return; + } $error = smbclient_state_errno($this->state); if ($error === 0) { return; @@ -120,7 +120,6 @@ public function init(IAuth $auth, IOptions $options) { // __deconstruct() of KerberosAuth should not caled too soon $this->auth = $auth; - /** @var bool $result */ $result = @smbclient_state_init($this->state, $auth->getWorkgroup(), $auth->getUsername(), $auth->getPassword()); $this->testResult($result, ''); @@ -133,6 +132,9 @@ public function init(IAuth $auth, IOptions $options) { * @return resource */ public function opendir(string $uri) { + if (!$this->state) { + throw new ConnectionException("Not connected"); + } /** @var resource $result */ $result = @smbclient_opendir($this->state, $uri); @@ -146,6 +148,9 @@ public function opendir(string $uri) { * @return array{"type": string, "comment": string, "name": string}|false */ public function readdir($dir, string $path) { + if (!$this->state) { + throw new ConnectionException("Not connected"); + } /** @var array{"type": string, "comment": string, "name": string}|false $result */ $result = @smbclient_readdir($this->state, $dir); @@ -159,8 +164,10 @@ public function readdir($dir, string $path) { * @return bool */ public function closedir($dir, string $path): bool { - /** @var bool $result */ - $result = smbclient_closedir($this->state, $dir); + if (!$this->state) { + throw new ConnectionException("Not connected"); + } + $result = @smbclient_closedir($this->state, $dir); $this->testResult($result, $path); return $result; @@ -172,7 +179,9 @@ public function closedir($dir, string $path): bool { * @return bool */ public function rename(string $old, string $new): bool { - /** @var bool $result */ + if (!$this->state) { + throw new ConnectionException("Not connected"); + } $result = @smbclient_rename($this->state, $old, $this->state, $new); $this->testResult($result, $new); @@ -184,7 +193,9 @@ public function rename(string $old, string $new): bool { * @return bool */ public function unlink(string $uri): bool { - /** @var bool $result */ + if (!$this->state) { + throw new ConnectionException("Not connected"); + } $result = @smbclient_unlink($this->state, $uri); $this->testResult($result, $uri); @@ -197,7 +208,9 @@ public function unlink(string $uri): bool { * @return bool */ public function mkdir(string $uri, int $mask = 0777): bool { - /** @var bool $result */ + if (!$this->state) { + throw new ConnectionException("Not connected"); + } $result = @smbclient_mkdir($this->state, $uri, $mask); $this->testResult($result, $uri); @@ -209,7 +222,9 @@ public function mkdir(string $uri, int $mask = 0777): bool { * @return bool */ public function rmdir(string $uri): bool { - /** @var bool $result */ + if (!$this->state) { + throw new ConnectionException("Not connected"); + } $result = @smbclient_rmdir($this->state, $uri); $this->testResult($result, $uri); @@ -221,6 +236,9 @@ public function rmdir(string $uri): bool { * @return array{"mtime": int, "size": int, "mode": int} */ public function stat(string $uri): array { + if (!$this->state) { + throw new ConnectionException("Not connected"); + } /** @var array{"mtime": int, "size": int, "mode": int} $result */ $result = @smbclient_stat($this->state, $uri); @@ -234,6 +252,9 @@ public function stat(string $uri): array { * @return array{"mtime": int, "size": int, "mode": int} */ public function fstat($file, string $path): array { + if (!$this->state) { + throw new ConnectionException("Not connected"); + } /** @var array{"mtime": int, "size": int, "mode": int} $result */ $result = @smbclient_fstat($this->state, $file); @@ -248,6 +269,9 @@ public function fstat($file, string $path): array { * @return resource */ public function open(string $uri, string $mode, int $mask = 0666) { + if (!$this->state) { + throw new ConnectionException("Not connected"); + } /** @var resource $result */ $result = @smbclient_open($this->state, $uri, $mode, $mask); @@ -261,6 +285,9 @@ public function open(string $uri, string $mode, int $mask = 0666) { * @return resource */ public function create(string $uri, int $mask = 0666) { + if (!$this->state) { + throw new ConnectionException("Not connected"); + } /** @var resource $result */ $result = @smbclient_creat($this->state, $uri, $mask); @@ -275,6 +302,9 @@ public function create(string $uri, int $mask = 0666) { * @return string */ public function read($file, int $bytes, string $path): string { + if (!$this->state) { + throw new ConnectionException("Not connected"); + } /** @var string $result */ $result = @smbclient_read($this->state, $file, $bytes); @@ -290,10 +320,19 @@ public function read($file, int $bytes, string $path): string { * @return int */ public function write($file, string $data, string $path, ?int $length = null): int { - /** @var int $result */ - $result = @smbclient_write($this->state, $file, $data, $length); + if (!$this->state) { + throw new ConnectionException("Not connected"); + } + if ($length) { + $result = @smbclient_write($this->state, $file, $data, $length); + } else { + $result = @smbclient_write($this->state, $file, $data); + } $this->testResult($result, $path); + if ($result === false) { + return 0; + } return $result; } @@ -302,10 +341,18 @@ public function write($file, string $data, string $path, ?int $length = null): i * @param int $offset * @param int $whence SEEK_SET | SEEK_CUR | SEEK_END * @param string|null $path - * @return int|false new file offset as measured from the start of the file on success. + * + * @return false|int new file offset as measured from the start of the file on success. */ public function lseek($file, int $offset, int $whence = SEEK_SET, string $path = null) { - /** @var int|false $result */ + if (!$this->state) { + throw new ConnectionException("Not connected"); + } + // psalm doesn't think int|false == int|false for some reason, so we do a needless annotation to help it out + /** + * @psalm-suppress UnnecessaryVarAnnotation + * @var int|false $result + */ $result = @smbclient_lseek($this->state, $file, $offset, $whence); $this->testResult($result, $path); @@ -319,7 +366,9 @@ public function lseek($file, int $offset, int $whence = SEEK_SET, string $path = * @return bool */ public function ftruncate($file, int $size, string $path): bool { - /** @var bool $result */ + if (!$this->state) { + throw new ConnectionException("Not connected"); + } $result = @smbclient_ftruncate($this->state, $file, $size); $this->testResult($result, $path); @@ -332,7 +381,9 @@ public function ftruncate($file, int $size, string $path): bool { * @return bool */ public function close($file, string $path): bool { - /** @var bool $result */ + if (!$this->state) { + return false; + } $result = @smbclient_close($this->state, $file); $this->testResult($result, $path); @@ -345,6 +396,9 @@ public function close($file, string $path): bool { * @return string */ public function getxattr(string $uri, string $key) { + if (!$this->state) { + throw new ConnectionException("Not connected"); + } /** @var string $result */ $result = @smbclient_getxattr($this->state, $uri, $key); @@ -360,6 +414,9 @@ public function getxattr(string $uri, string $key) { * @return bool */ public function setxattr(string $uri, string $key, string $value, int $flags = 0) { + if (!$this->state) { + throw new ConnectionException("Not connected"); + } /** @var bool $result */ $result = @smbclient_setxattr($this->state, $uri, $key, $value, $flags); @@ -368,7 +425,7 @@ public function setxattr(string $uri, string $key, string $value, int $flags = 0 } public function __destruct() { - if ($this->connected) { + if ($this->connected && $this->state) { if (smbclient_state_free($this->state) === false) { throw new Exception("Failed to free smb state"); } diff --git a/changelog/unreleased/PHPdependencies20230822onward b/changelog/unreleased/PHPdependencies20230822onward index da4741a90114..0c967f88983f 100644 --- a/changelog/unreleased/PHPdependencies20230822onward +++ b/changelog/unreleased/PHPdependencies20230822onward @@ -8,6 +8,8 @@ The following have been updated: - symfony/process (5.4.26 to 5.4.28) The following have been updated in apps/files_external/3rdparty: +- icewind/smb (3.5.4 to 3.6.0) https://github.com/owncloud/core/pull/40939 https://github.com/owncloud/core/pull/40952 +https://github.com/owncloud/core/pull/40923