Skip to content

Commit 427f0bc

Browse files
committed
fix(iMIP): Prevent mails from carrying an unrelated user's name
Assisted-by: ClaudeCode:claude-fable-5 Signed-off-by: David Dreschner <david.dreschner@nextcloud.com>
1 parent cd40539 commit 427f0bc

3 files changed

Lines changed: 277 additions & 8 deletions

File tree

apps/dav/lib/CalDAV/Schedule/IMipPlugin.php

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010

1111
use OCA\DAV\CalDAV\CalendarObject;
1212
use OCA\DAV\CalDAV\EventComparisonService;
13+
use OCP\Accounts\IAccountManager;
1314
use OCP\AppFramework\Utility\ITimeFactory;
1415
use OCP\Defaults;
1516
use OCP\IAppConfig;
17+
use OCP\IUser;
1618
use OCP\IUserSession;
1719
use OCP\Mail\IMailer;
1820
use OCP\Mail\Provider\Address;
@@ -63,6 +65,7 @@ public function __construct(
6365
private IMipService $imipService,
6466
private EventComparisonService $eventComparisonService,
6567
private IMailManager $mailManager,
68+
private IAccountManager $accountManager,
6669
) {
6770
parent::__construct('');
6871
}
@@ -179,21 +182,17 @@ public function schedule(Message $iTipMessage) {
179182
}
180183
$this->imipService->setL10nFromAttendee($attendee);
181184

182-
// Build the sender name.
185+
$sender = substr($iTipMessage->sender, 7);
186+
183187
// Due to a bug in sabre, the senderName property for an iTIP message can actually also be a VObject Property
184-
// If the iTIP message senderName is null or empty use the user session name as the senderName
185188
if (($iTipMessage->senderName instanceof Parameter) && !empty(trim($iTipMessage->senderName->getValue()))) {
186189
$senderName = trim($iTipMessage->senderName->getValue());
187190
} elseif (is_string($iTipMessage->senderName) && !empty(trim($iTipMessage->senderName))) {
188191
$senderName = trim($iTipMessage->senderName);
189-
} elseif ($this->userSession->getUser() !== null) {
190-
$senderName = trim($this->userSession->getUser()->getDisplayName());
191192
} else {
192-
$senderName = '';
193+
$senderName = $this->getSenderNameFor($sender);
193194
}
194195

195-
$sender = substr($iTipMessage->sender, 7);
196-
197196
$replyingAttendee = null;
198197
switch (strtolower($iTipMessage->method)) {
199198
case self::METHOD_REPLY:
@@ -333,6 +332,40 @@ public function schedule(Message $iTipMessage) {
333332
}
334333
}
335334

335+
/**
336+
* Messages are regularly brokered on behalf of somebody else, so the
337+
* session user's name is only used when the sender address is one of
338+
* theirs.
339+
*/
340+
private function getSenderNameFor(string $sender): ?string {
341+
$user = $this->userSession->getUser();
342+
if ($user !== null && $this->isAddressOfUser($sender, $user)) {
343+
return trim($user->getDisplayName()) ?: null;
344+
}
345+
346+
return null;
347+
}
348+
349+
/**
350+
* Profile email addresses are part of the user's calendar-user-address-set
351+
* and therefore valid sender addresses next to the system email address.
352+
*/
353+
private function isAddressOfUser(string $address, IUser $user): bool {
354+
if (strcasecmp((string)$user->getEMailAddress(), $address) === 0) {
355+
return true;
356+
}
357+
358+
$emailCollection = $this->accountManager->getAccount($user)
359+
->getPropertyCollection(IAccountManager::COLLECTION_EMAIL);
360+
foreach ($emailCollection->getProperties() as $property) {
361+
if (strcasecmp($property->getValue(), $address) === 0) {
362+
return true;
363+
}
364+
}
365+
366+
return false;
367+
}
368+
336369
/**
337370
* @return ?VCalendar
338371
*/

apps/dav/lib/Server.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,8 @@ public function __construct(
333333
$userSession,
334334
\OC::$server->get(IMipService::class),
335335
\OC::$server->get(EventComparisonService::class),
336-
\OC::$server->get(\OCP\Mail\Provider\IManager::class)
336+
\OC::$server->get(\OCP\Mail\Provider\IManager::class),
337+
\OC::$server->get(IAccountManager::class),
337338
));
338339
}
339340
$this->server->addPlugin(new \OCA\DAV\CalDAV\Search\SearchPlugin());

0 commit comments

Comments
 (0)