You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

417 lines
11 KiB

//
// PEPSession.m
// pEpiOSAdapter
//
// Created by Volker Birk on 08.07.15.
// Copyright (c) 2015 p≡p. All rights reserved.
//
#import "PEPSession.h"
#import "PEPSession+Internal.h"
#import "PEPObjCAdapter.h"
#import "PEPObjCAdapter+Internal.h"
#import "PEPMessage.h"
#import "PEPLanguage.h"
#import "PEPCSVScanner.h"
#import "NSArray+Extension.h"
@implementation PEPSession
// serialize all session access
+ (dispatch_queue_t)sharedSessionQueue
{
static dispatch_once_t once;
static dispatch_queue_t sharedSessionQueue;
dispatch_once(&once, ^{
sharedSessionQueue = dispatch_queue_create("pEp session queue", DISPATCH_QUEUE_CONCURRENT);
});
return sharedSessionQueue;
}
+ (PEPSession *)session
{
PEPSession *_session = [[PEPSession alloc] init];
return _session;
}
+ (void)dispatchAsyncOnSession:(PEPSessionBlock)block
{
dispatch_async([self sharedSessionQueue], ^{
PEPSession *pepSession = [[PEPSession alloc] init];
block(pepSession);
});
}
+ (void)dispatchSyncOnSession:(PEPSessionBlock)block
{
PEPSession *pepSession = [[PEPSession alloc] init];
block(pepSession);
}
+ (void)setupTrustWordsDB
{
static dispatch_once_t once;
dispatch_once(&once, ^{
[PEPObjCAdapter setupTrustWordsDB:[NSBundle bundleForClass:[self class]]];
});
}
- (id)init
{
[PEPSession setupTrustWordsDB];
PEP_STATUS status = init(&_session);
if (status != PEP_STATUS_OK) {
return nil;
}
[PEPObjCAdapter bindSession:self];
return self;
}
- (void)dealloc
{
[PEPObjCAdapter unbindSession:self];
release(_session);
}
- (PEP_rating)decryptMessageDict:(nonnull NSDictionary<NSString *, id> *)src
dest:(NSDictionary<NSString *, id> * _Nullable * _Nullable)dst
keys:(NSArray<NSString *> * _Nullable * _Nullable)keys
{
message * _src = PEP_messageDictToStruct(src);
message * _dst = NULL;
stringlist_t * _keys = NULL;
PEP_rating color = PEP_rating_undefined;
PEP_decrypt_flags_t flags = 0;
@synchronized (self) {
decrypt_message(_session, _src, &_dst, &_keys, &color, &flags);
}
NSDictionary * dst_;
if (_dst) {
dst_ = PEP_messageDictFromStruct(_dst);
}
else {
dst_ = PEP_messageDictFromStruct(_src);
}
NSArray * keys_ = nil;
if (_keys)
keys_ = PEP_arrayFromStringlist(_keys);
free_message(_src);
free_message(_dst);
free_stringlist(_keys);
if (dst) {
*dst = dst_;
}
if (keys) {
*keys = keys_;
}
return color;
}
- (void)removeEmptyArrayKey:(NSString *)key inDict:(NSMutableDictionary<NSString *, id> *)dict
{
if ([[dict objectForKey:key] count] == 0) {
[dict removeObjectForKey:key];
}
}
- (NSDictionary *)removeEmptyRecipients:(NSDictionary<NSString *, id> *)src
{
NSMutableDictionary *dest = src.mutableCopy;
[self removeEmptyArrayKey:kPepTo inDict:dest];
[self removeEmptyArrayKey:kPepCC inDict:dest];
[self removeEmptyArrayKey:kPepBCC inDict:dest];
return [NSDictionary dictionaryWithDictionary:dest];
}
- (PEP_STATUS)encryptMessageDict:(nonnull NSDictionary<NSString *, id> *)src
extra:(nullable NSArray *)keys
dest:(NSDictionary<NSString *, id> * _Nullable * _Nullable)dst
{
PEP_STATUS status;
PEP_encrypt_flags_t flags = 0;
message * _src = PEP_messageDictToStruct([self removeEmptyRecipients:src]);
message * _dst = NULL;
stringlist_t * _keys = PEP_arrayToStringlist(keys);
@synchronized (self) {
status = encrypt_message(_session, _src, _keys, &_dst, PEP_enc_PGP_MIME, flags);
}
NSDictionary * dst_;
if (_dst) {
dst_ = PEP_messageDictFromStruct(_dst);
}
else {
dst_ = PEP_messageDictFromStruct(_src);
}
if (dst) {
*dst = dst_;
}
free_message(_src);
free_message(_dst);
free_stringlist(_keys);
return status;
}
- (PEP_STATUS)encryptMessageDict:(nonnull NSDictionary<NSString *, id> *)src
identity:(nonnull NSDictionary<NSString *, id> *)identity
dest:(NSDictionary<NSString *, id> * _Nullable * _Nullable)dst
{
PEP_STATUS status;
PEP_encrypt_flags_t flags = 0;
message * _src = PEP_messageDictToStruct([self removeEmptyRecipients:src]);
pEp_identity *ident = PEP_identityDictToStruct(identity);
message * _dst = NULL;
@synchronized (self) {
status = encrypt_message_for_self(_session, ident, _src, &_dst, PEP_enc_PGP_MIME, flags);
}
NSDictionary * dst_;
if (_dst) {
dst_ = PEP_messageDictFromStruct(_dst);
}
else {
dst_ = PEP_messageDictFromStruct(_src);
}
if (dst) {
*dst = dst_;
}
free_message(_src);
free_message(_dst);
free_identity(ident);
return status;
}
- (PEP_rating)outgoingMessageColor:(NSDictionary<NSString *, id> *)msg
{
message * _msg = PEP_messageDictToStruct(msg);
PEP_rating color = PEP_rating_undefined;
@synchronized (self) {
outgoing_message_rating(_session, _msg, &color);
}
free_message(_msg);
return color;
}
- (PEP_rating)identityRating:(nonnull NSDictionary<NSString *, id> *)identity
{
pEp_identity *ident = PEP_identityDictToStruct(identity);
PEP_rating color = PEP_rating_undefined;
@synchronized (self) {
identity_rating(_session, ident, &color);
}
free_identity(ident);
return color;
}
DYNAMIC_API PEP_STATUS identity_rating(
PEP_SESSION session,
pEp_identity *ident,
PEP_rating *color
);
- (NSArray *)trustwords:(NSString *)fpr forLanguage:(NSString *)languageID shortened:(BOOL)shortened
{
NSMutableArray *array = [NSMutableArray array];
for (int i = 0; i < [fpr length]; i += 4) {
if (shortened && i >= 20)
break;
NSString *str = [fpr substringWithRange:NSMakeRange(i, 4)];
unsigned int value;
[[NSScanner scannerWithString:str] scanHexInt:&value];
char *word;
size_t size;
@synchronized (self) {
trustword(_session, value, [languageID UTF8String], &word, &size);
}
[array addObject:[NSString stringWithUTF8String:word]];
free(word);
}
return array;
}
- (void)mySelf:(NSMutableDictionary<NSString *, id> *)identity
{
[identity removeObjectForKey:kPepUserID];
pEp_identity *ident = PEP_identityDictToStruct(identity);
@synchronized(self) {
myself(_session, ident);
}
[identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
free_identity(ident);
}
- (void)updateIdentity:(NSMutableDictionary<NSString *, id> *)identity
{
pEp_identity *ident = PEP_identityDictToStruct(identity);
@synchronized(self) {
update_identity(_session, ident);
}
[identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
free_identity(ident);
}
- (void)trustPersonalKey:(NSMutableDictionary<NSString *, id> *)identity
{
pEp_identity *ident = PEP_identityDictToStruct(identity);
@synchronized(self) {
trust_personal_key(_session, ident);
}
[identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
free_identity(ident);
}
- (void)keyResetTrust:(NSMutableDictionary<NSString *, id> *)identity
{
pEp_identity *ident = PEP_identityDictToStruct(identity);
@synchronized(self) {
key_reset_trust(_session, ident);
}
[identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
free_identity(ident);
}
- (void)keyMistrusted:(NSMutableDictionary<NSString *, id> *)identity
{
pEp_identity *ident = PEP_identityDictToStruct(identity);
@synchronized(self) {
key_mistrusted(_session, ident);
}
[identity setValuesForKeysWithDictionary:PEP_identityDictFromStruct(ident)];
free_identity(ident);
}
- (void)importKey:(NSString *)keydata
{
@synchronized(self) {
import_key(_session, [keydata UTF8String], [keydata length], NULL);
}
}
- (void)logTitle:(nonnull NSString *)title entity:(nonnull NSString *)entity
description:(nullable NSString *)description comment:(nullable NSString *)comment
{
log_event(self.session, [[title precomposedStringWithCanonicalMapping] UTF8String],
[[entity precomposedStringWithCanonicalMapping] UTF8String],
[[description precomposedStringWithCanonicalMapping] UTF8String],
[[comment precomposedStringWithCanonicalMapping] UTF8String]);
}
- (nonnull NSString *)getLog
{
char *data;
get_crashdump_log(self.session, 0, &data);
NSString *logString = [NSString stringWithUTF8String:data];
return logString;
}
- (nullable NSString *)getTrustwordsIdentity1:(nonnull NSDictionary<NSString *, id> *)identity1
identity2:(nonnull NSDictionary<NSString *, id> *)identity2
language:(nullable NSString *)language
full:(BOOL)full
{
NSString *result = nil;
char *trustwords = nil;
size_t sizeWritten = 0;
pEp_identity *ident1 = PEP_identityDictToStruct(identity1);
pEp_identity *ident2 = PEP_identityDictToStruct(identity2);
PEP_STATUS status = get_trustwords(_session, ident1, ident2,
[[language precomposedStringWithCanonicalMapping]
UTF8String],
&trustwords, &sizeWritten, full);
if (status == PEP_STATUS_OK) {
result = [NSString stringWithCString:trustwords
encoding:NSUTF8StringEncoding];
}
if (trustwords) {
free(trustwords);
}
return result;
}
- (NSArray<PEPLanguage *> * _Nonnull)languageList
{
char *chLangs;
get_languagelist(self.session, &chLangs);
NSString *parserInput = [NSString stringWithUTF8String:chLangs];
NSMutableArray<NSString *> *tokens = [NSMutableArray array];
PEPCSVScanner *scanner = [[PEPCSVScanner alloc] initWithString:parserInput];
while (YES) {
NSString *token = [scanner nextString];
if (!token) {
break;
}
[tokens addObject:token];
}
NSArray *theTokens = [NSArray arrayWithArray:tokens];
NSMutableArray<PEPLanguage *> *langs = [NSMutableArray new];
while (YES) {
ArrayTake *take = [theTokens takeOrNil:3];
if (!take) {
break;
}
NSArray *elements = take.elements;
PEPLanguage *lang = [[PEPLanguage alloc]
initWithCode:[elements objectAtIndex:0]
name:[elements objectAtIndex:1]
sentence:[elements objectAtIndex:2]];
[langs addObject:lang];
theTokens = take.rest;
}
return [NSArray arrayWithArray:langs];
}
@end