(fix) proper handling of file attachments in S/MIME encrypted mails
parent
2f1c8cdbc8
commit
c875302a86
|
@ -1,6 +1,6 @@
|
|||
/* NSString+Mail.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2014 Inverse inc.
|
||||
* Copyright (C) 2007-2018 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -34,6 +34,7 @@
|
|||
- (int) indexOf: (unichar) _c;
|
||||
- (NSString *) decodedHeader;
|
||||
- (NSString *) asSafeFilename;
|
||||
- (NSString *) asPreferredFilenameUsingPath: (NSString *) thePath;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* NSString+Mail.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2008-2014 Inverse inc.
|
||||
* Copyright (C) 2008-2018 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -732,4 +732,33 @@ convertChars (const char *oldString, unsigned int oldLength,
|
|||
return safeName;
|
||||
}
|
||||
|
||||
//
|
||||
// We might end up here because of MUA that actually strips the
|
||||
// Content-Disposition (and thus, the filename) when mails containing
|
||||
// attachments have been forwarded. Thunderbird (2.x) does just that
|
||||
// when forwarding mails with images attached to them (using cid:...).
|
||||
//
|
||||
- (NSString *) asPreferredFilenameUsingPath: (NSString *) thePath
|
||||
{
|
||||
NSString *filename;
|
||||
|
||||
filename = nil;
|
||||
if (!thePath)
|
||||
thePath = @"1";
|
||||
|
||||
if ([self hasPrefix: @"application/"] ||
|
||||
[self hasPrefix: @"audio/"] ||
|
||||
[self hasPrefix: @"image/"] ||
|
||||
[self hasPrefix: @"video/"])
|
||||
{
|
||||
filename = [NSString stringWithFormat: @"unknown_%@", thePath];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([self isEqualToString: @"message/rfc822"])
|
||||
filename = [NSString stringWithFormat: @"email_%@.eml", thePath];
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -779,9 +779,10 @@ static NSString *userAgent = nil;
|
|||
//
|
||||
- (void) _fetchAttachmentsFromMail: (SOGoMailObject *) sourceMail
|
||||
{
|
||||
unsigned int max, count;
|
||||
NSArray *attachments;
|
||||
NSDictionary *currentInfo;
|
||||
NSArray *attachments;
|
||||
|
||||
unsigned int max, count;
|
||||
|
||||
attachments = [sourceMail fetchFileAttachments];
|
||||
max = [attachments count];
|
||||
|
@ -793,6 +794,70 @@ static NSString *userAgent = nil;
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (void) _fileAttachmentsFromPart: (id) thePart
|
||||
{
|
||||
if ([thePart isKindOfClass: [NGMimeBodyPart class]])
|
||||
{
|
||||
NSString *filename, *mimeType;
|
||||
id body;
|
||||
|
||||
mimeType = [[thePart contentType] stringValue];
|
||||
body = [thePart body];
|
||||
filename = [(NGMimeContentDispositionHeaderField *)[thePart headerForKey: @"content-disposition"] filename];
|
||||
|
||||
if (!filename)
|
||||
filename = [mimeType asPreferredFilenameUsingPath: nil];
|
||||
|
||||
if (filename)
|
||||
{
|
||||
NSDictionary *currentInfo;
|
||||
|
||||
currentInfo = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
filename, @"filename",
|
||||
mimeType, @"mimetype",
|
||||
nil];
|
||||
[self saveAttachment: body
|
||||
withMetadata: currentInfo];
|
||||
}
|
||||
}
|
||||
else if ([thePart isKindOfClass: [NGMimeMultipartBody class]])
|
||||
{
|
||||
NSArray *parts;
|
||||
int i;
|
||||
|
||||
parts = [thePart parts];
|
||||
for (i = 0; i < [parts count]; i++)
|
||||
{
|
||||
[self _fileAttachmentsFromPart: [parts objectAtIndex: i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
- (void) _fetchAttachmentsFromEncryptedMail: (SOGoMailObject *) sourceMail
|
||||
{
|
||||
NSData *certificate;
|
||||
|
||||
certificate = [[self mailAccountFolder] certificate];
|
||||
|
||||
// If we got a user certificate, let's use it. Otherwise we fallback we
|
||||
// don't try to get any attachments from the encrypted content
|
||||
if (certificate)
|
||||
{
|
||||
NGMimeMessage *m;
|
||||
|
||||
m = [[sourceMail content] messageFromEncryptedDataAndCertificate: certificate];
|
||||
[self _fileAttachmentsFromPart: [m body]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
@ -912,7 +977,10 @@ static NSString *userAgent = nil;
|
|||
if ([[ud mailMessageForwarding] isEqualToString: @"inline"])
|
||||
{
|
||||
[self setText: [sourceMail contentForInlineForward]];
|
||||
[self _fetchAttachmentsFromMail: sourceMail];
|
||||
if ([sourceMail isEncrypted])
|
||||
[self _fetchAttachmentsFromEncryptedMail: sourceMail];
|
||||
else
|
||||
[self _fetchAttachmentsFromMail: sourceMail];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1009,21 +1077,24 @@ static NSString *userAgent = nil;
|
|||
{
|
||||
NSString *p, *pmime, *name, *mimeType;
|
||||
|
||||
if (![_attach isNotNull]) {
|
||||
return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
|
||||
reason: @"Missing attachment content!"];
|
||||
}
|
||||
if (![_attach isNotNull])
|
||||
{
|
||||
return [NSException exceptionWithHTTPStatus: 400 /* Bad Request */
|
||||
reason: @"Missing attachment content!"];
|
||||
}
|
||||
|
||||
if (![self _ensureDraftFolderPath]) {
|
||||
return [NSException exceptionWithHTTPStatus:500 /* Server Error */
|
||||
reason: @"Could not create folder for draft!"];
|
||||
}
|
||||
if (![self _ensureDraftFolderPath])
|
||||
{
|
||||
return [NSException exceptionWithHTTPStatus: 500 /* Server Error */
|
||||
reason: @"Could not create folder for draft!"];
|
||||
}
|
||||
|
||||
name = [[metadata objectForKey: @"filename"] asSafeFilename];
|
||||
p = [self pathToAttachmentWithName: name];
|
||||
|
||||
if (![_attach writeToFile: p atomically: YES])
|
||||
{
|
||||
return [NSException exceptionWithHTTPStatus:500 /* Server Error */
|
||||
return [NSException exceptionWithHTTPStatus: 500 /* Server Error */
|
||||
reason: @"Could not write attachment to draft!"];
|
||||
}
|
||||
|
||||
|
|
|
@ -786,8 +786,8 @@ static BOOL debugSoParts = NO;
|
|||
if ([prefix hasSuffix: @"/"])
|
||||
prefix = [prefix substringToIndex: [prefix length] - 1];
|
||||
[self _feedFileAttachmentIds: attachmentIds
|
||||
withInfos: [coreInfos objectForKey: @"bodystructure"]
|
||||
andPrefix: prefix];
|
||||
withInfos: [coreInfos objectForKey: @"bodystructure"]
|
||||
andPrefix: prefix];
|
||||
|
||||
return attachmentIds;
|
||||
}
|
||||
|
@ -811,22 +811,7 @@ static BOOL debugSoParts = NO;
|
|||
|
||||
if (!filename)
|
||||
{
|
||||
// We might end up here because of MUA that actually strips the
|
||||
// Content-Disposition (and thus, the filename) when mails containing
|
||||
// attachments have been forwarded. Thunderbird (2.x) does just that
|
||||
// when forwarding mails with images attached to them (using cid:...).
|
||||
if ([mimeType hasPrefix: @"application/"] ||
|
||||
[mimeType hasPrefix: @"audio/"] ||
|
||||
[mimeType hasPrefix: @"image/"] ||
|
||||
[mimeType hasPrefix: @"video/"])
|
||||
{
|
||||
filename = [NSString stringWithFormat: @"unknown_%@", path];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([mimeType isEqualToString: @"message/rfc822"])
|
||||
filename = [NSString stringWithFormat: @"email_%@.eml", path];
|
||||
}
|
||||
filename = [mimeType asPreferredFilenameUsingPath: path];
|
||||
}
|
||||
|
||||
if (filename)
|
||||
|
|
Loading…
Reference in New Issue