pEpObjCAdapter/PEPPassphraseCache.m
author Dirk Zimmermann <dz@pep.security>
Fri, 26 Jun 2020 16:54:34 +0200
branchIOSAD-172
changeset 1475 cf82c13266ac
parent 1474 a37a548a6b3b
child 1476 388741294076
permissions -rw-r--r--
IOSAD-172 Handle the timer
dz@1449
     1
//
dz@1449
     2
//  PEPPassphraseCache.m
dz@1449
     3
//  pEpObjCAdapter
dz@1449
     4
//
dz@1449
     5
//  Created by Dirk Zimmermann on 25.06.20.
dz@1449
     6
//  Copyright © 2020 p≡p. All rights reserved.
dz@1449
     7
//
dz@1449
     8
dz@1449
     9
#import "PEPPassphraseCache.h"
dz@1449
    10
dz@1469
    11
#import "PEPPassphraseCacheInternal.h"
dz@1469
    12
dz@1467
    13
#import "PEPPassphraseCacheEntry.h"
dz@1467
    14
dz@1460
    15
static NSUInteger s_maxNumberOfPassphrases = 20;
dz@1468
    16
static NSTimeInterval s_defaultTimeoutInSeconds = 10 * 60;
dz@1474
    17
static NSTimeInterval s_defaultCheckExpiryInterval = 60;
dz@1457
    18
dz@1454
    19
@interface PEPPassphraseCache ()
dz@1454
    20
dz@1456
    21
@property (nonatomic) dispatch_queue_t queue;
dz@1467
    22
@property (nonatomic) NSMutableArray<PEPPassphraseCacheEntry *> *mutablePassphrases;
dz@1475
    23
@property (nonatomic) NSTimer *checkExpiryTimer;
dz@1456
    24
dz@1454
    25
@end
dz@1454
    26
dz@1449
    27
@implementation PEPPassphraseCache
dz@1449
    28
dz@1449
    29
/// Internal constructor (for now).
dz@1474
    30
- (instancetype)initWithPassphraseTimeout:(NSTimeInterval)timeout
dz@1474
    31
                      checkExpiryInterval:(NSTimeInterval)checkExpiryInterval
dz@1449
    32
{
dz@1449
    33
    self = [super init];
dz@1449
    34
    if (self) {
dz@1449
    35
        _timeout = timeout;
dz@1456
    36
        _queue = dispatch_queue_create("PEPPassphraseCache Queue", DISPATCH_QUEUE_SERIAL);
dz@1460
    37
        _mutablePassphrases = [NSMutableArray arrayWithCapacity:s_maxNumberOfPassphrases];
dz@1475
    38
dz@1475
    39
        // we have a strong reference to the timer, but the timer doesn't have one to us
dz@1475
    40
        typeof(self) __weak weakSelf = self;
dz@1475
    41
        _checkExpiryTimer = [NSTimer
dz@1475
    42
                             scheduledTimerWithTimeInterval:checkExpiryInterval
dz@1475
    43
                             repeats:YES
dz@1475
    44
                             block:^(NSTimer *timer) {
dz@1475
    45
            [weakSelf removeStaleEntries];
dz@1475
    46
        }];
dz@1449
    47
    }
dz@1449
    48
    return self;
dz@1449
    49
}
dz@1449
    50
dz@1475
    51
- (void)dealloc
dz@1475
    52
{
dz@1475
    53
    [_checkExpiryTimer invalidate];
dz@1475
    54
}
dz@1475
    55
dz@1449
    56
/// Public constructor with default values.
dz@1449
    57
- (instancetype)init
dz@1449
    58
{
dz@1474
    59
    return [self initWithPassphraseTimeout:s_defaultTimeoutInSeconds
dz@1474
    60
                       checkExpiryInterval:s_defaultCheckExpiryInterval];
dz@1449
    61
}
dz@1449
    62
dz@1449
    63
- (void)addPassphrase:(NSString *)passphrase
dz@1449
    64
{
dz@1467
    65
    PEPPassphraseCacheEntry *entry = [[PEPPassphraseCacheEntry alloc]
dz@1467
    66
                                      initWithPassphrase:passphrase];
dz@1459
    67
    dispatch_sync(self.queue, ^{
dz@1467
    68
        [self.mutablePassphrases addObject:entry];
dz@1460
    69
        if (self.mutablePassphrases.count > s_maxNumberOfPassphrases) {
dz@1459
    70
            [self.mutablePassphrases removeObjectAtIndex:0];
dz@1459
    71
        }
dz@1459
    72
    });
dz@1449
    73
}
dz@1449
    74
dz@1449
    75
- (NSArray *)passphrases
dz@1449
    76
{
dz@1457
    77
    NSMutableArray *resultingPassphrases = [NSMutableArray
dz@1460
    78
                                            arrayWithCapacity:s_maxNumberOfPassphrases + 1];
dz@1457
    79
    [resultingPassphrases addObject:@""];
dz@1457
    80
    dispatch_sync(self.queue, ^{
dz@1467
    81
        for (PEPPassphraseCacheEntry *entry in self.mutablePassphrases) {
dz@1467
    82
            [resultingPassphrases addObject:entry.passphrase];
dz@1457
    83
        }
dz@1457
    84
    });
dz@1457
    85
    return [NSArray arrayWithArray:resultingPassphrases];
dz@1449
    86
}
dz@1449
    87
dz@1468
    88
/// Remove password entries that have timed out.
dz@1468
    89
- (void)removeStaleEntries
dz@1468
    90
{
dz@1468
    91
    NSDate *now = [NSDate date];
dz@1468
    92
    NSDate *minimum = [now dateByAddingTimeInterval:-s_defaultTimeoutInSeconds];
dz@1468
    93
    NSTimeInterval minimumTimeInterval = [minimum timeIntervalSinceReferenceDate];
dz@1468
    94
    dispatch_sync(self.queue, ^{
dz@1468
    95
        NSMutableArray *resultingPassphrases = [NSMutableArray
dz@1468
    96
                                                arrayWithCapacity:s_maxNumberOfPassphrases];
dz@1468
    97
dz@1468
    98
        for (PEPPassphraseCacheEntry *entry in self.mutablePassphrases) {
dz@1468
    99
            if ([entry.dateAdded timeIntervalSinceReferenceDate] >= minimumTimeInterval) {
dz@1468
   100
                [resultingPassphrases addObject:entry];
dz@1468
   101
            }
dz@1468
   102
        }
dz@1468
   103
dz@1468
   104
        [self.mutablePassphrases removeAllObjects];
dz@1468
   105
        [self.mutablePassphrases addObjectsFromArray:resultingPassphrases];
dz@1468
   106
    });
dz@1468
   107
}
dz@1468
   108
dz@1449
   109
@end