Skip to content

Commit 560f12d

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 c8498e7 commit 560f12d

4 files changed

Lines changed: 267 additions & 7 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\IEmailValidator;
1820
use OCP\Mail\IMailer;
@@ -65,6 +67,7 @@ public function __construct(
6567
private EventComparisonService $eventComparisonService,
6668
private IMailManager $mailManager,
6769
private IEmailValidator $emailValidator,
70+
private IAccountManager $accountManager,
6871
) {
6972
parent::__construct('');
7073
}
@@ -181,21 +184,17 @@ public function schedule(Message $iTipMessage) {
181184
}
182185
$this->imipService->setL10nFromAttendee($attendee);
183186

184-
// Build the sender name.
187+
$sender = substr($iTipMessage->sender, 7);
188+
185189
// Due to a bug in sabre, the senderName property for an iTIP message can actually also be a VObject Property
186-
// If the iTIP message senderName is null or empty use the user session name as the senderName
187190
if (($iTipMessage->senderName instanceof Parameter) && !empty(trim($iTipMessage->senderName->getValue()))) {
188191
$senderName = trim($iTipMessage->senderName->getValue());
189192
} elseif (is_string($iTipMessage->senderName) && !empty(trim($iTipMessage->senderName))) {
190193
$senderName = trim($iTipMessage->senderName);
191-
} elseif ($this->userSession->getUser() !== null) {
192-
$senderName = trim($this->userSession->getUser()->getDisplayName());
193194
} else {
194-
$senderName = '';
195+
$senderName = $this->getSenderNameFor($sender);
195196
}
196197

197-
$sender = substr($iTipMessage->sender, 7);
198-
199198
$replyingAttendee = null;
200199
switch (strtolower($iTipMessage->method)) {
201200
case self::METHOD_REPLY:
@@ -335,6 +334,40 @@ public function schedule(Message $iTipMessage) {
335334
}
336335
}
337336

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

‎apps/dav/lib/Server.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ public function __construct(
358358
\OCP\Server::get(EventComparisonService::class),
359359
\OCP\Server::get(\OCP\Mail\Provider\IManager::class),
360360
\OCP\Server::get(IEmailValidator::class),
361+
\OCP\Server::get(IAccountManager::class),
361362
));
362363
}
363364
$this->server->addPlugin(new \OCA\DAV\CalDAV\Search\SearchPlugin());

‎apps/dav/tests/unit/CalDAV/Schedule/IMipPluginCharsetTest.php‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use OCA\DAV\CalDAV\EventComparisonService;
1414
use OCA\DAV\CalDAV\Schedule\IMipPlugin;
1515
use OCA\DAV\CalDAV\Schedule\IMipService;
16+
use OCP\Accounts\IAccountManager;
1617
use OCP\AppFramework\Utility\ITimeFactory;
1718
use OCP\Config\IUserConfig;
1819
use OCP\Defaults;
@@ -132,6 +133,7 @@ protected function setUp(): void {
132133
$this->eventComparisonService,
133134
$this->mailManager,
134135
$this->getEmailValidatorWithStrictEmailCheck(),
136+
$this->createMock(IAccountManager::class),
135137
);
136138

137139
// ITipMessage

0 commit comments

Comments
 (0)