IOSAD-180 Own PEPPassphraseUtil

IOSAD-180
Dirk Zimmermann 3 years ago
parent f9d0be6145
commit 049705c9cb

@ -70,6 +70,7 @@
435F519022204A67006EB11F /* PEPSessionProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 435F518F22204A67006EB11F /* PEPSessionProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
4360AA0E2227F22900E62E5A /* PEPObjCAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 43209B2F1ECC2ACD007E7E2E /* PEPObjCAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; };
43676B661C57EA1A00233933 /* B623F674_sec.asc in Resources */ = {isa = PBXBuildFile; fileRef = 43676B641C57EA1A00233933 /* B623F674_sec.asc */; };
436C9A3324DC48B600007A3D /* PEPPassphraseUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 436C9A3224DC48B600007A3D /* PEPPassphraseUtil.m */; };
436E916E24B65805000296FF /* PEPPassphraseProviderProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 436E916D24B65805000296FF /* PEPPassphraseProviderProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
436E917224B714A2000296FF /* Rick Deckard (43F270EC) Secret.asc in Resources */ = {isa = PBXBuildFile; fileRef = 436E917124B714A1000296FF /* Rick Deckard (43F270EC) Secret.asc */; };
436E917724B71E12000296FF /* PEPPassphraseProviderMock.m in Sources */ = {isa = PBXBuildFile; fileRef = 436E917624B71E12000296FF /* PEPPassphraseProviderMock.m */; };
@ -215,6 +216,8 @@
4360A9FE2227EBB200E62E5A /* NSNumber+PEPRating+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSNumber+PEPRating+Internal.h"; sourceTree = "<group>"; };
43676B631C57EA1A00233933 /* 0xB623F674.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = 0xB623F674.asc; sourceTree = "<group>"; };
43676B641C57EA1A00233933 /* B623F674_sec.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = B623F674_sec.asc; sourceTree = "<group>"; };
436C9A3124DC48B600007A3D /* PEPPassphraseUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PEPPassphraseUtil.h; sourceTree = "<group>"; };
436C9A3224DC48B600007A3D /* PEPPassphraseUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PEPPassphraseUtil.m; sourceTree = "<group>"; };
436E916D24B65805000296FF /* PEPPassphraseProviderProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PEPPassphraseProviderProtocol.h; sourceTree = "<group>"; };
436E917124B714A1000296FF /* Rick Deckard (43F270EC) Secret.asc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Rick Deckard (43F270EC) Secret.asc"; sourceTree = "<group>"; };
436E917524B71E12000296FF /* PEPPassphraseProviderMock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PEPPassphraseProviderMock.h; sourceTree = "<group>"; };
@ -405,6 +408,8 @@
4349CD6D24AC73FC00A22A13 /* NSString+NormalizePassphrase.h */,
4349CD6E24AC73FC00A22A13 /* NSString+NormalizePassphrase.m */,
434707F524C210CA00E05485 /* PEPAsyncSession.m */,
436C9A3124DC48B600007A3D /* PEPPassphraseUtil.h */,
436C9A3224DC48B600007A3D /* PEPPassphraseUtil.m */,
);
path = pEpObjCAdapter;
sourceTree = "<group>";
@ -716,6 +721,7 @@
4396CECB2187220200FDD398 /* PEPSessionTestSendMessageDelegate.m in Sources */,
152D58EF201B6DB200036219 /* PEPMessageUtilTest.m in Sources */,
434707F924C30E9700E05485 /* PEPAsyncSessionTest.m in Sources */,
436C9A3324DC48B600007A3D /* PEPPassphraseUtil.m in Sources */,
152A9C472010F50400F962ED /* PEPSessionTest.m in Sources */,
434226811D4F60000083ED79 /* PepTests.m in Sources */,
4336853F203D5CE60069A451 /* PEPTestUtils.m in Sources */,

@ -0,0 +1,28 @@
//
// PEPPassphraseUtil.h
// pEpObjCAdapterTests
//
// Created by Dirk Zimmermann on 06.08.20.
// Copyright © 2020 p≡p. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "pEpEngine.h"
#import "PEPEngineTypes.h"
NS_ASSUME_NONNULL_BEGIN
@interface PEPPassphraseUtil : NSObject
/// Gets the currently cached passwords,
/// and executes the given block after setting each password in turn
/// until it returns something else other than PEP_PASSPHRASE_REQUIRED
/// or PEP_WRONG_PASSPHRASE, or there are no passwords anymore.
/// @param block The status-returning block to execute against different passwords
+ (PEPStatus)runWithPasswordsSession:(PEP_SESSION)session
block:(PEP_STATUS (^)(PEP_SESSION session))block;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,129 @@
//
// PEPPassphraseUtil.m
// pEpObjCAdapterTests
//
// Created by Dirk Zimmermann on 06.08.20.
// Copyright © 2020 pp. All rights reserved.
//
#import "PEPPassphraseUtil.h"
#import "pEpEngine.h"
#import "PEPPassphraseCache.h"
#import "PEPObjCAdapter+Internal.h"
#import "NSString+NormalizePassphrase.h"
@implementation PEPPassphraseUtil
+ (PEPStatus)runWithPasswordsSession:(PEP_SESSION)session
block:(PEP_STATUS (^)(PEP_SESSION session))block
{
PEP_STATUS lastStatus = PEP_UNKNOWN_ERROR;
NSMutableArray *passphrases = [NSMutableArray
arrayWithArray:[[PEPPassphraseCache passphraseCache] passphrases]];
[passphrases insertObject:@"" atIndex:0];
if ([[PEPPassphraseCache passphraseCache] storedPassphrase]) {
[passphrases insertObject:[[PEPPassphraseCache passphraseCache] storedPassphrase] atIndex:1];
}
for (NSString *passphrase in passphrases) {
PEP_STATUS status = config_passphrase(session, [passphrase UTF8String]);
if (status != PEPStatusOK) {
return (PEPStatus) status;
}
lastStatus = block(session);
if (lastStatus != PEP_PASSPHRASE_REQUIRED && lastStatus != PEP_WRONG_PASSPHRASE) {
// The passphrase worked, so reset its timeout
[[PEPPassphraseCache passphraseCache] resetTimeoutForPassphrase:passphrase];
return (PEPStatus) lastStatus;
}
}
// If execution lands here, it means we ran out of passwords to set while
// receiving password-related error codes.
return [self tryPassphraseProviderSession:session
lastStatus:lastStatus block:block];
}
#pragma mark - Private
/// Invokes the given block while setting passphrases requested from the
/// passphrase provider, if set.
+ (PEPStatus)tryPassphraseProviderSession:(PEP_SESSION)session
lastStatus:(PEP_STATUS)lastStatus
block:(PEP_STATUS (^)(PEP_SESSION session))block
{
id<PEPPassphraseProviderProtocol> passphraseProvider = [PEPObjCAdapter passphraseProvider];
if (passphraseProvider) {
dispatch_group_t group = dispatch_group_create();
__block PEP_STATUS lastPassphraseProviderStatus = lastStatus;
__block NSString *lastPassphrase = nil;
PEPPassphraseProviderCallback passphraseCallback = ^(NSString * _Nullable passphrase) {
lastPassphrase = passphrase;
dispatch_group_leave(group);
};
while (YES) {
if (lastPassphraseProviderStatus == PEP_PASSPHRASE_REQUIRED) {
dispatch_group_enter(group);
[passphraseProvider passphraseRequired:passphraseCallback];
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
} else if (lastPassphraseProviderStatus == PEP_WRONG_PASSPHRASE) {
dispatch_group_enter(group);
[passphraseProvider wrongPassphrase:passphraseCallback];
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
}
if (lastPassphrase == nil) {
return (PEPStatus) lastPassphraseProviderStatus;
}
NSString *normalizedPassphrase = [lastPassphrase normalizedPassphraseWithError:nil];
//Add the new passphrase to our cache to not having to bother the client again.
[[PEPPassphraseCache passphraseCache] addPassphrase:normalizedPassphrase];
if (normalizedPassphrase == nil) {
// Assume excessively long passphrase means PEP_WRONG_PASSPHRASE
lastPassphraseProviderStatus = PEP_WRONG_PASSPHRASE;
dispatch_group_enter(group);
[passphraseProvider passphraseTooLong:passphraseCallback];
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
continue;
}
lastPassphraseProviderStatus = config_passphrase(session,
[lastPassphrase UTF8String]);
if (lastPassphraseProviderStatus != PEPStatusOK) {
return (PEPStatus) lastPassphraseProviderStatus;
}
lastPassphraseProviderStatus = block(session);
if (lastPassphraseProviderStatus != PEP_PASSPHRASE_REQUIRED &&
lastPassphraseProviderStatus != PEP_WRONG_PASSPHRASE) {
// The passphrase worked, so reset its timeout
[[PEPPassphraseCache passphraseCache] resetTimeoutForPassphrase:lastPassphrase];
return (PEPStatus) lastPassphraseProviderStatus;
}
}
return (PEPStatus) lastPassphraseProviderStatus;
} else {
// no passphrase provider
return (PEPStatus) lastStatus;
}
}
@end
Loading…
Cancel
Save