pEpObjCAdapter/PEPSession.m
author Dirk Zimmermann <dirk@pep-project.org>
Thu, 31 Aug 2017 12:42:03 +0200
changeset 207 573bc548d19a
parent 206 01b8419e8203
child 213 959a115bc0f7
permissions -rw-r--r--
IOSAD-25 ws, indentation
dirk@187
     1
//
dirk@187
     2
//  PEPSession.m
dirk@187
     3
//  pEpiOSAdapter
dirk@187
     4
//
dirk@187
     5
//  Created by Volker Birk on 08.07.15.
dirk@187
     6
//  Copyright (c) 2015 p≡p. All rights reserved.
dirk@187
     7
//
dirk@187
     8
dirk@187
     9
#import "PEPSession.h"
dirk@187
    10
#import "PEPSession+Internal.h"
dirk@187
    11
#import "PEPObjCAdapter.h"
dirk@187
    12
#import "PEPObjCAdapter+Internal.h"
dirk@187
    13
#import "PEPMessage.h"
dirk@187
    14
#import "PEPLanguage.h"
dirk@187
    15
#import "PEPCSVScanner.h"
dirk@187
    16
#import "NSArray+Extension.h"
dirk@187
    17
dirk@187
    18
@implementation PEPSession
dirk@187
    19
dirk@187
    20
// serialize all session access
dirk@187
    21
+ (dispatch_queue_t)sharedSessionQueue
dirk@187
    22
{
dirk@187
    23
    static dispatch_once_t once;
dirk@187
    24
    static dispatch_queue_t sharedSessionQueue;
dirk@187
    25
    dispatch_once(&once, ^{
dirk@187
    26
        sharedSessionQueue = dispatch_queue_create("pEp session queue", DISPATCH_QUEUE_CONCURRENT);
dirk@187
    27
    });
dirk@187
    28
    return sharedSessionQueue;
dirk@187
    29
}
dirk@187
    30
dirk@187
    31
+ (PEPSession *)session
dirk@187
    32
{
dirk@187
    33
    PEPSession *_session = [[PEPSession alloc] init];
dirk@187
    34
    return _session;
dirk@187
    35
}
dirk@187
    36
dirk@187
    37
+ (void)dispatchAsyncOnSession:(PEPSessionBlock)block
dirk@187
    38
{
dirk@187
    39
    dispatch_async([self sharedSessionQueue], ^{
dirk@187
    40
        PEPSession *pepSession = [[PEPSession alloc] init];
dirk@187
    41
        block(pepSession);
dirk@187
    42
    });
dirk@187
    43
}
dirk@187
    44
dirk@187
    45
+ (void)dispatchSyncOnSession:(PEPSessionBlock)block
dirk@187
    46
{
dirk@187
    47
    PEPSession *pepSession = [[PEPSession alloc] init];
dirk@187
    48
    block(pepSession);
dirk@187
    49
}
dirk@187
    50
dirk@187
    51
+ (void)setupTrustWordsDB
dirk@187
    52
{
dirk@187
    53
    static dispatch_once_t once;
dirk@187
    54
    dispatch_once(&once, ^{
dirk@187
    55
        [PEPObjCAdapter setupTrustWordsDB:[NSBundle bundleForClass:[self class]]];
dirk@187
    56
    });
dirk@187
    57
}
dirk@187
    58
dirk@187
    59
- (id)init
dirk@187
    60
{
dirk@187
    61
    [PEPSession setupTrustWordsDB];
dirk@187
    62
dirk@187
    63
    PEP_STATUS status = init(&_session);
dirk@187
    64
dirk@187
    65
    if (status != PEP_STATUS_OK) {
dirk@187
    66
        return nil;
dirk@187
    67
    }
dirk@187
    68
dirk@187
    69
    [PEPObjCAdapter bindSession:self];
dirk@207
    70
dirk@187
    71
    return self;
dirk@187
    72
}
dirk@187
    73
dirk@187
    74
- (void)dealloc
dirk@187
    75
{
dirk@187
    76
    [PEPObjCAdapter unbindSession:self];
dirk@207
    77
dirk@187
    78
    release(_session);
dirk@187
    79
}
dirk@187
    80
dirk@206
    81
- (PEP_rating)decryptMessageDict:(nonnull PEPDict *)src
dirk@206
    82
                            dest:(PEPDict * _Nullable * _Nullable)dst
dirk@206
    83
                            keys:(PEPStringList * _Nullable * _Nullable)keys
dirk@187
    84
{
dirk@187
    85
    message * _src = PEP_messageDictToStruct(src);
dirk@187
    86
    message * _dst = NULL;
dirk@187
    87
    stringlist_t * _keys = NULL;
dirk@187
    88
    PEP_rating color = PEP_rating_undefined;
dirk@187
    89
    PEP_decrypt_flags_t flags = 0;
dirk@187
    90
dirk@187
    91
    @synchronized (self) {
dirk@187
    92
        decrypt_message(_session, _src, &_dst, &_keys, &color, &flags);
dirk@187
    93
    }
dirk@187
    94
dirk@187
    95
    NSDictionary * dst_;
dirk@187
    96
dirk@187
    97
    if (_dst) {
dirk@187
    98
        dst_ = PEP_messageDictFromStruct(_dst);
dirk@187
    99
    }
dirk@187
   100
    else {
dirk@187
   101
        dst_ = PEP_messageDictFromStruct(_src);
dirk@187
   102
    }
dirk@187
   103
dirk@187
   104
    NSArray * keys_ = nil;
dirk@187
   105
    if (_keys)
dirk@187
   106
        keys_ = PEP_arrayFromStringlist(_keys);
dirk@187
   107
dirk@187
   108
    free_message(_src);
dirk@187
   109
    free_message(_dst);
dirk@187
   110
    free_stringlist(_keys);
dirk@187
   111
dirk@187
   112
    if (dst) {
dirk@187
   113
        *dst = dst_;
dirk@187
   114
    }
dirk@187
   115
    if (keys) {
dirk@187
   116
        *keys = keys_;
dirk@187
   117
    }
dirk@187
   118
    return color;
dirk@187
   119
}
dirk@187
   120
dirk@206
   121
- (PEP_rating)reEvaluateMessageRating:(nonnull PEPDict *)src
edouard@196
   122
{
edouard@196
   123
    message * _src = PEP_messageDictToStruct(src);
edouard@196
   124
    PEP_rating color = PEP_rating_undefined;
dirk@207
   125
edouard@196
   126
    @synchronized (self) {
edouard@196
   127
        re_evaluate_message_rating(_session, _src, NULL, PEP_rating_undefined, &color);
edouard@196
   128
    }
dirk@207
   129
edouard@196
   130
    free_message(_src);
dirk@207
   131
edouard@196
   132
    return color;
edouard@196
   133
}
edouard@196
   134
dirk@206
   135
- (void)removeEmptyArrayKey:(NSString *)key inDict:(PEPMutableDict *)dict
dirk@187
   136
{
dirk@187
   137
    if ([[dict objectForKey:key] count] == 0) {
dirk@187
   138
        [dict removeObjectForKey:key];
dirk@187
   139
    }
dirk@187
   140
}
dirk@187
   141
dirk@206
   142
- (NSDictionary *)removeEmptyRecipients:(PEPDict *)src
dirk@187
   143
{
dirk@187
   144
    NSMutableDictionary *dest = src.mutableCopy;
dirk@187
   145
dirk@187
   146
    [self removeEmptyArrayKey:kPepTo inDict:dest];
dirk@187
   147
    [self removeEmptyArrayKey:kPepCC inDict:dest];
dirk@187
   148
    [self removeEmptyArrayKey:kPepBCC inDict:dest];
dirk@187
   149
dirk@187
   150
    return [NSDictionary dictionaryWithDictionary:dest];
dirk@187
   151
}
dirk@187
   152
dirk@206
   153
- (PEP_STATUS)encryptMessageDict:(nonnull PEPDict *)src
dirk@187
   154
                           extra:(nullable NSArray *)keys
dirk@206
   155
                            dest:(PEPDict * _Nullable * _Nullable)dst
dirk@187
   156
{
dirk@187
   157
    PEP_STATUS status;
dirk@187
   158
    PEP_encrypt_flags_t flags = 0;
dirk@187
   159
dirk@187
   160
    message * _src = PEP_messageDictToStruct([self removeEmptyRecipients:src]);
dirk@187
   161
    message * _dst = NULL;
dirk@187
   162
    stringlist_t * _keys = PEP_arrayToStringlist(keys);
dirk@187
   163
dirk@187
   164
    @synchronized (self) {
dirk@187
   165
        status = encrypt_message(_session, _src, _keys, &_dst, PEP_enc_PGP_MIME, flags);
dirk@187
   166
    }
dirk@187
   167
dirk@187
   168
    NSDictionary * dst_;
dirk@187
   169
dirk@187
   170
    if (_dst) {
dirk@187
   171
        dst_ = PEP_messageDictFromStruct(_dst);
dirk@187
   172
    }
dirk@187
   173
    else {
dirk@187
   174
        dst_ = PEP_messageDictFromStruct(_src);
dirk@187
   175
    }
dirk@187
   176
    if (dst) {
dirk@187
   177
        *dst = dst_;
dirk@187
   178
    }
dirk@187
   179
dirk@187
   180
    free_message(_src);
dirk@187
   181
    free_message(_dst);
dirk@187
   182
    free_stringlist(_keys);
dirk@207
   183
dirk@187
   184
    return status;
dirk@187
   185
}
dirk@187
   186
dirk@206
   187
- (PEP_STATUS)encryptMessageDict:(nonnull PEPDict *)src
dirk@206
   188
                        identity:(nonnull PEPDict *)identity
dirk@206
   189
                            dest:(PEPDict * _Nullable * _Nullable)dst
dirk@187
   190
{
dirk@187
   191
    PEP_STATUS status;
dirk@187
   192
    PEP_encrypt_flags_t flags = 0;
dirk@187
   193
dirk@187
   194
    message * _src = PEP_messageDictToStruct([self removeEmptyRecipients:src]);
dirk@187
   195
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@187
   196
    message * _dst = NULL;
dirk@187
   197
dirk@187
   198
    @synchronized (self) {
dirk@187
   199
        status = encrypt_message_for_self(_session, ident, _src, &_dst, PEP_enc_PGP_MIME, flags);
dirk@187
   200
    }
dirk@187
   201
dirk@187
   202
    NSDictionary * dst_;
dirk@187
   203
dirk@187
   204
    if (_dst) {
dirk@187
   205
        dst_ = PEP_messageDictFromStruct(_dst);
dirk@187
   206
    }
dirk@187
   207
    else {
dirk@187
   208
        dst_ = PEP_messageDictFromStruct(_src);
dirk@187
   209
    }
dirk@187
   210
dirk@187
   211
    if (dst) {
dirk@187
   212
        *dst = dst_;
dirk@187
   213
    }
dirk@187
   214
dirk@187
   215
    free_message(_src);
dirk@187
   216
    free_message(_dst);
dirk@187
   217
    free_identity(ident);
dirk@187
   218
dirk@187
   219
    return status;
dirk@187
   220
}
dirk@187
   221
dirk@206
   222
- (PEP_rating)outgoingMessageColor:(PEPDict *)msg
dirk@187
   223
{
dirk@187
   224
    message * _msg = PEP_messageDictToStruct(msg);
dirk@187
   225
    PEP_rating color = PEP_rating_undefined;
dirk@187
   226
dirk@187
   227
    @synchronized (self) {
dirk@187
   228
        outgoing_message_rating(_session, _msg, &color);
dirk@187
   229
    }
dirk@187
   230
dirk@187
   231
    free_message(_msg);
dirk@207
   232
dirk@187
   233
    return color;
dirk@187
   234
}
dirk@187
   235
dirk@206
   236
- (PEP_rating)identityRating:(nonnull PEPDict *)identity
dirk@187
   237
{
dirk@187
   238
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@187
   239
    PEP_rating color = PEP_rating_undefined;
dirk@207
   240
dirk@187
   241
    @synchronized (self) {
dirk@187
   242
        identity_rating(_session, ident, &color);
dirk@187
   243
    }
dirk@207
   244
dirk@187
   245
    free_identity(ident);
dirk@207
   246
dirk@187
   247
    return color;
dirk@187
   248
}
dirk@187
   249
dirk@207
   250
DYNAMIC_API PEP_STATUS identity_rating(PEP_SESSION session, pEp_identity *ident, PEP_rating *color);
dirk@187
   251
dirk@187
   252
dirk@187
   253
- (NSArray *)trustwords:(NSString *)fpr forLanguage:(NSString *)languageID shortened:(BOOL)shortened
dirk@187
   254
{
dirk@187
   255
    NSMutableArray *array = [NSMutableArray array];
dirk@187
   256
dirk@187
   257
    for (int i = 0; i < [fpr length]; i += 4) {
dirk@187
   258
        if (shortened && i >= 20)
dirk@187
   259
            break;
dirk@207
   260
dirk@187
   261
        NSString *str = [fpr substringWithRange:NSMakeRange(i, 4)];
dirk@187
   262
dirk@187
   263
        unsigned int value;
dirk@187
   264
        [[NSScanner scannerWithString:str] scanHexInt:&value];
dirk@207
   265
dirk@187
   266
        char *word;
dirk@187
   267
        size_t size;
dirk@187
   268
dirk@187
   269
        @synchronized (self) {
dirk@187
   270
            trustword(_session, value, [languageID UTF8String], &word, &size);
dirk@187
   271
        }
dirk@187
   272
dirk@187
   273
        [array addObject:[NSString stringWithUTF8String:word]];
dirk@187
   274
        free(word);
dirk@187
   275
    }
dirk@207
   276
dirk@187
   277
    return array;
dirk@187
   278
}
dirk@187
   279
dirk@206
   280
- (void)mySelf:(PEPMutableDict *)identity
dirk@187
   281
{
dirk@187
   282
    [identity removeObjectForKey:kPepUserID];
dirk@187
   283
dirk@187
   284
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@187
   285
dirk@187
   286
    @synchronized(self) {
dirk@187
   287
        myself(_session, ident);
dirk@187
   288
    }
dirk@187
   289
dirk@187
   290
    [identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
dirk@187
   291
    free_identity(ident);
dirk@187
   292
}
dirk@187
   293
dirk@206
   294
- (void)updateIdentity:(PEPMutableDict *)identity
dirk@187
   295
{
dirk@187
   296
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@187
   297
dirk@187
   298
    @synchronized(self) {
dirk@187
   299
        update_identity(_session, ident);
dirk@187
   300
    }
dirk@187
   301
dirk@187
   302
    [identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
dirk@187
   303
    free_identity(ident);
dirk@187
   304
}
dirk@187
   305
dirk@206
   306
- (void)trustPersonalKey:(PEPMutableDict *)identity
dirk@187
   307
{
dirk@187
   308
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@207
   309
dirk@187
   310
    @synchronized(self) {
dirk@187
   311
        trust_personal_key(_session, ident);
dirk@187
   312
    }
dirk@207
   313
dirk@187
   314
    [identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
dirk@187
   315
    free_identity(ident);
dirk@187
   316
}
dirk@187
   317
dirk@206
   318
- (void)keyResetTrust:(PEPMutableDict *)identity
dirk@187
   319
{
dirk@187
   320
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@207
   321
dirk@187
   322
    @synchronized(self) {
dirk@187
   323
        key_reset_trust(_session, ident);
dirk@187
   324
    }
dirk@207
   325
dirk@187
   326
    [identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
dirk@187
   327
    free_identity(ident);
dirk@187
   328
}
dirk@187
   329
dirk@206
   330
- (void)keyMistrusted:(PEPMutableDict *)identity
dirk@187
   331
{
dirk@187
   332
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@207
   333
dirk@187
   334
    @synchronized(self) {
dirk@187
   335
        key_mistrusted(_session, ident);
dirk@187
   336
    }
dirk@207
   337
dirk@187
   338
    [identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
dirk@187
   339
    free_identity(ident);
dirk@187
   340
}
dirk@187
   341
dirk@187
   342
- (void)importKey:(NSString *)keydata
dirk@187
   343
{
dirk@187
   344
    @synchronized(self) {
dirk@187
   345
        import_key(_session, [keydata UTF8String], [keydata length], NULL);
dirk@187
   346
    }
dirk@187
   347
dirk@187
   348
}
dirk@187
   349
dirk@187
   350
- (void)logTitle:(nonnull NSString *)title entity:(nonnull NSString *)entity
dirk@187
   351
     description:(nullable NSString *)description comment:(nullable NSString *)comment
dirk@187
   352
{
dirk@187
   353
    log_event(self.session, [[title precomposedStringWithCanonicalMapping] UTF8String],
dirk@187
   354
              [[entity precomposedStringWithCanonicalMapping] UTF8String],
dirk@187
   355
              [[description precomposedStringWithCanonicalMapping] UTF8String],
dirk@187
   356
              [[comment precomposedStringWithCanonicalMapping] UTF8String]);
dirk@187
   357
}
dirk@187
   358
dirk@187
   359
- (nonnull NSString *)getLog
dirk@187
   360
{
dirk@187
   361
    char *data;
dirk@187
   362
    get_crashdump_log(self.session, 0, &data);
dirk@187
   363
    NSString *logString = [NSString stringWithUTF8String:data];
dirk@187
   364
    return logString;
dirk@187
   365
}
dirk@187
   366
dirk@206
   367
- (nullable NSString *)getTrustwordsIdentity1:(nonnull PEPDict *)identity1
dirk@206
   368
                                    identity2:(nonnull PEPDict *)identity2
dirk@187
   369
                                     language:(nullable NSString *)language
dirk@187
   370
                                         full:(BOOL)full
dirk@187
   371
{
dirk@187
   372
    NSString *result = nil;
dirk@187
   373
    char *trustwords = nil;
dirk@187
   374
    size_t sizeWritten = 0;
dirk@187
   375
dirk@187
   376
    pEp_identity *ident1 = PEP_identityDictToStruct(identity1);
dirk@187
   377
    pEp_identity *ident2 = PEP_identityDictToStruct(identity2);
dirk@202
   378
    PEP_STATUS status = get_trustwords(_session, ident1, ident2,
dirk@202
   379
                                       [[language precomposedStringWithCanonicalMapping]
dirk@202
   380
                                        UTF8String],
dirk@202
   381
                                       &trustwords, &sizeWritten, full);
dirk@202
   382
    if (status == PEP_STATUS_OK) {
dirk@202
   383
        result = [NSString stringWithCString:trustwords
dirk@202
   384
                                    encoding:NSUTF8StringEncoding];
dirk@202
   385
    }
dirk@202
   386
    if (trustwords) {
dirk@202
   387
        free(trustwords);
dirk@202
   388
    }
dirk@202
   389
    return result;
dirk@202
   390
}
dirk@202
   391
dirk@206
   392
- (nullable NSString *)getTrustwordsMessageDict:(nonnull PEPDict *)messageDict
dirk@206
   393
                                   receiverDict:(nonnull PEPDict *)receiverDict
dirk@206
   394
                                      keysArray:(PEPStringList * _Nullable)keysArray
dirk@202
   395
                                       language:(nullable NSString *)language
dirk@202
   396
                                           full:(BOOL)full
dirk@202
   397
{
dirk@202
   398
    NSString *result = nil;
dirk@202
   399
    char *trustwords = nil;
dirk@202
   400
dirk@202
   401
    message *theMessage = PEP_messageDictToStruct(messageDict);
dirk@202
   402
dirk@202
   403
    stringlist_t *keyList = nil;
dirk@202
   404
    if (keysArray) {
dirk@202
   405
        keyList = PEP_arrayToStringlist(keysArray);
dirk@202
   406
    }
dirk@202
   407
dirk@202
   408
    pEp_identity *receiver = PEP_identityDictToStruct(receiverDict);
dirk@202
   409
dirk@202
   410
    PEP_STATUS status = get_message_trustwords(_session, theMessage, keyList, receiver,
dirk@202
   411
                                               [[language
dirk@202
   412
                                                 precomposedStringWithCanonicalMapping] UTF8String],
dirk@202
   413
                                               &trustwords, full);
dirk@202
   414
dirk@187
   415
    if (status == PEP_STATUS_OK) {
dirk@187
   416
        result = [NSString stringWithCString:trustwords
dirk@187
   417
                                    encoding:NSUTF8StringEncoding];
dirk@187
   418
    }
dirk@187
   419
    if (trustwords) {
dirk@187
   420
        free(trustwords);
dirk@187
   421
    }
dirk@187
   422
    return result;
dirk@187
   423
}
dirk@187
   424
dirk@187
   425
- (NSArray<PEPLanguage *> * _Nonnull)languageList
dirk@187
   426
{
dirk@187
   427
    char *chLangs;
dirk@187
   428
    get_languagelist(self.session, &chLangs);
dirk@187
   429
    NSString *parserInput = [NSString stringWithUTF8String:chLangs];
dirk@187
   430
dirk@187
   431
    NSMutableArray<NSString *> *tokens = [NSMutableArray array];
dirk@187
   432
    PEPCSVScanner *scanner = [[PEPCSVScanner alloc] initWithString:parserInput];
dirk@187
   433
    while (YES) {
dirk@187
   434
        NSString *token = [scanner nextString];
dirk@187
   435
        if (!token) {
dirk@187
   436
            break;
dirk@187
   437
        }
dirk@187
   438
        [tokens addObject:token];
dirk@187
   439
    }
dirk@187
   440
dirk@187
   441
    NSArray *theTokens = [NSArray arrayWithArray:tokens];
dirk@187
   442
    NSMutableArray<PEPLanguage *> *langs = [NSMutableArray new];
dirk@187
   443
    while (YES) {
dirk@187
   444
        ArrayTake *take = [theTokens takeOrNil:3];
dirk@187
   445
        if (!take) {
dirk@187
   446
            break;
dirk@187
   447
        }
dirk@187
   448
        NSArray *elements = take.elements;
dirk@187
   449
        PEPLanguage *lang = [[PEPLanguage alloc]
dirk@187
   450
                             initWithCode:[elements objectAtIndex:0]
dirk@187
   451
                             name:[elements objectAtIndex:1]
dirk@187
   452
                             sentence:[elements objectAtIndex:2]];
dirk@187
   453
        [langs addObject:lang];
dirk@187
   454
        theTokens = take.rest;
dirk@187
   455
    }
dirk@207
   456
    
dirk@187
   457
    return [NSArray arrayWithArray:langs];
dirk@187
   458
}
dirk@187
   459
dirk@187
   460
@end