merge default IOS-1675
authorDirk Zimmermann <dz@pep.security>
Mon, 23 Sep 2019 08:57:17 +0200
branchIOS-1675
changeset 1273780a91298a4c
parent 1163 150f7d3e3da1
parent 1234 4e7e5af6608d
child 1432 7ac69ce22f27
merge default
pEpObjCAdapter.xcodeproj/project.pbxproj
pEpObjCTests/PEPSessionTest.m
     1.1 --- a/pEpObjCAdapter.xcodeproj/project.pbxproj	Fri Aug 09 16:29:40 2019 +0200
     1.2 +++ b/pEpObjCAdapter.xcodeproj/project.pbxproj	Mon Sep 23 08:57:17 2019 +0200
     1.3 @@ -61,6 +61,8 @@
     1.4  		437BEA9122328E570051E3A1 /* pEpTrustWords.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 64AE6B211BE15E3A000867E4 /* pEpTrustWords.bundle */; };
     1.5  		4396CEB82187196600FDD398 /* PEPSessionTestNotifyHandshakeDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4396CEB62187190F00FDD398 /* PEPSessionTestNotifyHandshakeDelegate.m */; };
     1.6  		4396CECB2187220200FDD398 /* PEPSessionTestSendMessageDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4396CEC8218721F900FDD398 /* PEPSessionTestSendMessageDelegate.m */; };
     1.7 +		43AD0E3022E99ECE00D46F56 /* PEPInternalConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 43AD0E2E22E99ECE00D46F56 /* PEPInternalConstants.h */; };
     1.8 +		43AD0E3122E99ECE00D46F56 /* PEPInternalConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 43AD0E2F22E99ECE00D46F56 /* PEPInternalConstants.m */; };
     1.9  		43BCEFF7222FBA2400148303 /* NSDictionary+CommType.h in Headers */ = {isa = PBXBuildFile; fileRef = 43D27DE41F5DA78700795687 /* NSDictionary+CommType.h */; settings = {ATTRIBUTES = (Public, ); }; };
    1.10  		43E02A201C71F65B008F05E9 /* A3FC7F0A_sec.asc in Resources */ = {isa = PBXBuildFile; fileRef = 43E02A1C1C71F65B008F05E9 /* A3FC7F0A_sec.asc */; };
    1.11  		43E02A211C71F65B008F05E9 /* A3FC7F0A.asc in Resources */ = {isa = PBXBuildFile; fileRef = 43E02A1D1C71F65B008F05E9 /* A3FC7F0A.asc */; };
    1.12 @@ -194,6 +196,8 @@
    1.13  		4396CEC9218721F900FDD398 /* PEPSessionTestSendMessageDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PEPSessionTestSendMessageDelegate.h; sourceTree = "<group>"; };
    1.14  		439D91A3208479EE003F6AC2 /* PEPAttachment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PEPAttachment.h; sourceTree = "<group>"; };
    1.15  		439D91A4208479EE003F6AC2 /* PEPAttachment.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PEPAttachment.m; sourceTree = "<group>"; };
    1.16 +		43AD0E2E22E99ECE00D46F56 /* PEPInternalConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PEPInternalConstants.h; sourceTree = "<group>"; };
    1.17 +		43AD0E2F22E99ECE00D46F56 /* PEPInternalConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PEPInternalConstants.m; sourceTree = "<group>"; };
    1.18  		43D27DE41F5DA78700795687 /* NSDictionary+CommType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+CommType.h"; sourceTree = "<group>"; };
    1.19  		43D27DE51F5DA7B700795687 /* NSDictionary+CommType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+CommType.m"; sourceTree = "<group>"; };
    1.20  		43DED784203C25E200D45CD6 /* NSError+PEP.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSError+PEP.h"; sourceTree = "<group>"; };
    1.21 @@ -350,6 +354,8 @@
    1.22  				439393F7208F5B5E00EB1DBD /* NSMutableDictionary+PEP.m */,
    1.23  				43F73BE92166248E00AB4524 /* PEPSync.m */,
    1.24  				430CD9BF2292B1EA00AAC37F /* PEPSync_Internal.h */,
    1.25 +				43AD0E2E22E99ECE00D46F56 /* PEPInternalConstants.h */,
    1.26 +				43AD0E2F22E99ECE00D46F56 /* PEPInternalConstants.m */,
    1.27  			);
    1.28  			path = pEpObjCAdapter;
    1.29  			sourceTree = "<group>";
    1.30 @@ -425,6 +431,7 @@
    1.31  				435C0C9922292C080025C6B5 /* PEPMessage.h in Headers */,
    1.32  				435C0CA222292E7C0025C6B5 /* PEPTypes.h in Headers */,
    1.33  				435F5164222045FB006EB11F /* PEPIdentity.h in Headers */,
    1.34 +				43AD0E3022E99ECE00D46F56 /* PEPInternalConstants.h in Headers */,
    1.35  				430CD9B62292ADAC00AAC37F /* PEPSendMessageDelegate.h in Headers */,
    1.36  				43E3985F221D7E56008E7983 /* PEPObjCAdapterFramework.h in Headers */,
    1.37  				435C0C8C22291FFB0025C6B5 /* PEPSession.h in Headers */,
    1.38 @@ -631,6 +638,7 @@
    1.39  				435F517A222046C2006EB11F /* NSObject+Extension.m in Sources */,
    1.40  				435F517D222046C2006EB11F /* PEPSync.m in Sources */,
    1.41  				435F516D222046C2006EB11F /* PEPQueue.m in Sources */,
    1.42 +				43AD0E3122E99ECE00D46F56 /* PEPInternalConstants.m in Sources */,
    1.43  			);
    1.44  			runOnlyForDeploymentPostprocessing = 0;
    1.45  		};
     2.1 --- a/pEpObjCAdapter/PEPIdentity.m	Fri Aug 09 16:29:40 2019 +0200
     2.2 +++ b/pEpObjCAdapter/PEPIdentity.m	Mon Sep 23 08:57:17 2019 +0200
     2.3 @@ -200,6 +200,24 @@
     2.4      self.isOwn = NO;
     2.5  }
     2.6  
     2.7 +- (BOOL)enableKeySync:(NSError * _Nullable * _Nullable)error
     2.8 +{
     2.9 +    PEPSession *session = [PEPSession new];
    2.10 +    return [session enableSyncForIdentity:self error:error];
    2.11 +}
    2.12 +
    2.13 +- (BOOL)disableKeySync:(NSError * _Nullable * _Nullable)error
    2.14 +{
    2.15 +    PEPSession *session = [PEPSession new];
    2.16 +    return [session disableSyncForIdentity:self error:error];
    2.17 +}
    2.18 +
    2.19 +- (NSNumber * _Nullable)queryKeySyncEnabled:(NSError * _Nullable * _Nullable)error
    2.20 +{
    2.21 +    PEPSession *session = [PEPSession new];
    2.22 +    return [session queryKeySyncEnabledForIdentity:self error:error];
    2.23 +}
    2.24 +
    2.25  // MARK: - NSDictionary - Helpers
    2.26  
    2.27  - (NSArray<NSArray<NSString *> *> *)keyValuePairs
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/pEpObjCAdapter/PEPInternalConstants.h	Mon Sep 23 08:57:17 2019 +0200
     3.3 @@ -0,0 +1,20 @@
     3.4 +//
     3.5 +//  PEPInternalConstants.h
     3.6 +//  PEPObjCAdapterFramework
     3.7 +//
     3.8 +//  Created by Dirk Zimmermann on 25.07.19.
     3.9 +//  Copyright © 2019 p≡p. All rights reserved.
    3.10 +//
    3.11 +
    3.12 +#import <Foundation/Foundation.h>
    3.13 +
    3.14 +NS_ASSUME_NONNULL_BEGIN
    3.15 +
    3.16 +@interface PEPInternalConstants : NSObject
    3.17 +
    3.18 +/** Constant for the string undefined */
    3.19 +extern NSString *const _Nonnull kUndefined;
    3.20 +
    3.21 +@end
    3.22 +
    3.23 +NS_ASSUME_NONNULL_END
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/pEpObjCAdapter/PEPInternalConstants.m	Mon Sep 23 08:57:17 2019 +0200
     4.3 @@ -0,0 +1,15 @@
     4.4 +//
     4.5 +//  PEPInternalConstants.m
     4.6 +//  PEPObjCAdapterFramework
     4.7 +//
     4.8 +//  Created by Dirk Zimmermann on 25.07.19.
     4.9 +//  Copyright © 2019 p≡p. All rights reserved.
    4.10 +//
    4.11 +
    4.12 +#import "PEPInternalConstants.h"
    4.13 +
    4.14 +@implementation PEPInternalConstants
    4.15 +
    4.16 +NSString *const kUndefined = @"undefined";
    4.17 +
    4.18 +@end
     5.1 --- a/pEpObjCAdapter/PEPInternalSession.h	Fri Aug 09 16:29:40 2019 +0200
     5.2 +++ b/pEpObjCAdapter/PEPInternalSession.h	Mon Sep 23 08:57:17 2019 +0200
     5.3 @@ -27,6 +27,8 @@
     5.4  
     5.5  @property (nonatomic) PEP_SESSION _Nullable session;
     5.6  
     5.7 +- (_Nullable instancetype)init;
     5.8 +
     5.9  /**
    5.10   Configures the session's unecryptedSubjectEnabled value.
    5.11  
     6.1 --- a/pEpObjCAdapter/PEPInternalSession.m	Fri Aug 09 16:29:40 2019 +0200
     6.2 +++ b/pEpObjCAdapter/PEPInternalSession.m	Mon Sep 23 08:57:17 2019 +0200
     6.3 @@ -25,12 +25,13 @@
     6.4  #import "NSNumber+PEPRating.h"
     6.5  #import "NSMutableDictionary+PEP.h"
     6.6  #import "PEPSync_Internal.h"
     6.7 +#import "PEPInternalConstants.h"
     6.8  
     6.9  #import "key_reset.h"
    6.10  
    6.11  @implementation PEPInternalSession
    6.12  
    6.13 -- (instancetype)init
    6.14 +- (_Nullable instancetype)init
    6.15  {
    6.16      self = [super init];
    6.17      if (self) {
    6.18 @@ -48,7 +49,9 @@
    6.19  
    6.20  - (void)dealloc
    6.21  {
    6.22 -    release(_session);
    6.23 +    if (_session != nil) {
    6.24 +        release(_session);
    6.25 +    }
    6.26  }
    6.27  
    6.28  #pragma mark - CONFIG
    6.29 @@ -466,9 +469,7 @@
    6.30      message *_msg = PEP_messageToStruct(theMessage);
    6.31      PEPRating rating = PEPRatingUndefined;
    6.32  
    6.33 -    PEPStatus status = (PEPStatus) outgoing_message_rating(_session,
    6.34 -                                                           _msg,
    6.35 -                                                           (PEP_rating *) &rating);
    6.36 +    PEPStatus status = (PEPStatus) ratingFunction(_session, _msg, (PEP_rating *) &rating);
    6.37  
    6.38      free_message(_msg);
    6.39  
    6.40 @@ -645,6 +646,78 @@
    6.41      return YES;
    6.42  }
    6.43  
    6.44 +- (BOOL)enableSyncForIdentity:(PEPIdentity * _Nonnull)identity
    6.45 +                        error:(NSError * _Nullable * _Nullable)error
    6.46 +{
    6.47 +    if (!identity.isOwn) {
    6.48 +        [NSError setError:error fromPEPStatus:PEPStatusIllegalValue];
    6.49 +        return NO;
    6.50 +    }
    6.51 +
    6.52 +    pEp_identity *ident = PEP_identityToStruct(identity);
    6.53 +
    6.54 +    PEPStatus status = (PEPStatus) enable_identity_for_sync(_session, ident);
    6.55 +
    6.56 +    if ([NSError setError:error fromPEPStatus:status]) {
    6.57 +        free_identity(ident);
    6.58 +        return NO;
    6.59 +    }
    6.60 +
    6.61 +    free_identity(ident);
    6.62 +
    6.63 +    return YES;
    6.64 +}
    6.65 +
    6.66 +- (BOOL)disableSyncForIdentity:(PEPIdentity * _Nonnull)identity
    6.67 +                         error:(NSError * _Nullable * _Nullable)error
    6.68 +{
    6.69 +    if (!identity.isOwn) {
    6.70 +        [NSError setError:error fromPEPStatus:PEPStatusIllegalValue];
    6.71 +        return NO;
    6.72 +    }
    6.73 +
    6.74 +    pEp_identity *ident = PEP_identityToStruct(identity);
    6.75 +
    6.76 +    PEPStatus status = (PEPStatus) disable_identity_for_sync(_session, ident);
    6.77 +
    6.78 +    if ([NSError setError:error fromPEPStatus:status]) {
    6.79 +        free_identity(ident);
    6.80 +        return NO;
    6.81 +    }
    6.82 +
    6.83 +    free_identity(ident);
    6.84 +
    6.85 +    return YES;
    6.86 +}
    6.87 +
    6.88 +- (NSNumber * _Nullable)queryKeySyncEnabledForIdentity:(PEPIdentity * _Nonnull)identity
    6.89 +                                                 error:(NSError * _Nullable * _Nullable)error
    6.90 +{
    6.91 +    pEp_identity *ident = PEP_identityToStruct(identity);
    6.92 +
    6.93 +    if (!identity.isOwn) {
    6.94 +        [NSError setError:error fromPEPStatus:PEPStatusIllegalValue];
    6.95 +        return nil;
    6.96 +    }
    6.97 +
    6.98 +    PEPStatus status = (PEPStatus) myself(_session, ident);
    6.99 +
   6.100 +    if ([NSError setError:error fromPEPStatus:status]) {
   6.101 +        free_identity(ident);
   6.102 +        return nil;
   6.103 +    }
   6.104 +
   6.105 +    identity_flags_t flags = ident->flags;
   6.106 +
   6.107 +    free_identity(ident);
   6.108 +
   6.109 +    if (flags & PEP_idf_not_for_sync) {
   6.110 +        return [NSNumber numberWithBool:NO];
   6.111 +    } else {
   6.112 +        return [NSNumber numberWithBool:YES];
   6.113 +    }
   6.114 +}
   6.115 +
   6.116  - (NSArray<PEPIdentity *> * _Nullable)importKey:(NSString * _Nonnull)keydata
   6.117                                            error:(NSError * _Nullable * _Nullable)error
   6.118  {
   6.119 @@ -822,7 +895,7 @@
   6.120        [NSNumber numberWithInteger:PEPRatingMistrust]: @"mistrust",
   6.121        [NSNumber numberWithInteger:PEPRatingB0rken]: @"b0rken",
   6.122        [NSNumber numberWithInteger:PEPRatingUnderAttack]: @"under_attack",
   6.123 -      [NSNumber numberWithInteger:PEPRatingUndefined]: @"undefined",
   6.124 +      [NSNumber numberWithInteger:PEPRatingUndefined]: kUndefined,
   6.125        };
   6.126      NSMutableDictionary *stringToRatingMutable = [NSMutableDictionary
   6.127                                                    dictionaryWithCapacity:
   6.128 @@ -851,7 +924,7 @@
   6.129      if (stringRating) {
   6.130          return stringRating;
   6.131      } else {
   6.132 -        return @"undefined";
   6.133 +        return kUndefined;
   6.134      }
   6.135  }
   6.136  
     7.1 --- a/pEpObjCAdapter/PEPObjCAdapter.m	Fri Aug 09 16:29:40 2019 +0200
     7.2 +++ b/pEpObjCAdapter/PEPObjCAdapter.m	Mon Sep 23 08:57:17 2019 +0200
     7.3 @@ -19,7 +19,11 @@
     7.4  
     7.5  const PEP_decrypt_flags PEP_decrypt_flag_none = 0x0;
     7.6  
     7.7 -const char* _Nullable SystemDB = NULL;
     7.8 +#if TARGET_OS_IPHONE
     7.9 +// marked for iOS to think about what we want on macOS
    7.10 +const char* _Nullable perMachineDirectory = NULL;
    7.11 +#endif
    7.12 +
    7.13  NSURL *s_homeURL;
    7.14  
    7.15  static BOOL s_unEncryptedSubjectEnabled = NO;
    7.16 @@ -56,7 +60,12 @@
    7.17  + (void)initialize
    7.18  {
    7.19      s_homeURL = [self createApplicationDirectory];
    7.20 -    [self setHomeDirectory:s_homeURL]; // Important, defines $HOME and $TEMP for the engine
    7.21 +
    7.22 +    // The engine will put its per_user_directory under this directory.
    7.23 +    setenv("HOME", [[s_homeURL path] cStringUsingEncoding:NSUTF8StringEncoding], 1);
    7.24 +
    7.25 +    // This sets the engine's per_machine_directory under iOS.
    7.26 +    [self setPerMachineDirectory:s_homeURL];
    7.27  }
    7.28  
    7.29  + (NSURL *)homeURL
    7.30 @@ -64,6 +73,18 @@
    7.31      return s_homeURL;
    7.32  }
    7.33  
    7.34 +/**
    7.35 + Looks up the application support directory and creates an app-specific subdirectory under it.
    7.36 +
    7.37 + Directories derived from it:
    7.38 +
    7.39 + * $HOME (the engine uses that).
    7.40 + * The engine's per_user_directory (which is placed under $HOME).
    7.41 + * The engine's per_machine_directory (for iOS).
    7.42 +
    7.43 + @return A URL pointing to as app-specific directory under the OS defined
    7.44 +         application support directory for the current user.
    7.45 + */
    7.46  + (NSURL *)createApplicationDirectory
    7.47  {
    7.48      NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier];
    7.49 @@ -98,14 +119,22 @@
    7.50      return dirPath;
    7.51  }
    7.52  
    7.53 -+ (void)setHomeDirectory:(NSURL *)homeDir
    7.54 +/**
    7.55 + Sets the directory that will be fed into the engine's per_machine_directory.
    7.56 +
    7.57 + Does not handle macOS. For macOS, either PER_MACHINE_DIRECTORY has to be defined
    7.58 + (if constant), or this method has to be extended to handle it.
    7.59 +
    7.60 + @param perMachineDir The url to use as the per_machine_directory directory.
    7.61 + */
    7.62 ++ (void)setPerMachineDirectory:(NSURL *)perMachineDir
    7.63  {
    7.64 -    // create and set home directory
    7.65 -    setenv("HOME", [[homeDir path] cStringUsingEncoding:NSUTF8StringEncoding], 1);
    7.66 -    
    7.67 -    // create and set temp directory
    7.68 -    NSURL *tmpDirUrl = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
    7.69 -    setenv("TEMP", [[tmpDirUrl path] cStringUsingEncoding:NSUTF8StringEncoding], 1);
    7.70 +#if TARGET_OS_IPHONE
    7.71 +    if (perMachineDirectory) {
    7.72 +        free((void *) perMachineDirectory);
    7.73 +    }
    7.74 +    perMachineDirectory = strdup([perMachineDir path].UTF8String);
    7.75 +#endif
    7.76  }
    7.77  
    7.78  + (NSString *)getBundlePathFor: (NSString *) filename
    7.79 @@ -113,25 +142,24 @@
    7.80      return nil;
    7.81  }
    7.82  
    7.83 -+ (NSString *)copyAssetsIntoDocumentsDirectory:(NSBundle *)rootBundle
    7.84 ++ (void)copyAssetsIntoDocumentsDirectory:(NSBundle *)rootBundle
    7.85                                      bundleName:(NSString *)bundleName
    7.86                                        fileName:(NSString *)fileName {
    7.87 +
    7.88 +    NSString *systemDir = [NSString stringWithUTF8String:perMachineDirectory];
    7.89      
    7.90 -    NSURL *homeUrl = s_homeURL;
    7.91 -    NSString *documentsDirectory = [homeUrl path];
    7.92 -    
    7.93 -    if(!(documentsDirectory && bundleName && fileName))
    7.94 -        return nil;
    7.95 +    if(!(systemDir && bundleName && fileName))
    7.96 +        return;
    7.97      
    7.98      // Check if the database file exists in the documents directory.
    7.99 -    NSString *destinationPath = [documentsDirectory stringByAppendingPathComponent:fileName];
   7.100 +    NSString *destinationPath = [systemDir stringByAppendingPathComponent:fileName];
   7.101      if (![[NSFileManager defaultManager] fileExistsAtPath:destinationPath]) {
   7.102          // The file does not exist in the documents directory, so copy it from bundle now.
   7.103          NSBundle *bundleObj = [NSBundle bundleWithPath:
   7.104                                 [[rootBundle resourcePath]
   7.105                                  stringByAppendingPathComponent: bundleName]];
   7.106          if (!bundleObj)
   7.107 -            return nil;
   7.108 +            return;
   7.109          
   7.110          NSString *sourcePath =[[bundleObj resourcePath] stringByAppendingPathComponent: fileName];
   7.111          
   7.112 @@ -142,21 +170,18 @@
   7.113          // Check if any error occurred during copying and display it.
   7.114          if (error != nil) {
   7.115              NSLog(@"%@", [error localizedDescription]);
   7.116 -            return nil;
   7.117          }
   7.118      }
   7.119 -    return destinationPath;
   7.120  }
   7.121  
   7.122 -+ (void)setupTrustWordsDB:(NSBundle *)rootBundle{
   7.123 -    NSString *systemDBPath = [PEPObjCAdapter
   7.124 -                              copyAssetsIntoDocumentsDirectory:rootBundle
   7.125 -                              bundleName:@"pEpTrustWords.bundle"
   7.126 -                              fileName:@"system.db"];
   7.127 -    if (SystemDB) {
   7.128 -        free((void *) SystemDB);
   7.129 -    }
   7.130 -    SystemDB = strdup(systemDBPath.UTF8String);
   7.131 ++ (void)setupTrustWordsDB:(NSBundle *)rootBundle {
   7.132 +// iOS to force us to think about macOS
   7.133 +#if TARGET_OS_IPHONE
   7.134 +    [PEPObjCAdapter copyAssetsIntoDocumentsDirectory:rootBundle
   7.135 +                                          bundleName:@"pEpTrustWords.bundle"
   7.136 +                                            fileName:@"system.db"];
   7.137 +
   7.138 +#endif
   7.139  }
   7.140  
   7.141  + (void)setupTrustWordsDB
   7.142 @@ -164,4 +189,15 @@
   7.143      [PEPObjCAdapter setupTrustWordsDB:[NSBundle mainBundle]];
   7.144  }
   7.145  
   7.146 +
   7.147 ++ (NSString * _Nonnull)perUserDirectoryString
   7.148 +{
   7.149 +    return [NSString stringWithCString:per_user_directory() encoding:NSUTF8StringEncoding];
   7.150 +}
   7.151 +
   7.152 ++ (NSString * _Nonnull)perMachineDirectoryString
   7.153 +{
   7.154 +    return [NSString stringWithCString:per_machine_directory() encoding:NSUTF8StringEncoding];
   7.155 +}
   7.156 +
   7.157  @end
     8.1 --- a/pEpObjCAdapter/PEPSession.m	Fri Aug 09 16:29:40 2019 +0200
     8.2 +++ b/pEpObjCAdapter/PEPSession.m	Mon Sep 23 08:57:17 2019 +0200
     8.3 @@ -14,9 +14,26 @@
     8.4  
     8.5  #import "PEPMessageUtil.h"
     8.6  #import "NSNumber+PEPRating.h"
     8.7 +#import "NSError+PEP+Internal.h"
     8.8 +#import "PEPInternalConstants.h"
     8.9  
    8.10  @implementation PEPSession
    8.11  
    8.12 +/**
    8.13 + Macro for causing a return if the given session is nil, optionally setting an error.
    8.14 +
    8.15 + @param session A session object that will be checked for being nil or not.
    8.16 + @param error If non-nil, will receive PEP_UNKNOWN_ERROR when the session is nil.
    8.17 + @param what The value to return in case of an error (session is nil).
    8.18 + */
    8.19 +#define RETURN_ON_ERROR(session, error, what)\
    8.20 +  if (session == nil) { \
    8.21 +    if (error != nil) { \
    8.22 +      *error = [NSError errorWithPEPStatusInternal:PEP_UNKNOWN_ERROR]; \
    8.23 +      return what; \
    8.24 +    } \
    8.25 +  }
    8.26 +
    8.27  #pragma mark - Public API
    8.28  
    8.29  + (void)cleanup
    8.30 @@ -32,6 +49,7 @@
    8.31                                      error:(NSError * _Nullable * _Nullable)error
    8.32  {
    8.33      PEPInternalSession *session = [PEPSessionProvider session];
    8.34 +    RETURN_ON_ERROR(session, error, nil);
    8.35      return [session
    8.36              decryptMessageDict:messageDict
    8.37              flags:flags
    8.38 @@ -49,6 +67,7 @@
    8.39                                     error:(NSError * _Nullable * _Nullable)error
    8.40  {
    8.41      PEPInternalSession *session = [PEPSessionProvider session];
    8.42 +    RETURN_ON_ERROR(session, error, nil);
    8.43      return [session
    8.44              decryptMessage:message
    8.45              flags:flags
    8.46 @@ -65,6 +84,7 @@
    8.47                          error:(NSError * _Nullable * _Nullable)error
    8.48  {
    8.49      PEPInternalSession *session = [PEPSessionProvider session];
    8.50 +    RETURN_ON_ERROR(session, error, NO);
    8.51      return [session reEvaluateMessageDict:messageDict
    8.52                                   xKeyList:xKeyList
    8.53                                     rating:rating
    8.54 @@ -79,6 +99,7 @@
    8.55                      error:(NSError * _Nullable * _Nullable)error
    8.56  {
    8.57      PEPInternalSession *session = [PEPSessionProvider session];
    8.58 +    RETURN_ON_ERROR(session, error, NO);
    8.59      return [session reEvaluateMessage:message
    8.60                               xKeyList:xKeyList
    8.61                                 rating:rating
    8.62 @@ -93,6 +114,7 @@
    8.63                                      error:(NSError * _Nullable * _Nullable)error
    8.64  {
    8.65      PEPInternalSession *session = [PEPSessionProvider session];
    8.66 +    RETURN_ON_ERROR(session, error, nil);
    8.67      return [session
    8.68              encryptMessageDict:messageDict
    8.69              extraKeys:extraKeys
    8.70 @@ -108,6 +130,7 @@
    8.71                                     error:(NSError * _Nullable * _Nullable)error
    8.72  {
    8.73      PEPInternalSession *session = [PEPSessionProvider session];
    8.74 +    RETURN_ON_ERROR(session, error, nil);
    8.75      return [session
    8.76              encryptMessage:message
    8.77              extraKeys:extraKeys
    8.78 @@ -122,6 +145,7 @@
    8.79                                     error:(NSError * _Nullable * _Nullable)error
    8.80  {
    8.81      PEPInternalSession *session = [PEPSessionProvider session];
    8.82 +    RETURN_ON_ERROR(session, error, nil);
    8.83      return [session encryptMessage:message extraKeys:extraKeys status:status error:error];
    8.84  }
    8.85  
    8.86 @@ -132,6 +156,7 @@
    8.87                                      error:(NSError * _Nullable * _Nullable)error
    8.88  {
    8.89      PEPInternalSession *session = [PEPSessionProvider session];
    8.90 +    RETURN_ON_ERROR(session, error, nil);
    8.91      return [session
    8.92              encryptMessageDict:messageDict
    8.93              forSelf:ownIdentity
    8.94 @@ -147,6 +172,7 @@
    8.95                                     error:(NSError * _Nullable * _Nullable)error
    8.96  {
    8.97      PEPInternalSession *session = [PEPSessionProvider session];
    8.98 +    RETURN_ON_ERROR(session, error, nil);
    8.99      return [session
   8.100              encryptMessage:message
   8.101              forSelf:ownIdentity
   8.102 @@ -163,6 +189,7 @@
   8.103                                      error:(NSError * _Nullable * _Nullable)error __deprecated
   8.104  {
   8.105      PEPInternalSession *session = [PEPSessionProvider session];
   8.106 +    RETURN_ON_ERROR(session, error, nil);
   8.107      return [session
   8.108              encryptMessageDict:messageDict
   8.109              toFpr:toFpr
   8.110 @@ -180,6 +207,7 @@
   8.111                                     error:(NSError * _Nullable * _Nullable)error
   8.112  {
   8.113      PEPInternalSession *session = [PEPSessionProvider session];
   8.114 +    RETURN_ON_ERROR(session, error, nil);
   8.115      return [session
   8.116              encryptMessage:message
   8.117              toFpr:toFpr
   8.118 @@ -193,6 +221,7 @@
   8.119                                             error:(NSError * _Nullable * _Nullable)error
   8.120  {
   8.121      PEPInternalSession *session = [PEPSessionProvider session];
   8.122 +    RETURN_ON_ERROR(session, error, nil);
   8.123      return [session outgoingRatingForMessage:theMessage error:error];
   8.124  }
   8.125  
   8.126 @@ -200,6 +229,7 @@
   8.127                                                    error:(NSError * _Nullable * _Nullable)error
   8.128  {
   8.129      PEPInternalSession *session = [PEPSessionProvider session];
   8.130 +    RETURN_ON_ERROR(session, error, nil);
   8.131      return [session outgoingRatingPreviewForMessage:theMessage error:error];
   8.132  }
   8.133  
   8.134 @@ -207,6 +237,7 @@
   8.135                                      error:(NSError * _Nullable * _Nullable)error
   8.136  {
   8.137      PEPInternalSession *session = [PEPSessionProvider session];
   8.138 +    RETURN_ON_ERROR(session, error, nil);
   8.139      return [session ratingForIdentity:identity error:error];
   8.140  }
   8.141  
   8.142 @@ -216,6 +247,7 @@
   8.143                                            error:(NSError * _Nullable * _Nullable)error
   8.144  {
   8.145      PEPInternalSession *session = [PEPSessionProvider session];
   8.146 +    RETURN_ON_ERROR(session, error, nil);
   8.147      return [session
   8.148              trustwordsForFingerprint:fingerprint
   8.149              languageID:languageID
   8.150 @@ -226,6 +258,7 @@
   8.151  - (BOOL)mySelf:(PEPIdentity * _Nonnull)identity error:(NSError * _Nullable * _Nullable)error
   8.152  {
   8.153      PEPInternalSession *session = [PEPSessionProvider session];
   8.154 +    RETURN_ON_ERROR(session, error, NO);
   8.155      return [session mySelf:identity error:error];
   8.156  }
   8.157  
   8.158 @@ -233,6 +266,7 @@
   8.159                   error:(NSError * _Nullable * _Nullable)error
   8.160  {
   8.161      PEPInternalSession *session = [PEPSessionProvider session];
   8.162 +    RETURN_ON_ERROR(session, error, NO);
   8.163      return [session updateIdentity:identity error:error];
   8.164  }
   8.165  
   8.166 @@ -240,6 +274,7 @@
   8.167                     error:(NSError * _Nullable * _Nullable)error
   8.168  {
   8.169      PEPInternalSession *session = [PEPSessionProvider session];
   8.170 +    RETURN_ON_ERROR(session, error, NO);
   8.171      return [session trustPersonalKey:identity error:error];
   8.172  }
   8.173  
   8.174 @@ -247,6 +282,7 @@
   8.175                  error:(NSError * _Nullable * _Nullable)error
   8.176  {
   8.177      PEPInternalSession *session = [PEPSessionProvider session];
   8.178 +    RETURN_ON_ERROR(session, error, NO);
   8.179      return [session keyMistrusted:identity error:error];
   8.180  }
   8.181  
   8.182 @@ -254,15 +290,41 @@
   8.183                  error:(NSError * _Nullable * _Nullable)error
   8.184  {
   8.185      PEPInternalSession *session = [PEPSessionProvider session];
   8.186 +    RETURN_ON_ERROR(session, error, NO);
   8.187      return [session keyResetTrust:identity error:error];
   8.188  }
   8.189  
   8.190 +- (BOOL)enableSyncForIdentity:(PEPIdentity * _Nonnull)identity
   8.191 +                        error:(NSError * _Nullable * _Nullable)error
   8.192 +{
   8.193 +    PEPInternalSession *session = [PEPSessionProvider session];
   8.194 +    RETURN_ON_ERROR(session, error, NO);
   8.195 +    return [session enableSyncForIdentity:identity error:error];
   8.196 +}
   8.197 +
   8.198 +- (BOOL)disableSyncForIdentity:(PEPIdentity * _Nonnull)identity
   8.199 +                         error:(NSError * _Nullable * _Nullable)error
   8.200 +{
   8.201 +    PEPInternalSession *session = [PEPSessionProvider session];
   8.202 +    RETURN_ON_ERROR(session, error, NO);
   8.203 +    return [session disableSyncForIdentity:identity error:error];
   8.204 +}
   8.205 +
   8.206 +- (NSNumber * _Nullable)queryKeySyncEnabledForIdentity:(PEPIdentity * _Nonnull)identity
   8.207 +                                                 error:(NSError * _Nullable * _Nullable)error
   8.208 +{
   8.209 +    PEPInternalSession *session = [PEPSessionProvider session];
   8.210 +    RETURN_ON_ERROR(session, error, nil);
   8.211 +    return [session queryKeySyncEnabledForIdentity:identity error:error];
   8.212 +}
   8.213 +
   8.214  #pragma mark Internal API (testing etc.)
   8.215  
   8.216  - (NSArray * _Nullable)importKey:(NSString * _Nonnull)keydata
   8.217                             error:(NSError * _Nullable * _Nullable)error
   8.218  {
   8.219      PEPInternalSession *session = [PEPSessionProvider session];
   8.220 +    RETURN_ON_ERROR(session, error, nil);
   8.221      return [session importKey:keydata error:error];
   8.222  }
   8.223  
   8.224 @@ -273,6 +335,7 @@
   8.225             error:(NSError * _Nullable * _Nullable)error
   8.226  {
   8.227      PEPInternalSession *session = [PEPSessionProvider session];
   8.228 +    RETURN_ON_ERROR(session, error, NO);
   8.229      return [session
   8.230              logTitle:title
   8.231              entity:entity
   8.232 @@ -284,6 +347,7 @@
   8.233  - (NSString * _Nullable)getLogWithError:(NSError * _Nullable * _Nullable)error
   8.234  {
   8.235      PEPInternalSession *session = [PEPSessionProvider session];
   8.236 +    RETURN_ON_ERROR(session, error, nil);
   8.237      return [session getLogWithError:error];
   8.238  }
   8.239  
   8.240 @@ -294,6 +358,7 @@
   8.241                                           error:(NSError * _Nullable * _Nullable)error
   8.242  {
   8.243      PEPInternalSession *session = [PEPSessionProvider session];
   8.244 +    RETURN_ON_ERROR(session, error, nil);
   8.245      return [session getTrustwordsIdentity1:identity1
   8.246                                   identity2:identity2
   8.247                                    language:language
   8.248 @@ -308,24 +373,32 @@
   8.249                                      error:(NSError * _Nullable * _Nullable)error
   8.250  {
   8.251      PEPInternalSession *session = [PEPSessionProvider session];
   8.252 +    RETURN_ON_ERROR(session, error, nil);
   8.253      return [session getTrustwordsFpr1:fpr1 fpr2:fpr2 language:language full:full error:error];
   8.254  }
   8.255  
   8.256  - (NSArray<PEPLanguage *> * _Nullable)languageListWithError:(NSError * _Nullable * _Nullable)error
   8.257  {
   8.258      PEPInternalSession *session = [PEPSessionProvider session];
   8.259 +    RETURN_ON_ERROR(session, error, nil);
   8.260      return [session languageListWithError:error];
   8.261  }
   8.262  
   8.263  - (PEPRating)ratingFromString:(NSString * _Nonnull)string
   8.264  {
   8.265      PEPInternalSession *session = [PEPSessionProvider session];
   8.266 +    if (session == nil) {
   8.267 +        return PEPRatingUndefined;
   8.268 +    }
   8.269      return [session ratingFromString:string];
   8.270  }
   8.271  
   8.272  - (NSString * _Nonnull)stringFromRating:(PEPRating)rating
   8.273  {
   8.274      PEPInternalSession *session = [PEPSessionProvider session];
   8.275 +    if (session == nil) {
   8.276 +        return kUndefined;
   8.277 +    }
   8.278      return [session stringFromRating:rating];
   8.279  }
   8.280  
   8.281 @@ -333,6 +406,7 @@
   8.282                              error:(NSError * _Nullable * _Nullable)error
   8.283  {
   8.284      PEPInternalSession *session = [PEPSessionProvider session];
   8.285 +    RETURN_ON_ERROR(session, error, nil);
   8.286      return [session isPEPUser:identity error:error];
   8.287  }
   8.288  
   8.289 @@ -340,6 +414,7 @@
   8.290              error:(NSError * _Nullable * _Nullable)error
   8.291  {
   8.292      PEPInternalSession *session = [PEPSessionProvider session];
   8.293 +    RETURN_ON_ERROR(session, error, NO);
   8.294      return [session setOwnKey:identity fingerprint:fingerprint error:error];
   8.295  }
   8.296  
   8.297 @@ -354,6 +429,7 @@
   8.298             error:(NSError * _Nullable * _Nullable)error
   8.299  {
   8.300      PEPInternalSession *session = [PEPSessionProvider session];
   8.301 +    RETURN_ON_ERROR(session, error, NO);
   8.302      return [session setFlags:flags forIdentity:identity error:error];
   8.303  }
   8.304  
   8.305 @@ -361,6 +437,7 @@
   8.306                        error:(NSError * _Nullable * _Nullable)error
   8.307  {
   8.308      PEPInternalSession *session = [PEPSessionProvider session];
   8.309 +    RETURN_ON_ERROR(session, error, NO);
   8.310      return [session trustOwnKeyIdentity:identity error:error];
   8.311  }
   8.312  
   8.313 @@ -369,12 +446,16 @@
   8.314                           error:(NSError * _Nullable * _Nullable)error;
   8.315  {
   8.316      PEPInternalSession *session = [PEPSessionProvider session];
   8.317 +    RETURN_ON_ERROR(session, error, NO);
   8.318      return [session deliverHandshakeResult:result identitiesSharing:identitiesSharing error:error];
   8.319  }
   8.320  
   8.321  - (PEPColor)colorFromRating:(PEPRating)rating
   8.322  {
   8.323      PEPInternalSession *session = [PEPSessionProvider session];
   8.324 +    if (session == nil) {
   8.325 +        return PEPColorNoColor;
   8.326 +    }
   8.327      return [session colorFromRating:rating];
   8.328  }
   8.329  
   8.330 @@ -383,12 +464,14 @@
   8.331             error:(NSError * _Nullable * _Nullable)error
   8.332  {
   8.333      PEPInternalSession *session = [PEPSessionProvider session];
   8.334 +    RETURN_ON_ERROR(session, error, NO);
   8.335      return [session keyReset:identity fingerprint:fingerprint error:error];
   8.336  }
   8.337  
   8.338  - (BOOL)leaveDeviceGroupError:(NSError * _Nullable * _Nullable)error
   8.339  {
   8.340      PEPInternalSession *session = [PEPSessionProvider session];
   8.341 +    RETURN_ON_ERROR(session, error, NO);
   8.342      return [session leaveDeviceGroupError:error];
   8.343  }
   8.344  
     9.1 --- a/pEpObjCAdapter/PEPSync.m	Fri Aug 09 16:29:40 2019 +0200
     9.2 +++ b/pEpObjCAdapter/PEPSync.m	Mon Sep 23 08:57:17 2019 +0200
     9.3 @@ -22,7 +22,9 @@
     9.4  #import "PEPSessionProvider.h"
     9.5  #import "PEPInternalSession.h"
     9.6  
     9.7 -// MARK: - Declare internals
     9.8 +// MARK: - Internals
     9.9 +
    9.10 +os_log_t s_logger;
    9.11  
    9.12  typedef PEP_STATUS (* t_messageToSendCallback)(struct _message *msg);
    9.13  typedef int (* t_injectSyncCallback)(SYNC_EVENT ev, void *management);
    9.14 @@ -34,7 +36,6 @@
    9.15  @property (nonatomic, nonnull) PEPQueue *queue;
    9.16  @property (nonatomic, nullable) NSThread *syncThread;
    9.17  @property (nonatomic, nullable) NSConditionLock *conditionLockForJoiningSyncThread;
    9.18 -@property (nonnull, readonly) os_log_t logger;
    9.19  
    9.20  /**
    9.21   @Return: The callback for message sending that should be used on every session init.
    9.22 @@ -132,6 +133,7 @@
    9.23      if (status != PEP_STATUS_OK) {
    9.24          if (error) {
    9.25              *error = [NSError errorWithPEPStatusInternal:status];
    9.26 +            os_log(s_logger, "error creating session: %{public}@", *error);
    9.27          }
    9.28          return nil;
    9.29      }
    9.30 @@ -145,7 +147,6 @@
    9.31                                               _Nullable)notifyHandshakeDelegate
    9.32  {
    9.33      if (self = [super init]) {
    9.34 -        _logger = os_log_create("security.pEp.adapter", "PEPSync");
    9.35          _sendMessageDelegate = sendMessageDelegate;
    9.36          _notifyHandshakeDelegate = notifyHandshakeDelegate;
    9.37          _queue = [PEPQueue new];
    9.38 @@ -179,6 +180,11 @@
    9.39  
    9.40  // MARK: - Private
    9.41  
    9.42 ++ (void)initialize
    9.43 +{
    9.44 +    s_logger = os_log_create("security.pEp.adapter", "PEPSync");
    9.45 +}
    9.46 +
    9.47  + (PEPSync * _Nullable)instance
    9.48  {
    9.49      return s_pEpSync;
    9.50 @@ -193,7 +199,7 @@
    9.51  {
    9.52      [self.conditionLockForJoiningSyncThread lock];
    9.53  
    9.54 -    os_log(self.logger, "trying to start the sync loop");
    9.55 +    os_log(s_logger, "trying to start the sync loop");
    9.56  
    9.57      PEPInternalSession *session = [PEPSessionProvider session];
    9.58  
    9.59 @@ -203,19 +209,19 @@
    9.60          if (status == PEP_STATUS_OK) {
    9.61              status = do_sync_protocol(session.session, nil);
    9.62              if (status != PEP_STATUS_OK) {
    9.63 -                os_log_error(self.logger, "do_sync_protocol returned PEP_STATUS %d", status);
    9.64 -                os_log(self.logger, "sync loop is NOT running");
    9.65 +                os_log_error(s_logger, "do_sync_protocol returned PEP_STATUS %d", status);
    9.66 +                os_log(s_logger, "sync loop is NOT running");
    9.67              }
    9.68              unregister_sync_callbacks(session.session);
    9.69          } else {
    9.70 -            os_log_error(self.logger, "register_sync_callbacks returned PEP_STATUS %d", status);
    9.71 -            os_log(self.logger, "sync loop is NOT running");
    9.72 +            os_log_error(s_logger, "register_sync_callbacks returned PEP_STATUS %d", status);
    9.73 +            os_log(s_logger, "sync loop is NOT running");
    9.74          }
    9.75      } else {
    9.76 -        os_log_error(self.logger, "could not create session for starting the sync loop");
    9.77 +        os_log_error(s_logger, "could not create session for starting the sync loop");
    9.78      }
    9.79  
    9.80 -    os_log(self.logger, "sync loop finished");
    9.81 +    os_log(s_logger, "sync loop finished");
    9.82  
    9.83      session = nil;
    9.84  
    10.1 --- a/pEpObjCAdapterFramework/PEPEngineTypes.h	Fri Aug 09 16:29:40 2019 +0200
    10.2 +++ b/pEpObjCAdapterFramework/PEPEngineTypes.h	Mon Sep 23 08:57:17 2019 +0200
    10.3 @@ -173,6 +173,9 @@
    10.4      // handshake dialog must be closed
    10.5      PEPSyncHandshakeSignalOvertaken = 9, // SYNC_NOTIFY_OVERTAKEN = 9,
    10.6  
    10.7 +    /** currently exchanging private keys */
    10.8 +    PEPSyncHandshakeSignalFormingGroup = 10, // SYNC_NOTIFY_FORMING_GROUP = 10
    10.9 +
   10.10      // notificaton of actual group status
   10.11      PEPSyncHandshakeSignalSole = 254, // SYNC_NOTIFY_SOLE = 254,
   10.12      PEPSyncHandshakeSignalInGroup = 255 // SYNC_NOTIFY_IN_GROUP = 255
    11.1 --- a/pEpObjCAdapterFramework/PEPIdentity.h	Fri Aug 09 16:29:40 2019 +0200
    11.2 +++ b/pEpObjCAdapterFramework/PEPIdentity.h	Mon Sep 23 08:57:17 2019 +0200
    11.3 @@ -105,4 +105,36 @@
    11.4   */
    11.5  - (void)reset;
    11.6  
    11.7 +/**
    11.8 + Enables key sync on this identity.
    11.9 +
   11.10 + Will invoke the needed methods on an own session.
   11.11 +
   11.12 + @param error The usual cocoa error handling.
   11.13 + @return The usual cocoa error handling.
   11.14 + */
   11.15 +- (BOOL)enableKeySync:(NSError * _Nullable * _Nullable)error;
   11.16 +
   11.17 +/**
   11.18 + Disables key sync on this identity.
   11.19 +
   11.20 + Will invoke the needed methods on an own session.
   11.21 +
   11.22 + @param error The usual cocoa error handling.
   11.23 + @return The usual cocoa error handling.
   11.24 + */
   11.25 +- (BOOL)disableKeySync:(NSError * _Nullable * _Nullable)error;
   11.26 +
   11.27 +/**
   11.28 + Queries whether this own identity has key sync enabled or not.
   11.29 +
   11.30 + Will invoke the needed methods on an own session.
   11.31 +
   11.32 + @param error The usual cocoa error handling.
   11.33 + @return A NSNumber denoting whether this own identity can participate in key sync enabled or not,
   11.34 +         or nil on error.
   11.35 +         YES means that key sync is allowed for this identity, otherwise it's NO.
   11.36 + */
   11.37 +- (NSNumber * _Nullable)queryKeySyncEnabled:(NSError * _Nullable * _Nullable)error;
   11.38 +
   11.39  @end
    12.1 --- a/pEpObjCAdapterFramework/PEPObjCAdapter.h	Fri Aug 09 16:29:40 2019 +0200
    12.2 +++ b/pEpObjCAdapterFramework/PEPObjCAdapter.h	Mon Sep 23 08:57:17 2019 +0200
    12.3 @@ -37,4 +37,19 @@
    12.4  + (void)setupTrustWordsDB;
    12.5  + (void)setupTrustWordsDB:(NSBundle * _Nonnull)rootBundle;
    12.6  
    12.7 +/**
    12.8 + The directory where pEp stores user-specific data.
    12.9 +
   12.10 + @return An NSString denoting the directory where user-specific data gets stored by the engine.
   12.11 + */
   12.12 ++ (NSString * _Nonnull)perUserDirectoryString;
   12.13 +
   12.14 +/**
   12.15 + The directory where pEp stores data for all users on this machine.
   12.16 +
   12.17 + @return An NSString denoting the directory where global data (for all users of this machine
   12.18 +         or device) gets stored by the engine.
   12.19 + */
   12.20 ++ (NSString * _Nonnull)perMachineDirectoryString;
   12.21 +
   12.22  @end
    13.1 --- a/pEpObjCAdapterFramework/PEPSessionProtocol.h	Fri Aug 09 16:29:40 2019 +0200
    13.2 +++ b/pEpObjCAdapterFramework/PEPSessionProtocol.h	Mon Sep 23 08:57:17 2019 +0200
    13.3 @@ -180,6 +180,41 @@
    13.4  - (BOOL)keyResetTrust:(PEPIdentity * _Nonnull)identity
    13.5                  error:(NSError * _Nullable * _Nullable)error;
    13.6  
    13.7 +/**
    13.8 + Enables key sync.
    13.9 +
   13.10 + Wraps enable_identity_for_sync.
   13.11 +
   13.12 + @param identity The (own) identity to enable key sync for.
   13.13 + @param error The usual cocoa error handling.
   13.14 + @return The usual cocoa error handling.
   13.15 + */
   13.16 +- (BOOL)enableSyncForIdentity:(PEPIdentity * _Nonnull)identity
   13.17 +                        error:(NSError * _Nullable * _Nullable)error;
   13.18 +
   13.19 +/**
   13.20 + Disables key sync.
   13.21 +
   13.22 + Wraps disable_identity_for_sync.
   13.23 +
   13.24 + @param identity The (own) identity to disable key sync for.
   13.25 + @param error The usual cocoa error handling.
   13.26 + @return The usual cocoa error handling.
   13.27 + */
   13.28 +- (BOOL)disableSyncForIdentity:(PEPIdentity * _Nonnull)identity
   13.29 +                         error:(NSError * _Nullable * _Nullable)error;
   13.30 +
   13.31 +/**
   13.32 + Queries the given own identity on whether it has key sync disabled or not.
   13.33 +
   13.34 + @param identity The (own) identity to query.
   13.35 + @param error The usual cocoa error handling.
   13.36 + @return An NSNumber containing a boolean denoting whether key sync is enabled or not, or
   13.37 +         nil on error. YES means that key sync is allowed for this identity, otherwise it's NO.
   13.38 + */
   13.39 +- (NSNumber * _Nullable)queryKeySyncEnabledForIdentity:(PEPIdentity * _Nonnull)identity
   13.40 +                                                 error:(NSError * _Nullable * _Nullable)error;
   13.41 +
   13.42  #pragma mark -- Internal API (testing etc.)
   13.43  
   13.44  /** For testing purpose, manual key import */
   13.45 @@ -242,6 +277,7 @@
   13.46  
   13.47  /**
   13.48   Wraps the engine's `config_passive_mode`.
   13.49 + @note That there's absolutely no error handling.
   13.50   */
   13.51  - (void)configurePassiveModeEnabled:(BOOL)enabled;
   13.52  
    14.1 --- a/pEpObjCTests/PEPSessionTest.m	Fri Aug 09 16:29:40 2019 +0200
    14.2 +++ b/pEpObjCTests/PEPSessionTest.m	Mon Sep 23 08:57:17 2019 +0200
    14.3 @@ -1400,6 +1400,113 @@
    14.4      [self shutdownSync];
    14.5  }
    14.6  
    14.7 +#pragma mark - enable/disable sync
    14.8 +
    14.9 +- (void)testEnableDisableFailForSyncOnPartnerIdentity
   14.10 +{
   14.11 +    PEPIdentity *notMe = [[PEPIdentity alloc]
   14.12 +                          initWithAddress:@"notme@pep-project.org"
   14.13 +                          userID:@"notme_ID"
   14.14 +                          userName:@"notme"
   14.15 +                          isOwn:NO];
   14.16 +
   14.17 +    NSError *error = nil;
   14.18 +    XCTAssertFalse([notMe enableKeySync:&error]);
   14.19 +    XCTAssertNotNil(error);
   14.20 +
   14.21 +    error = nil;
   14.22 +    XCTAssertFalse([notMe disableKeySync:&error]);
   14.23 +    XCTAssertNotNil(error);
   14.24 +
   14.25 +    error = nil;
   14.26 +    XCTAssertNil([notMe queryKeySyncEnabled:&error]);
   14.27 +    XCTAssertNotNil(error);
   14.28 +}
   14.29 +
   14.30 +- (void)testEnableDisableSyncOnOwnIdentityWithQuery
   14.31 +{
   14.32 +    PEPSession *session = [PEPSession new];
   14.33 +
   14.34 +    PEPIdentity *identMe1 = [[PEPIdentity alloc]
   14.35 +                             initWithAddress:@"me-myself-and-i@pep-project.org"
   14.36 +                             userID:@"me-myself-and-i"
   14.37 +                             userName:@"pEp Me"
   14.38 +                             isOwn:YES];
   14.39 +    NSError *error = nil;
   14.40 +    XCTAssertTrue([session mySelf:identMe1 error:&error]);
   14.41 +    XCTAssertNil(error);
   14.42 +
   14.43 +    error = nil;
   14.44 +    PEPIdentity *identMe2 = [[PEPIdentity alloc]
   14.45 +                             initWithAddress:@"me-myself-and-i2@pep-project.org"
   14.46 +                             userID:@"me-myself-and-i2"
   14.47 +                             userName:@"pEp Me2"
   14.48 +                             isOwn:YES];
   14.49 +    XCTAssertTrue([session mySelf:identMe2 error:&error]);
   14.50 +    XCTAssertNil(error);
   14.51 +
   14.52 +    XCTAssertNotEqualObjects(identMe1.fingerPrint, identMe2.fingerPrint);
   14.53 +
   14.54 +    for (int i = 0; i < 10; ++i) {
   14.55 +        error = nil;
   14.56 +        BOOL enable = i % 2 == 0; // enable keysync on even numbers (roughly)
   14.57 +        if (enable) {
   14.58 +            XCTAssertTrue([session enableSyncForIdentity:identMe1 error:&error]);
   14.59 +            XCTAssertTrue([identMe2 enableKeySync:&error]);
   14.60 +        } else {
   14.61 +            XCTAssertTrue([session disableSyncForIdentity:identMe1 error:&error]);
   14.62 +            XCTAssertTrue([identMe2 disableKeySync:&error]);
   14.63 +        }
   14.64 +        XCTAssertNil(error);
   14.65 +
   14.66 +        NSNumber *keySyncState1 = [session queryKeySyncEnabledForIdentity:identMe1 error:&error];
   14.67 +        NSNumber *keySyncState2 = [identMe2 queryKeySyncEnabled:&error];
   14.68 +        XCTAssertNil(error);
   14.69 +        XCTAssertNotNil(keySyncState1);
   14.70 +        XCTAssertNotNil(keySyncState2);
   14.71 +        if (enable) {
   14.72 +            XCTAssertTrue([keySyncState1 boolValue]);
   14.73 +        } else {
   14.74 +            XCTAssertFalse([keySyncState1 boolValue]);
   14.75 +        }
   14.76 +        XCTAssertEqualObjects(keySyncState1, keySyncState2);
   14.77 +    }
   14.78 +}
   14.79 +
   14.80 +/**
   14.81 + ENGINE-604, just in case.
   14.82 + */
   14.83 +- (void)testQueryKeySyncOnOwnIdentityInALoop
   14.84 +{
   14.85 +    PEPSession *session = [PEPSession new];
   14.86 +
   14.87 +    PEPIdentity *identMe = [[PEPIdentity alloc]
   14.88 +                            initWithAddress:@"me-myself-and-i@pep-project.org"
   14.89 +                            userID:@"me-myself-and-i"
   14.90 +                            userName:@"pEp Me"
   14.91 +                            isOwn:YES];
   14.92 +    NSError *error = nil;
   14.93 +    XCTAssertTrue([session mySelf:identMe error:&error]);
   14.94 +    XCTAssertNil(error);
   14.95 +
   14.96 +    for (NSNumber *numBool in @[@YES, @NO]) {
   14.97 +        error = nil;
   14.98 +        if ([numBool boolValue]) {
   14.99 +            XCTAssertTrue([session enableSyncForIdentity:identMe error:&error]);
  14.100 +        } else {
  14.101 +            XCTAssertTrue([session disableSyncForIdentity:identMe error:&error]);
  14.102 +        }
  14.103 +        XCTAssertNil(error);
  14.104 +
  14.105 +        for (int i = 0; i < 10; ++i) {
  14.106 +            NSNumber *numQuery = [session queryKeySyncEnabledForIdentity:identMe error:&error];
  14.107 +            XCTAssertNotNil(numQuery);
  14.108 +            XCTAssertEqualObjects(numBool, numQuery);
  14.109 +            XCTAssertNil(error);
  14.110 +        }
  14.111 +    }
  14.112 +}
  14.113 +
  14.114  #pragma mark - Helpers
  14.115  
  14.116  - (void)testSendMessageOnSession:(PEPSession *)session
    15.1 --- a/pEpObjCTests/TestUtils/PEPTestUtils.h	Fri Aug 09 16:29:40 2019 +0200
    15.2 +++ b/pEpObjCTests/TestUtils/PEPTestUtils.h	Mon Sep 23 08:57:17 2019 +0200
    15.3 @@ -46,8 +46,6 @@
    15.4  
    15.5  + (void)cleanUp;
    15.6  
    15.7 -+ (NSArray *)pEpWorkFiles;
    15.8 -
    15.9  @end
   15.10  
   15.11  NS_ASSUME_NONNULL_END
    16.1 --- a/pEpObjCTests/TestUtils/PEPTestUtils.m	Fri Aug 09 16:29:40 2019 +0200
    16.2 +++ b/pEpObjCTests/TestUtils/PEPTestUtils.m	Mon Sep 23 08:57:17 2019 +0200
    16.3 @@ -116,64 +116,20 @@
    16.4      return message;
    16.5  }
    16.6  
    16.7 -+ (NSArray *)pEpWorkFiles;
    16.8 -{
    16.9 -    // Only files whose content is affected by tests.
   16.10 -    NSString *home = [[[NSProcessInfo processInfo]environment]objectForKey:@"HOME"];
   16.11 -
   16.12 -    NSArray *baseNames = @[@".pEp_keys", @".pEp_management"];
   16.13 -    NSArray *baseEndings = @[@"db", @"db-shm", @"db-wal"];
   16.14 -
   16.15 -    NSMutableArray *result = [NSMutableArray array];
   16.16 -
   16.17 -    for (NSString *base in baseNames) {
   16.18 -        for (NSString *ending in baseEndings) {
   16.19 -            NSString *filename = [NSString stringWithFormat:@"%@.%@", base, ending];
   16.20 -            [result addObject:[home stringByAppendingPathComponent:filename]];
   16.21 -        }
   16.22 -    }
   16.23 -
   16.24 -    return result;
   16.25 -}
   16.26 -
   16.27  + (void)cleanUp
   16.28  {
   16.29 -    // This triggers setting HOME und GPGHOME in the adapter.
   16.30 -    // Important for tests which do a cleanup on test start.
   16.31 -    [PEPObjCAdapter homeURL];
   16.32 -
   16.33      [PEPSession cleanup];
   16.34  
   16.35 -    for (id path in [self pEpWorkFiles]) {
   16.36 -        [self delFilePath:path];
   16.37 -    }
   16.38 -}
   16.39 +    NSString *homeString = [PEPObjCAdapter perUserDirectoryString];
   16.40 +    NSURL *homeUrl = [NSURL fileURLWithPath:homeString isDirectory:YES];
   16.41  
   16.42 -#pragma mark - PRIVATE
   16.43 -
   16.44 -+ (void)delFilePath:(NSString *)filePath
   16.45 -{
   16.46      NSFileManager *fileManager = [NSFileManager defaultManager];
   16.47 -    NSError *error = nil;
   16.48 -    if ([fileManager fileExistsAtPath:filePath]) {
   16.49 -        BOOL success = [fileManager removeItemAtPath:filePath error:&error];
   16.50 -        if (!success) {
   16.51 -            NSLog(@"Error: %@", [error localizedDescription]);
   16.52 -        }
   16.53 -    }
   16.54 -}
   16.55 -
   16.56 -+ (void)undelFileWithPath:(NSString *)path backup:(NSString *)backup;
   16.57 -{
   16.58 -    NSParameterAssert(backup);
   16.59 -    NSFileManager *fileManager = [NSFileManager defaultManager];
   16.60 -    NSString* bpath = [path stringByAppendingString:backup];
   16.61 -    BOOL fileExists = [fileManager fileExistsAtPath:bpath];
   16.62 -    if (fileExists) {
   16.63 +    NSDirectoryEnumerator<NSString *> *enumerator = [fileManager enumeratorAtPath:homeString];
   16.64 +    for (NSString *path in enumerator) {
   16.65 +        NSURL *fileUrl = [NSURL fileURLWithPath:path isDirectory:NO relativeToURL:homeUrl];
   16.66          NSError *error = nil;
   16.67 -        BOOL success = [fileManager moveItemAtPath:bpath toPath:path error:&error];
   16.68 -        if (!success) {
   16.69 -            NSLog(@"Error: %@", [error localizedDescription]);
   16.70 +        if (![fileManager removeItemAtURL:fileUrl error:&error]) {
   16.71 +            NSLog(@"Error deleting '%@': %@", fileUrl, [error localizedDescription]);
   16.72          }
   16.73      }
   16.74  }