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