From caa89fb548189a9d0c4d9471ab07ff1d359dcb80 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 17 Oct 2025 10:02:44 +0200 Subject: [PATCH 1/2] fix(federation): Allow outgoing federation with oCIS federated cloud ids Signed-off-by: Joas Schilling --- lib/private/Federation/CloudIdManager.php | 32 ++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/private/Federation/CloudIdManager.php b/lib/private/Federation/CloudIdManager.php index 7e7adda3d39..b07679ac02f 100644 --- a/lib/private/Federation/CloudIdManager.php +++ b/lib/private/Federation/CloudIdManager.php @@ -109,7 +109,7 @@ class CloudIdManager implements ICloudIdManager { // We accept slightly more chars when working with federationId than with a local userId. // We remove those eventual chars from the UserId before using // the IUserManager API to confirm its format. - $this->userManager->validateUserId(str_replace('=', '-', $user)); + $this->validateUser($user, $remote); if (!empty($user) && !empty($remote)) { $remote = $this->ensureDefaultProtocol($remote); @@ -119,6 +119,36 @@ class CloudIdManager implements ICloudIdManager { throw new \InvalidArgumentException('Invalid cloud id'); } + protected function validateUser(string $user, string $remote): void { + // Check the ID for bad characters + // Allowed are: "a-z", "A-Z", "0-9", spaces and "_.@-'" (Nextcloud) + // Additional: "=" (oCIS) + if (preg_match('/[^a-zA-Z0-9 _.@\-\'=]/', $user)) { + throw new \InvalidArgumentException('Invalid characters'); + } + + // No empty user ID + if (trim($user) === '') { + throw new \InvalidArgumentException('Empty user'); + } + + // No whitespace at the beginning or at the end + if (trim($user) !== $user) { + throw new \InvalidArgumentException('User contains whitespace at the beginning or at the end'); + } + + // User ID only consists of 1 or 2 dots (directory traversal) + if ($user === '.' || $user === '..') { + throw new \InvalidArgumentException('User must not consist of dots only'); + } + + // User ID is too long + if (strlen($user . '@' . $remote) > 255) { + // TRANSLATORS User ID is too long + throw new \InvalidArgumentException('Cloud id is too long'); + } + } + public function getDisplayNameFromContact(string $cloudId): ?string { $cachedName = $this->displayNameCache->get($cloudId); if ($cachedName !== null) { From 21651a2e0be2230d6510f36199ebeb9e8e593a71 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 17 Oct 2025 10:26:49 +0200 Subject: [PATCH 2/2] fix(federation): Increase the size of owner to allow oCIS cloud ids Signed-off-by: Joas Schilling --- apps/files_sharing/appinfo/info.xml | 2 +- .../composer/composer/autoload_classmap.php | 1 + .../composer/composer/autoload_static.php | 1 + .../Version32000Date20251017081948.php | 38 +++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 apps/files_sharing/lib/Migration/Version32000Date20251017081948.php diff --git a/apps/files_sharing/appinfo/info.xml b/apps/files_sharing/appinfo/info.xml index 06bf6cdc9e1..e73086d8719 100644 --- a/apps/files_sharing/appinfo/info.xml +++ b/apps/files_sharing/appinfo/info.xml @@ -14,7 +14,7 @@ Turning the feature off removes shared files and folders on the server for all share recipients, and also on the sync clients and mobile apps. More information is available in the Nextcloud Documentation. - 1.23.1 + 1.23.2 agpl Michael Gapczynski Bjoern Schiessle diff --git a/apps/files_sharing/composer/composer/autoload_classmap.php b/apps/files_sharing/composer/composer/autoload_classmap.php index 992aff9408e..6515aa31c83 100644 --- a/apps/files_sharing/composer/composer/autoload_classmap.php +++ b/apps/files_sharing/composer/composer/autoload_classmap.php @@ -80,6 +80,7 @@ return array( 'OCA\\Files_Sharing\\Migration\\Version24000Date20220208195521' => $baseDir . '/../lib/Migration/Version24000Date20220208195521.php', 'OCA\\Files_Sharing\\Migration\\Version24000Date20220404142216' => $baseDir . '/../lib/Migration/Version24000Date20220404142216.php', 'OCA\\Files_Sharing\\Migration\\Version31000Date20240821142813' => $baseDir . '/../lib/Migration/Version31000Date20240821142813.php', + 'OCA\\Files_Sharing\\Migration\\Version32000Date20251017081948' => $baseDir . '/../lib/Migration/Version32000Date20251017081948.php', 'OCA\\Files_Sharing\\MountProvider' => $baseDir . '/../lib/MountProvider.php', 'OCA\\Files_Sharing\\Notification\\Listener' => $baseDir . '/../lib/Notification/Listener.php', 'OCA\\Files_Sharing\\Notification\\Notifier' => $baseDir . '/../lib/Notification/Notifier.php', diff --git a/apps/files_sharing/composer/composer/autoload_static.php b/apps/files_sharing/composer/composer/autoload_static.php index 6ca9705984e..67e75640916 100644 --- a/apps/files_sharing/composer/composer/autoload_static.php +++ b/apps/files_sharing/composer/composer/autoload_static.php @@ -95,6 +95,7 @@ class ComposerStaticInitFiles_Sharing 'OCA\\Files_Sharing\\Migration\\Version24000Date20220208195521' => __DIR__ . '/..' . '/../lib/Migration/Version24000Date20220208195521.php', 'OCA\\Files_Sharing\\Migration\\Version24000Date20220404142216' => __DIR__ . '/..' . '/../lib/Migration/Version24000Date20220404142216.php', 'OCA\\Files_Sharing\\Migration\\Version31000Date20240821142813' => __DIR__ . '/..' . '/../lib/Migration/Version31000Date20240821142813.php', + 'OCA\\Files_Sharing\\Migration\\Version32000Date20251017081948' => __DIR__ . '/..' . '/../lib/Migration/Version32000Date20251017081948.php', 'OCA\\Files_Sharing\\MountProvider' => __DIR__ . '/..' . '/../lib/MountProvider.php', 'OCA\\Files_Sharing\\Notification\\Listener' => __DIR__ . '/..' . '/../lib/Notification/Listener.php', 'OCA\\Files_Sharing\\Notification\\Notifier' => __DIR__ . '/..' . '/../lib/Notification/Notifier.php', diff --git a/apps/files_sharing/lib/Migration/Version32000Date20251017081948.php b/apps/files_sharing/lib/Migration/Version32000Date20251017081948.php new file mode 100644 index 00000000000..15038dc0ec0 --- /dev/null +++ b/apps/files_sharing/lib/Migration/Version32000Date20251017081948.php @@ -0,0 +1,38 @@ +getTable('share_external'); + $column = $table->getColumn('owner'); + if ($column->getLength() < 255) { + $column->setLength(255); + return $schema; + } + return null; + } +}