IOSAD-180 Own PEPPassphraseUtil
parent
f9d0be6145
commit
049705c9cb
@ -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 p≡p. 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…
Reference in New Issue