Skip to content

Commit 96f04ec

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 c50f1e3 commit 96f04ec

4 files changed

Lines changed: 266 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
@@ -11,9 +11,11 @@
1111

1212
use OCA\DAV\CalDAV\CalendarObject;
1313
use OCA\DAV\CalDAV\EventComparisonService;
14+
use OCP\Accounts\IAccountManager;
1415
use OCP\AppFramework\Utility\ITimeFactory;
1516
use OCP\Defaults;
1617
use OCP\IAppConfig;
18+
use OCP\IUser;
1719
use OCP\IUserSession;
1820
use OCP\Mail\IEmailValidator;
1921
use OCP\Mail\IMailer;
@@ -66,6 +68,7 @@ public function __construct(
6668
private EventComparisonService $eventComparisonService,
6769
private IMailManager $mailManager,
6870
private IEmailValidator $emailValidator,
71+
private IAccountManager $accountManager,
6972
) {
7073
parent::__construct('');
7174
}
@@ -184,21 +187,17 @@ public function schedule(Message $iTipMessage) {
184187
}
185188
$this->imipService->setL10nFromAttendee($attendee);
186189

187-
// Build the sender name.
190+
$sender = substr($iTipMessage->sender, 7);
191+
188192
// Due to a bug in sabre, the senderName property for an iTIP message can actually also be a VObject Property
189-
// If the iTIP message senderName is null or empty use the user session name as the senderName
190193
if (($iTipMessage->senderName instanceof Parameter) && !empty(trim($iTipMessage->senderName->getValue()))) {
191194
$senderName = trim($iTipMessage->senderName->getValue());
192195
} elseif (is_string($iTipMessage->senderName) && !empty(trim($iTipMessage->senderName))) {
193196
$senderName = trim($iTipMessage->senderName);
194-
} elseif ($this->userSession->getUser() !== null) {
195-
$senderName = trim($this->userSession->getUser()->getDisplayName());
196197
} else {
197-
$senderName = '';
198+
$senderName = $this->getSenderNameFor($sender);
198199
}
199200

200-
$sender = substr($iTipMessage->sender, 7);
201-
202201
$replyingAttendee = null;
203202
switch (strtolower($iTipMessage->method)) {
204203
case self::METHOD_REPLY:
@@ -338,6 +337,40 @@ public function schedule(Message $iTipMessage) {
338337
}
339338
}
340339

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

apps/dav/lib/Server.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ public function __construct(
360360
\OCP\Server::get(EventComparisonService::class),
361361
\OCP\Server::get(\OCP\Mail\Provider\IManager::class),
362362
\OCP\Server::get(IEmailValidator::class),
363+
\OCP\Server::get(IAccountManager::class),
363364
));
364365
}
365366
$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)