From 575600cabc57b29f3161b999389e50497307506e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Mon, 2 Mar 2015 23:36:28 +0100 Subject: [PATCH 1/5] oc-calendar: Return PidTagContainerClass for Calendar folders And it must "IPF.Appointment" as described in [MS-OXOCAL] Section 2.2.11.1 --- OpenChange/MAPIStoreCalendarFolder.m | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OpenChange/MAPIStoreCalendarFolder.m b/OpenChange/MAPIStoreCalendarFolder.m index 27ab9c3e1..5f57c0560 100644 --- a/OpenChange/MAPIStoreCalendarFolder.m +++ b/OpenChange/MAPIStoreCalendarFolder.m @@ -186,6 +186,14 @@ [(SOGoAppointmentFolder *) sogoObject aclSQLListingFilter]]; } +- (int) getPidTagContainerClass: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + *data = [@"IPF.Appointment" asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + - (int) getPidTagDefaultPostMessageClass: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { From 316ade13f84798006c3cdaf2c0fa5e884d7a29c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Mon, 2 Mar 2015 23:41:04 +0100 Subject: [PATCH 2/5] oc: Implement Sharing Message Object It acts as a proxy of MAPIStoreMailMessage and it manages the properties defined in [MS-OXSHARE] Section 2.2 by storing them in the mail message as eXtensible MIME headers which starts with X-MS-Sharing. --- OpenChange/GNUmakefile | 2 + OpenChange/MAPIStoreMailMessage.h | 1 + OpenChange/MAPIStoreMailMessage.m | 21 ++ OpenChange/MAPIStoreMailVolatileMessage.m | 89 +++++- OpenChange/MAPIStoreSharingMessage.h | 94 ++++++ OpenChange/MAPIStoreSharingMessage.m | 372 ++++++++++++++++++++++ 6 files changed, 575 insertions(+), 4 deletions(-) create mode 100644 OpenChange/MAPIStoreSharingMessage.h create mode 100644 OpenChange/MAPIStoreSharingMessage.m diff --git a/OpenChange/GNUmakefile b/OpenChange/GNUmakefile index d9eaf92a4..688ef19e1 100644 --- a/OpenChange/GNUmakefile +++ b/OpenChange/GNUmakefile @@ -110,6 +110,8 @@ $(SOGOBACKEND)_OBJC_FILES += \ \ MAPIStoreFallbackContext.m \ \ + MAPIStoreSharingMessage.m \ + \ NSArray+MAPIStore.m \ NSData+MAPIStore.m \ NSDate+MAPIStore.m \ diff --git a/OpenChange/MAPIStoreMailMessage.h b/OpenChange/MAPIStoreMailMessage.h index 6bae6647a..2f6192c16 100644 --- a/OpenChange/MAPIStoreMailMessage.h +++ b/OpenChange/MAPIStoreMailMessage.h @@ -35,6 +35,7 @@ { BOOL headerSetup; BOOL mailIsEvent; + BOOL mailIsSharingObject; NSString *mimeKey; NSString *headerCharset; NSString *headerEncoding; diff --git a/OpenChange/MAPIStoreMailMessage.m b/OpenChange/MAPIStoreMailMessage.m index 8a9bd1918..cf6e019de 100644 --- a/OpenChange/MAPIStoreMailMessage.m +++ b/OpenChange/MAPIStoreMailMessage.m @@ -51,6 +51,7 @@ #import "MAPIStoreMailFolder.h" #import "MAPIStoreMapping.h" #import "MAPIStoreSamDBUtils.h" +#import "MAPIStoreSharingMessage.h" #import "MAPIStoreTypes.h" #import "MAPIStoreUserContext.h" @@ -115,6 +116,7 @@ static Class NSExceptionK; { mimeKey = nil; mailIsEvent = NO; + mailIsSharingObject = NO; headerCharset = nil; headerEncoding = nil; headerMimeType = nil; @@ -201,9 +203,11 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) - (void) _fetchHeaderData { + MAPIStoreSharingMessage *sharingMessage; NSMutableArray *keys; NSArray *acceptedTypes; NSDictionary *messageData, *partHeaderData, *parameters; + NSString *sharingHeader; acceptedTypes = [NSArray arrayWithObjects: @"text/calendar", @"application/ics", @@ -228,6 +232,21 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) if ([headerMimeType isEqualToString: @"text/calendar"] || [headerMimeType isEqualToString: @"application/ics"]) mailIsEvent = YES; + else + { + sharingHeader = [[sogoObject mailHeaders] objectForKey: @"x-ms-sharing-localtype"]; + if (sharingHeader) + { + mailIsSharingObject = YES; + /* It is difficult to subclass this in folder class, that's why + a sharing object is a proxy in a mail message */ + sharingMessage = [[MAPIStoreSharingMessage alloc] + initWithMailHeaders: [sogoObject mailHeaders] + andConnectionInfo: [[self context] connectionInfo]]; + [self addProxy: sharingMessage]; + [sharingMessage release]; + } + } } headerSetup = YES; @@ -517,6 +536,8 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) if (mailIsEvent) [[self _appointmentWrapper] getPidTagMessageClass: data inMemCtx: memCtx]; + else if (mailIsSharingObject) + *data = talloc_strdup (memCtx, "IPM.Sharing"); else *data = talloc_strdup (memCtx, "IPM.Note"); diff --git a/OpenChange/MAPIStoreMailVolatileMessage.m b/OpenChange/MAPIStoreMailVolatileMessage.m index ed9fbf8d2..a2aac76ee 100644 --- a/OpenChange/MAPIStoreMailVolatileMessage.m +++ b/OpenChange/MAPIStoreMailVolatileMessage.m @@ -30,6 +30,7 @@ #import #import #import +#import #import #import #import @@ -42,6 +43,7 @@ #import #import #import +#import #import #import #import @@ -62,13 +64,13 @@ #import "NSData+MAPIStore.h" #import "NSObject+MAPIStore.h" #import "NSString+MAPIStore.h" -#import #import "MAPIStoreMailVolatileMessage.h" #undef DEBUG #include #include +#include static Class NSNumberK = Nil; @@ -531,6 +533,78 @@ QuoteSpecials (NSString *address) return result; } +static inline void +FillMessageHeadersFromSharingProperties (NGMutableHashMap *headers, NSDictionary *mailProperties) +{ + /* Store the *important* properties related with a sharing object as + MIME eXtension headers. See [MS-OXSHARE] Section 2.2 for details + about the properties */ + + id value; + + value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingCapabilities)]; + if (value) + [headers setObject: value + forKey: @"X-MS-Sharing-Capabilities"]; + + value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingFlavor)]; + if (value) + [headers setObject: value + forKey: @"X-MS-Sharing-Flavor"]; + + value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingInitiatorEntryId)]; + if (value) + [headers setObject: [[value stringByEncodingBase64] stringByReplacingOccurrencesOfString: @"\n" + withString: @""] + forKey: @"X-MS-Sharing-InitiatorEntryId"]; + + value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingInitiatorName)]; + if (value) + [headers setObject: value + forKey: @"X-MS-Sharing-InitiatorName"]; + + value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingInitiatorSmtp)]; + if (value) + [headers setObject: value + forKey: @"X-MS-Sharing-InitiatorSmtp"]; + + value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingLocalType)]; + if (value) + [headers setObject: value + forKey: @"X-MS-Sharing-LocalType"]; + + value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingProviderName)]; + if (value) + [headers setObject: value + forKey: @"X-MS-Sharing-ProviderName"]; + + value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingRemoteName)]; + if (value) + [headers setObject: value + forKey: @"X-MS-Sharing-RemoteName"]; + + value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingRemoteStoreUid)]; + if (value) + [headers setObject: value + forKey: @"X-MS-Sharing-RemoteStoreUid"]; + + value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingRemoteUid)]; + if (value) + [headers setObject: value + forKey: @"X-MS-Sharing-RemoteUid"]; + + value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingResponseTime)]; + if (value) + [headers setObject: value + forKey: @"X-MS-Sharing-ResponseTime"]; + + value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingResponseType)]; + if (value) + [headers setObject: value + forKey: @"X-MS-Sharing-ResponseType"]; + +} + static inline void FillMessageHeadersFromProperties (NGMutableHashMap *headers, NSDictionary *mailProperties, BOOL withBcc, @@ -538,7 +612,7 @@ FillMessageHeadersFromProperties (NGMutableHashMap *headers, { NSData *senderEntryId; NSMutableString *subject; - NSString *from, *recId, *messageId, *subjectData, *recipientsStr; + NSString *from, *recId, *messageId, *subjectData, *recipientsStr, *msgClass; NSArray *list; NSCalendarDate *date; NSDictionary *recipients; @@ -690,6 +764,13 @@ FillMessageHeadersFromProperties (NGMutableHashMap *headers, { [headers addObject: @"5 (Lowest)" forKey: @"X-Priority"]; } + + msgClass = [mailProperties objectForKey: MAPIPropertyKey (PidTagMessageClass)]; + if ([msgClass isEqualToString: @"IPM.Sharing"]) + { + FillMessageHeadersFromSharingProperties (headers, mailProperties); + } + } static NSArray * @@ -939,12 +1020,12 @@ MakeMessageBody (NSDictionary *mailProperties, NSDictionary *attachmentParts, NS id authenticator; msgClass = [properties objectForKey: MAPIPropertyKey (PidTagMessageClass)]; - if ([msgClass isEqualToString: @"IPM.Note"]) /* we skip invitation replies */ + if ([msgClass isEqualToString: @"IPM.Note"] || [msgClass isEqualToString: @"IPM.Sharing"]) /* we skip invitation replies */ { /* send mail */ messageData = [self _generateMailDataWithBcc: NO]; - + recipientEmails = [NSMutableArray arrayWithCapacity: 32]; recipients = [properties objectForKey: @"recipients"]; for (type = MAPI_ORIG; type <= MAPI_BCC; type++) diff --git a/OpenChange/MAPIStoreSharingMessage.h b/OpenChange/MAPIStoreSharingMessage.h new file mode 100644 index 000000000..9b62389a0 --- /dev/null +++ b/OpenChange/MAPIStoreSharingMessage.h @@ -0,0 +1,94 @@ +/* MAPIStoreSharingMessage.h - this file is part of SOGo-OpenChange + * + * Copyright (C) 2015 Enrique J. Hernández + * + * Author: Enrique J. Hernández + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef MAPISTORESHARINGMESSAGE_H +#define MAPISTORESHARINGMESSAGE_H + +#import "MAPIStoreObjectProxy.h" + + +@interface MAPIStoreSharingMessage : MAPIStoreObjectProxy +{ + struct mapistore_connection_info *connInfo; + NSMutableDictionary *properties; +} + +- (id) initWithMailHeaders: (NSDictionary *) mailHeaders + andConnectionInfo: (struct mapistore_connection_info *) newConnInfo; + +/* getters */ +- (int) getPidLidSharingCapabilities: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidNameXSharingCapabilities: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingConfigurationUrl: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidNameXSharingConfigUrl: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingFlavor: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidNameXSharingFlavor: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingInitiatorEntryId: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingInitiatorName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingInitiatorSmtp: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingLocalType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidNameXSharingLocalType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingProviderGuid: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidNameXSharingProviderGuid: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingProviderName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidNameXSharingProviderName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingProviderUrl: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidNameXSharingProviderUrl: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingRemoteName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidNameXSharingRemoteName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingRemoteStoreUid: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidNameXSharingRemoteStoreUid: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingRemoteType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidTypeXSharingRemoteType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingResponseTime: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidLidSharingResponseType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; +- (int) getPidNameContentClass: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx; + +@end + +#endif /* MAPISTORECALENDARWRAPPER_H */ diff --git a/OpenChange/MAPIStoreSharingMessage.m b/OpenChange/MAPIStoreSharingMessage.m new file mode 100644 index 000000000..b25db2444 --- /dev/null +++ b/OpenChange/MAPIStoreSharingMessage.m @@ -0,0 +1,372 @@ +/* MAPIStoreSharingMessage.m - this file is part of SOGo-OpenChange + * + * Copyright (C) 2015 Enrique J. Hernández + * + * Author: Enrique J. Hernández + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#import +#import + +#import + +#import "MAPIStoreTypes.h" +#import "NSData+MAPIStore.h" +#import "NSDate+MAPIStore.h" +#import "NSString+MAPIStore.h" +#import "NSValue+MAPIStore.h" + +#import "MAPIStoreSharingMessage.h" + +#include + +@implementation MAPIStoreSharingMessage + +- (id) init +{ + if ((self = [super init])) + { + connInfo = NULL; + properties = nil; + } + + return self; +} + +- (id) initWithMailHeaders: (NSDictionary *) mailHeaders + andConnectionInfo: (struct mapistore_connection_info *) newConnInfo +{ + NSEnumerator *enumerator; + NSString *key; + + if ((self = [self init])) + { + connInfo = newConnInfo; + enumerator = [mailHeaders keyEnumerator]; + properties = [NSMutableDictionary new]; + while ((key = [enumerator nextObject])) + { + if ([key hasPrefix: @"x-ms-sharing-"]) + [properties setObject: [mailHeaders objectForKey: key] + forKey: key]; + } + } + + return self; +} + +- (void) dealloc +{ + [properties release]; + [super dealloc]; +} + +- (enum mapistore_error) _getStringProperty: (NSString *) propertyName + inData: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; + id value; + + value = [properties objectForKey: propertyName]; + if (value) + { + *data = [value asUnicodeInMemCtx: memCtx]; + rc = MAPISTORE_SUCCESS; + } + + return rc; + +} + +- (int) getPidLidSharingCapabilities: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + + enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; + id value; + + value = [properties objectForKey: @"x-ms-sharing-capabilities"]; + if (value) + { + *data = MAPILongValue (memCtx, [value intValue]); + rc = MAPISTORE_SUCCESS; + } + + return rc; +} + +- (int) getPidNameXSharingCapabilities: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + + enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; + id value; + + value = [properties objectForKey: @"x-ms-sharing-capabilities"]; + if (value) + { + *data = [[value stringValue] asUnicodeInMemCtx: memCtx]; + rc = MAPISTORE_SUCCESS; + } + + return rc; +} + +- (int) getPidLidSharingConfigurationUrl: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + + *data = [@"" asUnicodeInMemCtx: memCtx]; + return MAPISTORE_SUCCESS; +} + +- (int) getPidNameXSharingConfigUrl: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getPidLidSharingConfigurationUrl: data inMemCtx: memCtx]; +} + +- (int) getPidLidSharingFlavor: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; + id value; + + value = [properties objectForKey: @"x-ms-sharing-flavor"]; + if (value) + { + *data = MAPILongValue (memCtx, [value intValue]); + rc = MAPISTORE_SUCCESS; + } + + return rc; +} + +- (int) getPidNameXSharingFlavor: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; + id value; + + value = [properties objectForKey: @"x-ms-sharing-flavor"]; + if (value) + { + *data = [[value stringValue] asUnicodeInMemCtx: memCtx]; + rc = MAPISTORE_SUCCESS; + } + + return rc; +} + +- (int) getPidLidSharingInitiatorEntryId: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; + id value; + NSData *entryId; + + value = [properties objectForKey: @"x-ms-sharing-initiatorentryid"]; + if (value) + { + entryId = [value dataByDecodingBase64]; + if (entryId) + { + *data = [entryId asBinaryInMemCtx: memCtx]; + rc = MAPISTORE_SUCCESS; + } + } + + return rc; +} + +- (int) getPidLidSharingInitiatorName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getStringProperty: @"x-ms-sharing-initiatorname" + inData: data + inMemCtx: memCtx]; +} + +- (int) getPidLidSharingInitiatorSmtp: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getStringProperty: @"x-ms-sharing-initiatorsmtp" + inData: data + inMemCtx: memCtx]; +} + +- (int) getPidLidSharingLocalType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getStringProperty: @"x-ms-sharing-localtype" + inData: data + inMemCtx: memCtx]; +} + +- (int) getPidNameXSharingLocalType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getPidLidSharingLocalType: data inMemCtx: memCtx]; +} + +- (int) getPidLidSharingProviderGuid: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + const unsigned char providerGuidBytes[] = {0xAE, 0xF0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}; + NSData *providerGuid = [NSData dataWithBytes: providerGuidBytes length: 16]; + *data = [providerGuid asBinaryInMemCtx: memCtx]; + return MAPISTORE_SUCCESS; +} + +- (int) getPidNameXSharingProviderGuid: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + *data = [@"AEF0060000000000C000000000000046" asUnicodeInMemCtx: memCtx]; + return MAPISTORE_SUCCESS; +} + +- (int) getPidLidSharingProviderName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + + return [self _getStringProperty: @"x-ms-sharing-providername" + inData: data + inMemCtx: memCtx]; +} + +- (int) getPidNameXSharingProviderName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getPidLidSharingProviderName: data inMemCtx: memCtx]; +} + +- (int) getPidLidSharingProviderUrl: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getStringProperty: @"x-ms-sharing-providerurl" + inData: data + inMemCtx: memCtx]; +} + +- (int) getPidNameXSharingProviderUrl: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getPidLidSharingProviderUrl: data inMemCtx: memCtx]; +} + +- (int) getPidLidSharingRemoteName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getStringProperty: @"x-ms-sharing-remotename" + inData: data + inMemCtx: memCtx]; +} + +- (int) getPidNameXSharingRemoteName: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getPidLidSharingRemoteName: data inMemCtx: memCtx]; +} + +- (int) getPidLidSharingRemoteStoreUid: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getStringProperty: @"x-ms-sharing-remotestoreuid" + inData: data + inMemCtx: memCtx]; +} + +- (int) getPidNameXSharingRemoteStoreUid: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getPidLidSharingRemoteStoreUid: data inMemCtx: memCtx]; +} + +- (int) getPidLidSharingRemoteType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getStringProperty: @"x-ms-sharing-remotetype" + inData: data + inMemCtx: memCtx]; +} + +- (int) getPidTypeXSharingRemoteType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getPidLidSharingRemoteType: data inMemCtx: memCtx]; +} + +- (int) getPidLidSharingRemoteUid: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self _getStringProperty: @"x-ms-sharing-remoteuid" + inData: data + inMemCtx: memCtx]; +} + +- (int) getPidUidXSharingRemoteUid: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + return [self getPidLidSharingRemoteUid: data inMemCtx: memCtx]; +} + +- (int) getPidLidSharingResponseTime: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; + id value; + + value = [properties objectForKey: @"x-ms-sharing-responsetime"]; + if (value) + { + *data = [value asFileTimeInMemCtx: memCtx]; + rc = MAPISTORE_SUCCESS; + } + + return rc; +} + +- (int) getPidLidSharingResponseType: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + + enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; + id value; + + value = [properties objectForKey: @"x-ms-sharing-responsetype"]; + if (value) + { + *data = MAPILongValue (memCtx, [value intValue]); + rc = MAPISTORE_SUCCESS; + } + + return rc; +} + +- (int) getPidNameContentClass: (void **) data + inMemCtx: (TALLOC_CTX *) memCtx +{ + *data = talloc_strdup (memCtx, "Sharing"); + return MAPISTORE_SUCCESS; +} + +@end From 6af8b486df521274082f312e57614c0e88b68e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Tue, 3 Mar 2015 00:08:34 +0100 Subject: [PATCH 3/5] oc-mail: Return special properties on sharing_metadata.xml attachment As required by [MS-OXWSMSHR] Section 3.1.1 to display the share object message correctly and be able to open the shared calendar directly from the message. --- NEWS | 1 + OpenChange/MAPIStoreMailAttachment.m | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index cf81a2201..1562d099d 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ master ------ Enhancements + - Give support to calendar sharing invitations - Missing contact fields are now saved and available when sharing it (Office, Profession, Manager's name, Assistant's name, Spouse/Partner, Anniversary) - Appointment color and importance work now between Outlooks diff --git a/OpenChange/MAPIStoreMailAttachment.m b/OpenChange/MAPIStoreMailAttachment.m index e21fc7925..388ad924d 100644 --- a/OpenChange/MAPIStoreMailAttachment.m +++ b/OpenChange/MAPIStoreMailAttachment.m @@ -163,8 +163,15 @@ - (int) getPidTagDisplayName: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { - *data = [[bodyInfo objectForKey: @"description"] - asUnicodeInMemCtx: memCtx]; + NSString *fileName; + + fileName = [self _fileName]; + if ([fileName isEqualToString: @"sharing_metadata.xml"]) + /* Required to disallow user from seeing the attachment by default */ + *data = [@"sharing_metadata.xml" asUnicodeInMemCtx: memCtx]; + else + *data = [[bodyInfo objectForKey: @"description"] + asUnicodeInMemCtx: memCtx]; return MAPISTORE_SUCCESS; } @@ -181,11 +188,17 @@ - (int) getPidTagAttachMimeTag: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { - NSString *mimeTag; + NSString *mimeTag, *fileName; + + fileName = [self _fileName]; + if ([fileName isEqualToString: @"sharing_metadata.xml"]) + /* Required by [MS-OXWSMSHR] Section 3.1.1 */ + mimeTag = [NSString stringWithFormat: @"application/x-sharing-metadata-xml"]; + else + mimeTag = [NSString stringWithFormat: @"%@/%@", + [bodyInfo objectForKey: @"type"], + [bodyInfo objectForKey: @"subtype"]]; - mimeTag = [NSString stringWithFormat: @"%@/%@", - [bodyInfo objectForKey: @"type"], - [bodyInfo objectForKey: @"subtype"]]; *data = [[mimeTag lowercaseString] asUnicodeInMemCtx: memCtx]; return MAPISTORE_SUCCESS; From ae7ac1be296ab362ac98c55345c66811ce591f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Thu, 5 Mar 2015 00:02:19 +0100 Subject: [PATCH 4/5] oc-mail: Return sharing properties on sharing object mail message When it is asked for available properties for an specific message. --- OpenChange/MAPIStoreMailMessage.m | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/OpenChange/MAPIStoreMailMessage.m b/OpenChange/MAPIStoreMailMessage.m index cf6e019de..156d7e558 100644 --- a/OpenChange/MAPIStoreMailMessage.m +++ b/OpenChange/MAPIStoreMailMessage.m @@ -154,6 +154,30 @@ static Class NSExceptionK; return [sogoObject date]; } +- (enum mapistore_error) getAvailableProperties: (struct SPropTagArray **) propertiesP + inMemCtx: (TALLOC_CTX *) memCtx +{ + BOOL listedProperties[65536]; + NSUInteger count; + uint16_t propId; + + if (mailIsSharingObject) + { + memset (listedProperties, NO, 65536 * sizeof (BOOL)); + [super getAvailableProperties: propertiesP inMemCtx: memCtx]; + for (count = 0; count < (*propertiesP)->cValues; count++) + { + propId = ((*propertiesP)->aulPropTag[count] >> 16) & 0xffff; + listedProperties[propId] = YES; + } + [MAPIStoreSharingMessage fillAvailableProperties: *propertiesP + withExclusions: listedProperties]; + return MAPISTORE_SUCCESS; + } + else + return [super getAvailableProperties: propertiesP inMemCtx: memCtx]; +} + static NSComparisonResult _compareBodyKeysByPriority (id entry1, id entry2, void *data) { From 2b54897d29cf6beeadd602acb4620229858623d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Thu, 5 Mar 2015 00:05:02 +0100 Subject: [PATCH 5/5] oc-sharing: Guess PidLidSharingFlavor from other props When it is not set by the client on the first place. See [MS-OXSHARE] Section 2.2.2.5 for details on returned values. --- OpenChange/MAPIStoreSharingMessage.m | 35 +++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/OpenChange/MAPIStoreSharingMessage.m b/OpenChange/MAPIStoreSharingMessage.m index b25db2444..594863e0e 100644 --- a/OpenChange/MAPIStoreSharingMessage.m +++ b/OpenChange/MAPIStoreSharingMessage.m @@ -147,8 +147,9 @@ - (int) getPidLidSharingFlavor: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { + /* See [MS-OXSHARE] Section 2.2.2.5 for details */ enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; - id value; + id value, auxValue; value = [properties objectForKey: @"x-ms-sharing-flavor"]; if (value) @@ -156,6 +157,38 @@ *data = MAPILongValue (memCtx, [value intValue]); rc = MAPISTORE_SUCCESS; } + else + { + /* Guess its value required by old clients based on other properties */ + value = [properties objectForKey: @"x-ms-sharing-capabilities"]; + if (value) + { + if ([value intValue] == 0x40290) /* Special folder */ + { + value = [properties objectForKey: @"x-ms-sharing-responsetime"]; + auxValue = [properties objectForKey: @"x-ms-sharing-remotename"]; + if (value) /* A sharing request */ + { + if (auxValue) + *data = MAPILongValue (memCtx, 0x20710); + else + *data = MAPILongValue (memCtx, 0x20500); + } + else + { + if (auxValue) /* It SHOULD be an invitation or response acceptance */ + *data = MAPILongValue (memCtx, 0x20310); + else + *data = MAPILongValue (memCtx, 0x23310); + } + } + else + { + *data = MAPILongValue (memCtx, 0x310); + } + rc = MAPISTORE_SUCCESS; + } + } return rc; }