From 90be8f336cf55a3238aeecacf3a852484d5c342b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 May 2018 16:17:19 +0200 Subject: [PATCH] Add support for using kerberos ticket to authenticate to smb servers Signed-off-by: Robin Appelman --- .../lib/AppInfo/Application.php | 2 ++ .../lib/Lib/Auth/AuthMechanism.php | 1 + .../lib/Lib/Auth/SMB/KerberosAuth.php | 34 +++++++++++++++++++ apps/files_external/lib/Lib/Backend/SMB.php | 28 +++++++++++---- apps/files_external/lib/Lib/Storage/SMB.php | 26 +++++++++----- 5 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 apps/files_external/lib/Lib/Auth/SMB/KerberosAuth.php diff --git a/apps/files_external/lib/AppInfo/Application.php b/apps/files_external/lib/AppInfo/Application.php index e372a906ba..8eebc550d0 100644 --- a/apps/files_external/lib/AppInfo/Application.php +++ b/apps/files_external/lib/AppInfo/Application.php @@ -30,6 +30,7 @@ namespace OCA\Files_External\AppInfo; use OCA\Files_External\Lib\Auth\PublicKey\RSAPrivateKey; +use OCA\Files_External\Lib\Auth\SMB\KerberosAuth; use \OCP\AppFramework\App; use OCP\AppFramework\IAppContainer; use \OCA\Files_External\Service\BackendService; @@ -148,6 +149,7 @@ class Application extends App implements IBackendProvider, IAuthMechanismProvide // Specialized mechanisms $container->query(AccessKey::class), + $container->query(KerberosAuth::class), ]; } diff --git a/apps/files_external/lib/Lib/Auth/AuthMechanism.php b/apps/files_external/lib/Lib/Auth/AuthMechanism.php index 28d1dde437..6b583e6daa 100644 --- a/apps/files_external/lib/Lib/Auth/AuthMechanism.php +++ b/apps/files_external/lib/Lib/Auth/AuthMechanism.php @@ -60,6 +60,7 @@ class AuthMechanism implements \JsonSerializable { const SCHEME_OAUTH2 = 'oauth2'; const SCHEME_PUBLICKEY = 'publickey'; const SCHEME_OPENSTACK = 'openstack'; + const SCHEME_SMB = 'smb'; use VisibilityTrait; use FrontendDefinitionTrait; diff --git a/apps/files_external/lib/Lib/Auth/SMB/KerberosAuth.php b/apps/files_external/lib/Lib/Auth/SMB/KerberosAuth.php new file mode 100644 index 0000000000..ce1d050bbd --- /dev/null +++ b/apps/files_external/lib/Lib/Auth/SMB/KerberosAuth.php @@ -0,0 +1,34 @@ + + * + * @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 OCA\Files_External\Lib\Auth\SMB; + +use OCA\Files_External\Lib\Auth\AuthMechanism; +use OCP\IL10N; + +class KerberosAuth extends AuthMechanism { + public function __construct(IL10N $l) { + $this + ->setIdentifier('smb::kerberos') + ->setScheme(self::SCHEME_SMB) + ->setText($l->t('Kerberos ticket')); + } +} diff --git a/apps/files_external/lib/Lib/Backend/SMB.php b/apps/files_external/lib/Lib/Backend/SMB.php index f5335f4940..c871dc6977 100644 --- a/apps/files_external/lib/Lib/Backend/SMB.php +++ b/apps/files_external/lib/Lib/Backend/SMB.php @@ -22,6 +22,8 @@ namespace OCA\Files_External\Lib\Backend; +use Icewind\SMB\BasicAuth; +use Icewind\SMB\KerberosAuth; use \OCP\IL10N; use \OCA\Files_External\Lib\DefinitionParameter; use \OCA\Files_External\Lib\Auth\AuthMechanism; @@ -38,7 +40,7 @@ class SMB extends Backend { public function __construct(IL10N $l, Password $legacyAuth) { $this ->setIdentifier('smb') - ->addIdentifierAlias('\OC\Files\Storage\SMB') // legacy compat + ->addIdentifierAlias('\OC\Files\Storage\SMB')// legacy compat ->setStorageClass('\OCA\Files_External\Lib\Storage\SMB') ->setText($l->t('SMB / CIFS')) ->addParameters([ @@ -50,8 +52,8 @@ class SMB extends Backend { ->setFlag(DefinitionParameter::FLAG_OPTIONAL), ]) ->addAuthScheme(AuthMechanism::SCHEME_PASSWORD) - ->setLegacyAuthMechanism($legacyAuth) - ; + ->addAuthScheme(AuthMechanism::SCHEME_SMB) + ->setLegacyAuthMechanism($legacyAuth); } /** @@ -59,10 +61,24 @@ class SMB extends Backend { * @param IUser $user */ public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) { - $user = $storage->getBackendOption('user'); - if ($domain = $storage->getBackendOption('domain')) { - $storage->setBackendOption('user', $domain.'\\'.$user); + $auth = $storage->getAuthMechanism(); + if ($auth->getScheme() === AuthMechanism::SCHEME_PASSWORD) { + $smbAuth = new BasicAuth( + $storage->getBackendOption('user'), + $storage->getBackendOption('domain'), + $storage->getBackendOption('password') + ); + } else { + switch ($auth->getIdentifier()) { + case 'smb::kerberos': + $smbAuth = new KerberosAuth(); + break; + default: + throw new \InvalidArgumentException('unknown authentication backend'); + } } + + $storage->setBackendOption('auth', $smbAuth); } } diff --git a/apps/files_external/lib/Lib/Storage/SMB.php b/apps/files_external/lib/Lib/Storage/SMB.php index 93fc020d71..6213e54dff 100644 --- a/apps/files_external/lib/Lib/Storage/SMB.php +++ b/apps/files_external/lib/Lib/Storage/SMB.php @@ -78,19 +78,27 @@ class SMB extends Common implements INotifyStorage { protected $statCache; public function __construct($params) { - if (isset($params['host']) && isset($params['user']) && isset($params['password']) && isset($params['share'])) { + if (!isset($params['host'])) { + throw new \Exception('Invalid configuration, no host provided'); + } + + if (isset($params['auth'])) { + $auth = $params['auth']; + } else if (isset($params['user']) && isset($params['password']) && isset($params['share'])) { list($workgroup, $user) = $this->splitUser($params['user']); $auth = new BasicAuth($user, $workgroup, $params['password']); - $serverFactory = new ServerFactory(); - $this->server = $serverFactory->createServer($params['host'], $auth); - $this->share = $this->server->getShare(trim($params['share'], '/')); - - $this->root = $params['root'] ?? '/'; - $this->root = '/' . ltrim($this->root, '/'); - $this->root = rtrim($this->root, '/') . '/'; } else { - throw new \Exception('Invalid configuration'); + throw new \Exception('Invalid configuration, no credentials provided'); } + + $serverFactory = new ServerFactory(); + $this->server = $serverFactory->createServer($params['host'], $auth); + $this->share = $this->server->getShare(trim($params['share'], '/')); + + $this->root = $params['root'] ?? '/'; + $this->root = '/' . ltrim($this->root, '/'); + $this->root = rtrim($this->root, '/') . '/'; + $this->statCache = new CappedMemoryCache(); parent::__construct($params); }