pEpObjCAdapter/PEPSession.m
author Edouard Tisserant <edouard@pep-project.org>
Tue, 06 Jun 2017 15:32:01 +0200
changeset 196 d660aae03056
parent 187 1f630a05e444
child 202 9887f3326221
permissions -rw-r--r--
ENGINE-179 added reEvaluateMessageRating, calling engine's re_evaluate_message_rating
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@187
    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@187
    77
    
dirk@187
    78
    release(_session);
dirk@187
    79
}
dirk@187
    80
dirk@187
    81
- (PEP_rating)decryptMessageDict:(nonnull NSDictionary<NSString *, id> *)src
dirk@187
    82
                            dest:(NSDictionary<NSString *, id> * _Nullable * _Nullable)dst
dirk@187
    83
                            keys:(NSArray<NSString *> * _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
edouard@196
   121
- (PEP_rating)reEvaluateMessageRating:(nonnull NSDictionary<NSString *, id> *)src
edouard@196
   122
{
edouard@196
   123
    message * _src = PEP_messageDictToStruct(src);
edouard@196
   124
    PEP_rating color = PEP_rating_undefined;
edouard@196
   125
    
edouard@196
   126
    @synchronized (self) {
edouard@196
   127
        re_evaluate_message_rating(_session, _src, NULL, PEP_rating_undefined, &color);
edouard@196
   128
    }
edouard@196
   129
    
edouard@196
   130
    free_message(_src);
edouard@196
   131
    
edouard@196
   132
    return color;
edouard@196
   133
}
edouard@196
   134
dirk@187
   135
- (void)removeEmptyArrayKey:(NSString *)key inDict:(NSMutableDictionary<NSString *, id> *)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@187
   142
- (NSDictionary *)removeEmptyRecipients:(NSDictionary<NSString *, id> *)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@187
   153
- (PEP_STATUS)encryptMessageDict:(nonnull NSDictionary<NSString *, id> *)src
dirk@187
   154
                           extra:(nullable NSArray *)keys
dirk@187
   155
                            dest:(NSDictionary<NSString *, id> * _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@187
   183
    
dirk@187
   184
    return status;
dirk@187
   185
}
dirk@187
   186
dirk@187
   187
- (PEP_STATUS)encryptMessageDict:(nonnull NSDictionary<NSString *, id> *)src
dirk@187
   188
                        identity:(nonnull NSDictionary<NSString *, id> *)identity
dirk@187
   189
                            dest:(NSDictionary<NSString *, id> * _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@187
   222
- (PEP_rating)outgoingMessageColor:(NSDictionary<NSString *, id> *)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@187
   232
    
dirk@187
   233
    return color;
dirk@187
   234
}
dirk@187
   235
dirk@187
   236
- (PEP_rating)identityRating:(nonnull NSDictionary<NSString *, id> *)identity
dirk@187
   237
{
dirk@187
   238
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@187
   239
    PEP_rating color = PEP_rating_undefined;
dirk@187
   240
    
dirk@187
   241
    @synchronized (self) {
dirk@187
   242
        identity_rating(_session, ident, &color);
dirk@187
   243
    }
dirk@187
   244
    
dirk@187
   245
    free_identity(ident);
dirk@187
   246
    
dirk@187
   247
    return color;
dirk@187
   248
}
dirk@187
   249
dirk@187
   250
DYNAMIC_API PEP_STATUS identity_rating(
dirk@187
   251
                                      PEP_SESSION session,
dirk@187
   252
                                      pEp_identity *ident,
dirk@187
   253
                                      PEP_rating *color
dirk@187
   254
                                      );
dirk@187
   255
dirk@187
   256
dirk@187
   257
- (NSArray *)trustwords:(NSString *)fpr forLanguage:(NSString *)languageID shortened:(BOOL)shortened
dirk@187
   258
{
dirk@187
   259
    NSMutableArray *array = [NSMutableArray array];
dirk@187
   260
dirk@187
   261
    for (int i = 0; i < [fpr length]; i += 4) {
dirk@187
   262
        if (shortened && i >= 20)
dirk@187
   263
            break;
dirk@187
   264
        
dirk@187
   265
        NSString *str = [fpr substringWithRange:NSMakeRange(i, 4)];
dirk@187
   266
dirk@187
   267
        unsigned int value;
dirk@187
   268
        [[NSScanner scannerWithString:str] scanHexInt:&value];
dirk@187
   269
        
dirk@187
   270
        char *word;
dirk@187
   271
        size_t size;
dirk@187
   272
dirk@187
   273
        @synchronized (self) {
dirk@187
   274
            trustword(_session, value, [languageID UTF8String], &word, &size);
dirk@187
   275
        }
dirk@187
   276
dirk@187
   277
        [array addObject:[NSString stringWithUTF8String:word]];
dirk@187
   278
        free(word);
dirk@187
   279
    }
dirk@187
   280
    
dirk@187
   281
    return array;
dirk@187
   282
}
dirk@187
   283
dirk@187
   284
- (void)mySelf:(NSMutableDictionary<NSString *, id> *)identity
dirk@187
   285
{
dirk@187
   286
    [identity removeObjectForKey:kPepUserID];
dirk@187
   287
dirk@187
   288
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@187
   289
dirk@187
   290
    @synchronized(self) {
dirk@187
   291
        myself(_session, ident);
dirk@187
   292
    }
dirk@187
   293
dirk@187
   294
    [identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
dirk@187
   295
    free_identity(ident);
dirk@187
   296
}
dirk@187
   297
dirk@187
   298
- (void)updateIdentity:(NSMutableDictionary<NSString *, id> *)identity
dirk@187
   299
{
dirk@187
   300
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@187
   301
dirk@187
   302
    @synchronized(self) {
dirk@187
   303
        update_identity(_session, ident);
dirk@187
   304
    }
dirk@187
   305
dirk@187
   306
    [identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
dirk@187
   307
    free_identity(ident);
dirk@187
   308
}
dirk@187
   309
dirk@187
   310
- (void)trustPersonalKey:(NSMutableDictionary<NSString *, id> *)identity
dirk@187
   311
{
dirk@187
   312
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@187
   313
    
dirk@187
   314
    @synchronized(self) {
dirk@187
   315
        trust_personal_key(_session, ident);
dirk@187
   316
    }
dirk@187
   317
    
dirk@187
   318
    [identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
dirk@187
   319
    free_identity(ident);
dirk@187
   320
}
dirk@187
   321
dirk@187
   322
- (void)keyResetTrust:(NSMutableDictionary<NSString *, id> *)identity
dirk@187
   323
{
dirk@187
   324
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@187
   325
    
dirk@187
   326
    @synchronized(self) {
dirk@187
   327
        key_reset_trust(_session, ident);
dirk@187
   328
    }
dirk@187
   329
    
dirk@187
   330
    [identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
dirk@187
   331
    free_identity(ident);
dirk@187
   332
}
dirk@187
   333
dirk@187
   334
- (void)keyMistrusted:(NSMutableDictionary<NSString *, id> *)identity
dirk@187
   335
{
dirk@187
   336
    pEp_identity *ident = PEP_identityDictToStruct(identity);
dirk@187
   337
    
dirk@187
   338
    @synchronized(self) {
dirk@187
   339
        key_mistrusted(_session, ident);
dirk@187
   340
    }
dirk@187
   341
    
dirk@187
   342
    [identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
dirk@187
   343
    free_identity(ident);
dirk@187
   344
}
dirk@187
   345
dirk@187
   346
- (void)importKey:(NSString *)keydata
dirk@187
   347
{
dirk@187
   348
    @synchronized(self) {
dirk@187
   349
        import_key(_session, [keydata UTF8String], [keydata length], NULL);
dirk@187
   350
    }
dirk@187
   351
dirk@187
   352
}
dirk@187
   353
dirk@187
   354
- (void)logTitle:(nonnull NSString *)title entity:(nonnull NSString *)entity
dirk@187
   355
     description:(nullable NSString *)description comment:(nullable NSString *)comment
dirk@187
   356
{
dirk@187
   357
    log_event(self.session, [[title precomposedStringWithCanonicalMapping] UTF8String],
dirk@187
   358
              [[entity precomposedStringWithCanonicalMapping] UTF8String],
dirk@187
   359
              [[description precomposedStringWithCanonicalMapping] UTF8String],
dirk@187
   360
              [[comment precomposedStringWithCanonicalMapping] UTF8String]);
dirk@187
   361
}
dirk@187
   362
dirk@187
   363
- (nonnull NSString *)getLog
dirk@187
   364
{
dirk@187
   365
    char *data;
dirk@187
   366
    get_crashdump_log(self.session, 0, &data);
dirk@187
   367
    NSString *logString = [NSString stringWithUTF8String:data];
dirk@187
   368
    return logString;
dirk@187
   369
}
dirk@187
   370
dirk@187
   371
- (nullable NSString *)getTrustwordsIdentity1:(nonnull NSDictionary<NSString *, id> *)identity1
dirk@187
   372
                                    identity2:(nonnull NSDictionary<NSString *, id> *)identity2
dirk@187
   373
                                     language:(nullable NSString *)language
dirk@187
   374
                                         full:(BOOL)full
dirk@187
   375
{
dirk@187
   376
    NSString *result = nil;
dirk@187
   377
    char *trustwords = nil;
dirk@187
   378
    size_t sizeWritten = 0;
dirk@187
   379
dirk@187
   380
    pEp_identity *ident1 = PEP_identityDictToStruct(identity1);
dirk@187
   381
    pEp_identity *ident2 = PEP_identityDictToStruct(identity2);
dirk@187
   382
    PEP_STATUS status =  get_trustwords(_session, ident1, ident2,
dirk@187
   383
                                        [[language precomposedStringWithCanonicalMapping]
dirk@187
   384
                                         UTF8String],
dirk@187
   385
                                        &trustwords, &sizeWritten, full);
dirk@187
   386
    if (status == PEP_STATUS_OK) {
dirk@187
   387
        result = [NSString stringWithCString:trustwords
dirk@187
   388
                                    encoding:NSUTF8StringEncoding];
dirk@187
   389
    }
dirk@187
   390
    if (trustwords) {
dirk@187
   391
        free(trustwords);
dirk@187
   392
    }
dirk@187
   393
    return result;
dirk@187
   394
}
dirk@187
   395
dirk@187
   396
- (NSArray<PEPLanguage *> * _Nonnull)languageList
dirk@187
   397
{
dirk@187
   398
    char *chLangs;
dirk@187
   399
    get_languagelist(self.session, &chLangs);
dirk@187
   400
    NSString *parserInput = [NSString stringWithUTF8String:chLangs];
dirk@187
   401
dirk@187
   402
    NSMutableArray<NSString *> *tokens = [NSMutableArray array];
dirk@187
   403
    PEPCSVScanner *scanner = [[PEPCSVScanner alloc] initWithString:parserInput];
dirk@187
   404
    while (YES) {
dirk@187
   405
        NSString *token = [scanner nextString];
dirk@187
   406
        if (!token) {
dirk@187
   407
            break;
dirk@187
   408
        }
dirk@187
   409
        [tokens addObject:token];
dirk@187
   410
    }
dirk@187
   411
dirk@187
   412
    NSArray *theTokens = [NSArray arrayWithArray:tokens];
dirk@187
   413
    NSMutableArray<PEPLanguage *> *langs = [NSMutableArray new];
dirk@187
   414
    while (YES) {
dirk@187
   415
        ArrayTake *take = [theTokens takeOrNil:3];
dirk@187
   416
        if (!take) {
dirk@187
   417
            break;
dirk@187
   418
        }
dirk@187
   419
        NSArray *elements = take.elements;
dirk@187
   420
        PEPLanguage *lang = [[PEPLanguage alloc]
dirk@187
   421
                             initWithCode:[elements objectAtIndex:0]
dirk@187
   422
                             name:[elements objectAtIndex:1]
dirk@187
   423
                             sentence:[elements objectAtIndex:2]];
dirk@187
   424
        [langs addObject:lang];
dirk@187
   425
        theTokens = take.rest;
dirk@187
   426
    }
dirk@187
   427
dirk@187
   428
    return [NSArray arrayWithArray:langs];
dirk@187
   429
}
dirk@187
   430
dirk@187
   431
@end