View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0003576 | SOGo | ActiveSync | public | 2016-03-11 07:07 | 2016-04-13 10:07 |
Reporter | st41ker | Assigned To | ludovic | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Platform | Any | OS | Any | OS Version | Any |
Product Version | 2.3.8 | ||||
Fixed in Version | 2.3.10 | ||||
Summary | 0003576: Wrong MessageClass via ActiveSync on S/MIME mails | ||||
Description | When MUA uses Content-Type of x-pkcs7-mime for S/MIME encrypted+signed messages, SoGo sets MessageClass to IPM.Note, instead of IPM.Note.SMIME. Also, clients are getting empty(zero bytes in size) attachement in this case. Seems like the code for this issue is located in ActiveSync/SOGoMailObject+ActiveSync.m, on line 929: | ||||
Steps To Reproduce | Change content type in email from Content-Type: application/pkcs7-mime; name="smime.p7m"; smime-type="enveloped-data" to Content-Type: application/x-pkcs7-mime; name="smime.p7m"; smime-type="enveloped-data" and try to decrypt email. | ||||
Tags | No tags attached. | ||||
According to RFC 2311 C.1 (https://tools.ietf.org/html/rfc2311#appendix-C.1) following mime-types: application/x-pkcs7-mime should also be supported. |
|
The same issue exists for GPG signed+encrypted emails with the following content-type: Content-Type: multipart/encrypted; protocol="application/pgp-encrypted"; MessageClass is set to IPM.Note, instead of IPM.Note.SMIME. |
|
Please attach a patch for what you have found, so that people from inverse can have a look. |
|
@tfu: |
|
May be else if ([subtype isEqualToString: @"pkcs7-mime"]) should be replaced with the following: else if ([subtype hasSuffix: @"pkcs7-mime"] || [subtype hasSuffix: @"encrypted"]) |
|
your sample looks ok - can you compile it and test the problem you described is fixed. i.e. test with your client which sends/use other mime-types then currently supported. |
|
I could try to do this, but I've never compiled SoGo from source. |
|
sogo-2.3.8-st41ker.patch (2,538 bytes)
diff -uNr SOGo-2.3.8/ActiveSync/SOGoMailObject+ActiveSync.m SOGo-2.3.8-2/ActiveSync/SOGoMailObject+ActiveSync.m --- SOGo-2.3.8/ActiveSync/SOGoMailObject+ActiveSync.m 2016-03-05 21:09:27.000000000 +0200 +++ SOGo-2.3.8-2/ActiveSync/SOGoMailObject+ActiveSync.m 2016-03-11 19:27:36.554328063 +0200 @@ -522,7 +522,7 @@ else if ([type isEqualToString: @"multipart"]) *theNativeType = 4; - if (([subtype isEqualToString: @"signed"] || [subtype isEqualToString: @"pkcs7-mime"] ) && theMimeSupport > 0) + if (([subtype isEqualToString: @"signed"] || [subtype hasSuffix: @"pkcs7-mime"] || [subtype hasSuffix: @"encrypted"]) && theMimeSupport > 0) { *theNativeType = 4; isSMIME = YES; @@ -900,7 +900,7 @@ // MesssageClass and ContentClass if ([subtype isEqualToString: @"signed"]) [s appendFormat: @"<MessageClass xmlns=\"Email:\">%@</MessageClass>", @"IPM.Note.SMIME.MultipartSigned"]; - else if ([subtype isEqualToString: @"pkcs7-mime"]) + else if ([subtype hasSuffix: @"pkcs7-mime"] || [subtype hasSuffix: @"encrypted"]) [s appendFormat: @"<MessageClass xmlns=\"Email:\">%@</MessageClass>", @"IPM.Note.SMIME"]; else [s appendFormat: @"<MessageClass xmlns=\"Email:\">%@</MessageClass>", @"IPM.Note"]; @@ -1024,7 +1024,7 @@ // For s/mime mails type is always 4 if mimeSupport is 1 or 2. if (preferredBodyType == 2 && nativeBodyType == 1) [s appendString: @"<Type>1</Type>"]; - else if (([subtype isEqualToString: @"signed"] || [subtype isEqualToString: @"pkcs7-mime"] ) && mimeSupport > 0) + else if (([subtype isEqualToString: @"signed"] || [subtype hasSuffix: @"pkcs7-mime"] || [subtype hasSuffix: @"encrypted"]) && mimeSupport > 0) [s appendString: @"<Type>4</Type>"]; else [s appendFormat: @"<Type>%d</Type>", preferredBodyType]; diff -uNr SOGo-2.3.8/SoObjects/Mailer/SOGoMailObject.m SOGo-2.3.8-1/SoObjects/Mailer/SOGoMailObject.m --- SOGo-2.3.8/SoObjects/Mailer/SOGoMailObject.m 2016-03-05 21:09:28.000000000 +0200 +++ SOGo-2.3.8-1/SoObjects/Mailer/SOGoMailObject.m 2016-03-11 19:26:32.017596837 +0200 @@ -851,7 +851,7 @@ // We set the path to 0 in case of a smime mail if not provided. subtype = [[part objectForKey: @"subtype"] lowercaseString]; - if ([subtype isEqualToString: @"pkcs7-mime"]) + if ([subtype hasSuffix: @"pkcs7-mime"]) path = @"0"; } |
|
I've uploaded working by somehow patch. |
|
The same problem with PGP signed+encrypted mail sent from Office365 account. Content-Type: multipart/mixed; --_0032016031118073453289815328944 --_0032016031118073453289815328944 --_0032016031118073453289815328944 LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCndjQk1BeUNWZ1hDMmZyM29BUWYvV281SG93 |
|
I don't understand your last update. |
|
@tfu: Your second question could be answered by MS in their AS protocol specs: https://msdn.microsoft.com/en-us/library/ee200767%28v=exchg.80%29.aspx IPM.Note.SMIME: The message is encrypted and can also be signed. In my example above email is a MIME email, and it is encrypted, and signed. There is another type of PGP encryption - inline encryption. These emails should have IPM.Note MessageClass if they are not signed, and should have IPM.Note.SMIME.MultipartSigned if they're PGP signed. At least, Office365 works exactly as I've proposed here. |
|
I don't think that PGP encrypted/signed emails can be handled the same way as SMIME signed/encrypted mails. EAS can deal with sMIME mails (there is the validateCert command which is used to verify signed (IPM.Note.SMIME) mails.
|
|
That is correct, but Office365 via AS provides exactly IPM.Note.SMIME for PGP\MIME emails. |
|
Also, some MUAs (BB10 for example) rely on MessageClass so they're not checking the email body for encrypted content. Just showing secure content as attachments. |
|
Please share the complete email you used for the test and the AS trace from 365. |
|
Actually, I've tested it with SoGo and disabling IPM.Note.SMIME and IPM.Note.SMIME.MultipartSigned MessageClass by hand via sources. |
|
Please send me the raw format of all emails you tested via email with a short description whether it is working or not. (tfu@aon.at) |
|
Are you speaking about AS debug replies? |
|
I want to see how the content-type(s) looks like for mails which are ok and not ok. |
|
I've used single email for tests, nothing changed in it. Please, confirm that you've understood this. Headers below: Content-Type: multipart/encrypted; protocol="application/pgp-encrypted"; boundary="===============0901805523==" --===============0901805523== --===============0901805523== -----BEGIN PGP MESSAGE----- The only change I've made - changed SoGo ActiveSync sources (aplied patch attached to this ticket), to provide IPM.Note.SMIME in MessageClass. If MessageClass on that email is not IPM.Note.SMIME then MUA shows email as simple email with attachments. The second question is that this patch is not working with mail sent from Office365 and delivered by SoGo to MUA. Sample email headers were posted here: http://sogo.nu/bugs/view.php?id=3576#c9713 |
|
sogo-2.3.9-pkcs-pgp.patch (2,538 bytes)
diff -uNr SOGo-2.3.9/ActiveSync/SOGoMailObject+ActiveSync.m SOGo-2.3.9-2/ActiveSync/SOGoMailObject+ActiveSync.m --- SOGo-2.3.9/ActiveSync/SOGoMailObject+ActiveSync.m 2016-03-16 18:14:43.000000000 +0200 +++ SOGo-2.3.9-2/ActiveSync/SOGoMailObject+ActiveSync.m 2016-03-16 20:56:20.526947500 +0200 @@ -523,7 +523,7 @@ else if ([type isEqualToString: @"multipart"]) *theNativeType = 4; - if (([subtype isEqualToString: @"signed"] || [subtype isEqualToString: @"pkcs7-mime"] ) && theMimeSupport > 0) + if (([subtype isEqualToString: @"signed"] || [subtype hasSuffix: @"pkcs7-mime"] || [subtype hasSuffix: @"encrypted"]) && theMimeSupport > 0) { *theNativeType = 4; isSMIME = YES; @@ -931,7 +931,7 @@ // MesssageClass and ContentClass if ([subtype isEqualToString: @"signed"]) [s appendFormat: @"<MessageClass xmlns=\"Email:\">%@</MessageClass>", @"IPM.Note.SMIME.MultipartSigned"]; - else if ([subtype isEqualToString: @"pkcs7-mime"]) + else if ([subtype hasSuffix: @"pkcs7-mime"] || [subtype hasSuffix: @"encrypted"]) [s appendFormat: @"<MessageClass xmlns=\"Email:\">%@</MessageClass>", @"IPM.Note.SMIME"]; else [s appendFormat: @"<MessageClass xmlns=\"Email:\">%@</MessageClass>", @"IPM.Note"]; @@ -1096,7 +1096,7 @@ // For s/mime mails type is always 4 if mimeSupport is 1 or 2. if (preferredBodyType == 2 && nativeBodyType == 1) [s appendString: @"<Type>1</Type>"]; - else if (([subtype isEqualToString: @"signed"] || [subtype isEqualToString: @"pkcs7-mime"] ) && mimeSupport > 0) + else if (([subtype isEqualToString: @"signed"] || [subtype hasSuffix: @"pkcs7-mime"] || [subtype hasSuffix: @"encrypted"]) && mimeSupport > 0) [s appendString: @"<Type>4</Type>"]; else [s appendFormat: @"<Type>%d</Type>", preferredBodyType]; diff -uNr SOGo-2.3.9/SoObjects/Mailer/SOGoMailObject.m SOGo-2.3.9-2/SoObjects/Mailer/SOGoMailObject.m --- SOGo-2.3.9/SoObjects/Mailer/SOGoMailObject.m 2016-03-16 18:14:43.000000000 +0200 +++ SOGo-2.3.9-2/SoObjects/Mailer/SOGoMailObject.m 2016-03-16 20:57:30.194659195 +0200 @@ -851,7 +851,7 @@ // We set the path to 0 in case of a smime mail if not provided. subtype = [[part objectForKey: @"subtype"] lowercaseString]; - if ([subtype isEqualToString: @"pkcs7-mime"]) + if ([subtype hasSuffix: @"pkcs7-mime"]) path = @"0"; } |
|
I've uploaded working patch for SOGo 2.3.9. |
|
For pgp encrypted mails the messageclass shouldn't be ipm.note.smime. This might be no problem for outlook or bb but prevent wp to show the pgp attachment. What about mails with Content-Type: multipart/mixed; mentioned in you update from 2016-03-11 14:13? |
|
Following email pgp encrypted and sent from Office365. Return-Path: <fromemail@accentgold.com> --_0032016031620243153044052986274accentgoldcom --_0032016031620243153044052986274accentgoldcom --_0032016031620243153044052986274accentgoldcom LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tDQoNCndjQk1BeUNWZ1hDMmZyM29BUWY5RVZNWXBp --_0032016031620243153044052986274accentgoldcom-- |
|
Could you, please, clarify what is WP? |
|
wp = windows phone. |
|
Are you 100% sure? |
|
about what? |
|
About WP incompatibility with MessageClass set to IPM.Note.SMIME for PGP encrypted email. |
|
YES, do you have other experience based on what you have tested? |
|
No, unfortunately. I've tested only PGP\MIME. With inline PGP everything works with IPM.Note MessageClass. |
|
I think I have a patch which takes care of most situations. I hope that I can finish my tests today evening. What app do you use on Android for pgp mails? |
|
|
|
I haven't tried, but can R2Mail2 talk ActiveSync? |
|
Heh, seems like it is not. |
|
@tfu: How can I help you any further? |
|
0017-PGP.patch (6,582 bytes)
From 8938f85a0a0f64d93320a4694bce7a893adb89e1 Mon Sep 17 00:00:00 2001 From: root <root@poldi2.hopto.org> Date: Thu, 17 Mar 2016 20:19:12 +0100 Subject: [PATCH 17/17] PGP --- ActiveSync/SOGoMailObject+ActiveSync.m | 104 ++++++++++++++++++++++++++++++--- SoObjects/Mailer/SOGoMailObject.m | 2 +- 2 files changed, 97 insertions(+), 9 deletions(-) diff --git a/ActiveSync/SOGoMailObject+ActiveSync.m b/ActiveSync/SOGoMailObject+ActiveSync.m index d9d123f..4d65f18 100644 --- a/ActiveSync/SOGoMailObject+ActiveSync.m +++ b/ActiveSync/SOGoMailObject+ActiveSync.m @@ -499,6 +499,91 @@ struct GlobalObjectId { return NO; } + +- (BOOL) _isSigned: (NSDictionary *) thePart +{ + NSMutableDictionary *currentPart; + NSArray *subparts; + NSString *type, *subtype; + NSUInteger i; + + type = [[thePart objectForKey: @"type"] lowercaseString]; + subtype = [[thePart objectForKey: @"subtype"] lowercaseString]; + + if ([type isEqualToString: @"multipart"]) + { + if ([subtype isEqualToString: @"signed"]) + return YES; + + subparts = [thePart objectForKey: @"parts"]; + for (i = 0; i < [subparts count]; i++) + { + currentPart = [subparts objectAtIndex: i]; + if ([self _isSigned: currentPart]) + return YES; + } + } + + return NO; +} + +- (BOOL) _isSmimeEncrypted: (NSDictionary *) thePart +{ + NSMutableDictionary *currentPart; + NSArray *subparts; + NSString *type, *subtype; + NSUInteger i; + + type = [[thePart objectForKey: @"type"] lowercaseString]; + subtype = [[thePart objectForKey: @"subtype"] lowercaseString]; + + if ([type isEqualToString: @"multipart"]) + { + subparts = [thePart objectForKey: @"parts"]; + for (i = 0; i < [subparts count]; i++) + { + currentPart = [subparts objectAtIndex: i]; + if ([self _isSmimeEncrypted: currentPart]) + return YES; + } + } + else if ([type isEqualToString: @"application"] && ([subtype isEqualToString: @"pkcs7-mime"] || + [subtype isEqualToString: @"x-pkcs7-mime"])) + return YES; + + return NO; +} + +- (BOOL) _isPGP: (NSDictionary *) thePart +{ + NSMutableDictionary *currentPart; + NSArray *subparts; + NSString *type, *subtype, *protocol; + NSUInteger i; + + type = [[thePart objectForKey: @"type"] lowercaseString]; + subtype = [[thePart objectForKey: @"subtype"] lowercaseString]; + protocol = [[[thePart objectForKey: @"parameterList"] objectForKey: @"protocol"] lowercaseString]; + + if ([type isEqualToString: @"multipart"]) + { + if (([protocol isEqualToString: @"application/pgp-signature"] || [protocol isEqualToString: @"application/pgp-encrypted"])) + return YES; + + subparts = [thePart objectForKey: @"parts"]; + for (i = 0; i < [subparts count]; i++) + { + currentPart = [subparts objectAtIndex: i]; + if ([self _isPGP: currentPart]) + return YES; + } + } + else if ([type isEqualToString: @"application"] && [subtype isEqualToString: @"pgp-encrypted"]) + return YES; + + return NO; +} + // // // @@ -523,7 +608,9 @@ struct GlobalObjectId { else if ([type isEqualToString: @"multipart"]) *theNativeType = 4; - if (([subtype isEqualToString: @"signed"] || [subtype isEqualToString: @"pkcs7-mime"] ) && theMimeSupport > 0) + if (([self _isSigned: [self bodyStructure]] || + [self _isSmimeEncrypted: [self bodyStructure]] || + [self _isPGP: [self bodyStructure]]) && theMimeSupport > 0) { *theNativeType = 4; isSMIME = YES; @@ -721,15 +808,13 @@ struct GlobalObjectId { NSData *d, *globalObjId; NSArray *attachmentKeys; iCalCalendar *calendar; - NSString *p, *subtype; + NSString *p; NSMutableString *s; id value; int preferredBodyType, mimeSupport, mimeTruncation, nativeBodyType; uint32_t v; - subtype = [[[self bodyStructure] valueForKey: @"subtype"] lowercaseString]; - preferredBodyType = [[context objectForKey: @"BodyPreferenceType"] intValue]; mimeSupport = [[context objectForKey: @"MIMESupport"] intValue]; mimeTruncation = [[context objectForKey: @"MIMETruncation"] intValue]; @@ -929,12 +1014,13 @@ struct GlobalObjectId { else { // MesssageClass and ContentClass - if ([subtype isEqualToString: @"signed"]) + if ([self _isSigned: [self bodyStructure]]) [s appendFormat: @"<MessageClass xmlns=\"Email:\">%@</MessageClass>", @"IPM.Note.SMIME.MultipartSigned"]; - else if ([subtype isEqualToString: @"pkcs7-mime"]) + else if ([self _isSmimeEncrypted: [self bodyStructure]]) [s appendFormat: @"<MessageClass xmlns=\"Email:\">%@</MessageClass>", @"IPM.Note.SMIME"]; else [s appendFormat: @"<MessageClass xmlns=\"Email:\">%@</MessageClass>", @"IPM.Note"]; + [s appendFormat: @"<ContentClass xmlns=\"Email:\">%@</ContentClass>", @"urn:content-classes:message"]; } @@ -1096,7 +1182,9 @@ struct GlobalObjectId { // For s/mime mails type is always 4 if mimeSupport is 1 or 2. if (preferredBodyType == 2 && nativeBodyType == 1) [s appendString: @"<Type>1</Type>"]; - else if (([subtype isEqualToString: @"signed"] || [subtype isEqualToString: @"pkcs7-mime"] ) && mimeSupport > 0) + else if (([self _isSigned: [self bodyStructure]] || + [self _isSmimeEncrypted: [self bodyStructure]] || + [self _isPGP: [self bodyStructure]]) && mimeSupport > 0) [s appendString: @"<Type>4</Type>"]; else [s appendFormat: @"<Type>%d</Type>", preferredBodyType]; @@ -1112,7 +1200,7 @@ struct GlobalObjectId { // Attachments -namespace 16 attachmentKeys = [self fetchFileAttachmentKeys]; - if ([attachmentKeys count] && !([subtype isEqualToString: @"signed"])) + if ([attachmentKeys count] && !([self _isSigned: [self bodyStructure]])) { int i; diff --git a/SoObjects/Mailer/SOGoMailObject.m b/SoObjects/Mailer/SOGoMailObject.m index dd4ee03..b71b974 100644 --- a/SoObjects/Mailer/SOGoMailObject.m +++ b/SoObjects/Mailer/SOGoMailObject.m @@ -851,7 +851,7 @@ static BOOL debugSoParts = NO; // We set the path to 0 in case of a smime mail if not provided. subtype = [[part objectForKey: @"subtype"] lowercaseString]; - if ([subtype isEqualToString: @"pkcs7-mime"]) + if ([subtype isEqualToString: @"pkcs7-mime"] || [subtype isEqualToString: @"x-pkcs7-mime"]) path = @"0"; } -- 2.1.4 |
|
Can you please test the attached patch (0017-PGP.patch). |
|
Tested PGP/MIME enc. (and\or)signed, S/MIME enc. (and\or) signed with BB10, Outlook 2013. Everything works as expected, except emails from Office365 read by Thunderbird, seems like it breaks something, but this has nothing commond with current issue. Since that Outlook 2013 has no support for PGP in AS mailboxes, I was unable to test it. |
|
tfu's patch pushed: 9621527414f35bd13cfe6acd40781d881ecaf860 thanks for your excellent work! |
|
Date Modified | Username | Field | Change |
---|---|---|---|
2016-03-11 07:07 | st41ker | New Issue | |
2016-03-11 07:11 | st41ker | Note Added: 0009703 | |
2016-03-11 07:17 | st41ker | Note Added: 0009704 | |
2016-03-11 10:20 | tfu | Note Added: 0009705 | |
2016-03-11 10:22 | st41ker | Note Added: 0009706 | |
2016-03-11 10:49 | st41ker | Note Added: 0009707 | |
2016-03-11 11:52 | tfu | Note Added: 0009708 | |
2016-03-11 11:54 | st41ker | Note Added: 0009709 | |
2016-03-11 17:41 | st41ker | File Added: sogo-2.3.8-st41ker.patch | |
2016-03-11 17:44 | st41ker | Note Added: 0009712 | |
2016-03-11 19:13 | st41ker | Note Added: 0009713 | |
2016-03-11 19:16 | st41ker | Note Edited: 0009713 | |
2016-03-11 21:19 | tfu | Note Added: 0009714 | |
2016-03-11 23:06 | tfu | Note Edited: 0009714 | |
2016-03-12 07:10 | st41ker | Note Added: 0009718 | |
2016-03-12 08:41 | tfu | Note Added: 0009721 | |
2016-03-12 08:43 | st41ker | Note Added: 0009722 | |
2016-03-12 09:08 | st41ker | Note Added: 0009724 | |
2016-03-12 09:10 | tfu | Note Added: 0009725 | |
2016-03-12 09:11 | st41ker | Note Edited: 0009724 | |
2016-03-12 09:15 | st41ker | Note Added: 0009726 | |
2016-03-12 11:50 | tfu | Note Added: 0009728 | |
2016-03-12 12:40 | st41ker | Note Added: 0009729 | |
2016-03-12 12:40 | st41ker | Note Edited: 0009729 | |
2016-03-12 13:28 | tfu | Note Added: 0009730 | |
2016-03-14 13:17 | st41ker | Note Added: 0009740 | |
2016-03-14 13:43 | st41ker | Note Edited: 0009740 | |
2016-03-14 13:51 | st41ker | Note Edited: 0009740 | |
2016-03-16 19:23 | st41ker | File Added: sogo-2.3.9-pkcs-pgp.patch | |
2016-03-16 19:24 | st41ker | Note Added: 0009761 | |
2016-03-16 20:14 | tfu | Note Added: 0009762 | |
2016-03-16 20:32 | st41ker | Note Added: 0009764 | |
2016-03-16 20:32 | st41ker | Note Added: 0009765 | |
2016-03-16 20:51 | tfu | Note Added: 0009766 | |
2016-03-16 20:57 | st41ker | Note Added: 0009767 | |
2016-03-16 20:57 | st41ker | Note Edited: 0009767 | |
2016-03-16 21:07 | tfu | Note Added: 0009768 | |
2016-03-17 13:11 | st41ker | Note Added: 0009775 | |
2016-03-17 13:50 | tfu | Note Added: 0009776 | |
2016-03-17 13:56 | st41ker | Note Added: 0009777 | |
2016-03-17 14:04 | tfu | Note Added: 0009778 | |
2016-03-17 14:10 | st41ker | Note Added: 0009779 | |
2016-03-17 14:35 | tfu | Note Added: 0009780 | |
2016-03-17 14:54 | st41ker | Note Added: 0009781 | |
2016-03-17 16:21 | st41ker | Note Added: 0009784 | |
2016-03-17 20:50 | tfu | File Added: 0017-PGP.patch | |
2016-03-17 20:52 | tfu | Note Added: 0009787 | |
2016-03-18 15:05 | st41ker | Note Added: 0009791 | |
2016-03-18 17:01 | ludovic | Note Added: 0009796 | |
2016-03-18 17:01 | ludovic | Status | new => resolved |
2016-03-18 17:01 | ludovic | Fixed in Version | => 2.3.10 |
2016-03-18 17:01 | ludovic | Resolution | open => fixed |
2016-03-18 17:01 | ludovic | Assigned To | => ludovic |