iOS: Add initial parts of support for key files

This commit is contained in:
Jonathan Schleifer 2017-11-26 21:09:53 +01:00
parent f886262722
commit fa21a9d8f3
No known key found for this signature in database
GPG key ID: 28D65178B37F33E3
13 changed files with 226 additions and 99 deletions

View file

@ -26,7 +26,7 @@
{ {
size_t _length; size_t _length;
OFString *_site; OFString *_site;
OFData *_keyfile; OFData *_keyFile;
const char *_passphrase; const char *_passphrase;
unsigned char *_output; unsigned char *_output;
} }

View file

@ -23,7 +23,7 @@
#import "LegacyPasswordGenerator.h" #import "LegacyPasswordGenerator.h"
@implementation LegacyPasswordGenerator @implementation LegacyPasswordGenerator
@synthesize site = _site, keyfile = _keyfile, passphrase = _passphrase; @synthesize site = _site, keyFile = _keyFile, passphrase = _passphrase;
@synthesize output = _output; @synthesize output = _output;
+ (instancetype)generator + (instancetype)generator
@ -70,11 +70,11 @@
_output = [self allocMemoryWithSize: _length + 1]; _output = [self allocMemoryWithSize: _length + 1];
passphraseLength = combinedPassphraseLength = strlen(_passphrase); passphraseLength = combinedPassphraseLength = strlen(_passphrase);
if (_keyfile != nil) { if (_keyFile != nil) {
if (SIZE_MAX - combinedPassphraseLength < _keyfile.count) if (SIZE_MAX - combinedPassphraseLength < _keyFile.count)
@throw [OFOutOfRangeException exception]; @throw [OFOutOfRangeException exception];
combinedPassphraseLength += _keyfile.count; combinedPassphraseLength += _keyFile.count;
} }
if ((combinedPassphrase = malloc(combinedPassphraseLength)) == NULL) if ((combinedPassphrase = malloc(combinedPassphraseLength)) == NULL)
@ -83,9 +83,9 @@
@try { @try {
memcpy(combinedPassphrase, _passphrase, passphraseLength); memcpy(combinedPassphrase, _passphrase, passphraseLength);
if (_keyfile != nil) if (_keyFile != nil)
memcpy(combinedPassphrase + passphraseLength, memcpy(combinedPassphrase + passphraseLength,
_keyfile.items, _keyfile.count); _keyFile.items, _keyFile.count);
of_scrypt(8, 524288, 2, siteHash.digest, of_scrypt(8, 524288, 2, siteHash.digest,
[siteHash.class digestSize], combinedPassphrase, [siteHash.class digestSize], combinedPassphrase,

View file

@ -26,7 +26,7 @@
{ {
size_t _length; size_t _length;
OFString *_site; OFString *_site;
OFData *_keyfile; OFData *_keyFile;
const char *_passphrase; const char *_passphrase;
unsigned char *_output; unsigned char *_output;
} }

View file

@ -23,7 +23,7 @@
#import "NewPasswordGenerator.h" #import "NewPasswordGenerator.h"
@implementation NewPasswordGenerator @implementation NewPasswordGenerator
@synthesize length = _length, site = _site, keyfile = _keyfile; @synthesize length = _length, site = _site, keyFile = _keyFile;
@synthesize passphrase = _passphrase, output = _output; @synthesize passphrase = _passphrase, output = _output;
+ (instancetype)generator + (instancetype)generator
@ -57,11 +57,11 @@
_output = [self allocMemoryWithSize: _length + 1]; _output = [self allocMemoryWithSize: _length + 1];
passphraseLength = combinedPassphraseLength = strlen(_passphrase); passphraseLength = combinedPassphraseLength = strlen(_passphrase);
if (_keyfile != nil) { if (_keyFile != nil) {
if (SIZE_MAX - combinedPassphraseLength < _keyfile.count) if (SIZE_MAX - combinedPassphraseLength < _keyFile.count)
@throw [OFOutOfRangeException exception]; @throw [OFOutOfRangeException exception];
combinedPassphraseLength += _keyfile.count; combinedPassphraseLength += _keyFile.count;
} }
if ((combinedPassphrase = malloc(combinedPassphraseLength)) == NULL) if ((combinedPassphrase = malloc(combinedPassphraseLength)) == NULL)
@ -70,9 +70,9 @@
@try { @try {
memcpy(combinedPassphrase, _passphrase, passphraseLength); memcpy(combinedPassphrase, _passphrase, passphraseLength);
if (_keyfile != nil) if (_keyFile != nil)
memcpy(combinedPassphrase + passphraseLength, memcpy(combinedPassphrase + passphraseLength,
_keyfile.items, _keyfile.count); _keyFile.items, _keyFile.count);
of_scrypt(8, 524288, 2, siteHash.digest, of_scrypt(8, 524288, 2, siteHash.digest,
[siteHash.class digestSize], combinedPassphrase, [siteHash.class digestSize], combinedPassphrase,

View file

@ -25,7 +25,7 @@
@protocol PasswordGenerator @protocol PasswordGenerator
@property (nonatomic) size_t length; @property (nonatomic) size_t length;
@property (copy, nonatomic) OFString *site; @property (copy, nonatomic) OFString *site;
@property (retain, nonatomic) OFData *keyfile; @property (retain, nonatomic) OFData *keyFile;
@property (nonatomic) const char *passphrase; @property (nonatomic) const char *passphrase;
@property (readonly, nonatomic) unsigned char *output; @property (readonly, nonatomic) unsigned char *output;

View file

@ -49,10 +49,10 @@ showHelp(OFStream *output, bool verbose)
@implementation ScryptPWGen @implementation ScryptPWGen
- (void)applicationDidFinishLaunching - (void)applicationDidFinishLaunching
{ {
OFString *keyfilePath, *lengthString; OFString *keyFilePath, *lengthString;
const of_options_parser_option_t options[] = { const of_options_parser_option_t options[] = {
{ 'h', @"help", 0, NULL, NULL }, { 'h', @"help", 0, NULL, NULL },
{ 'k', @"keyfile", 1, NULL, &keyfilePath }, { 'k', @"keyfile", 1, NULL, &keyFilePath },
{ 'l', @"length", 1, NULL, &lengthString }, { 'l', @"length", 1, NULL, &lengthString },
{ 'L', @"legacy", 0, &_legacy, NULL }, { 'L', @"legacy", 0, &_legacy, NULL },
{ 'r', @"repeat", 0, &_repeat, NULL }, { 'r', @"repeat", 0, &_repeat, NULL },
@ -61,7 +61,7 @@ showHelp(OFStream *output, bool verbose)
OFOptionsParser *optionsParser = OFOptionsParser *optionsParser =
[OFOptionsParser parserWithOptions: options]; [OFOptionsParser parserWithOptions: options];
of_unichar_t option; of_unichar_t option;
OFMutableData *keyfile = nil; OFMutableData *keyFile = nil;
OFString *prompt; OFString *prompt;
const char *promptCString; const char *promptCString;
char *passphrase; char *passphrase;
@ -140,8 +140,8 @@ showHelp(OFStream *output, bool verbose)
generator.site]; generator.site];
promptCString = [prompt cStringWithEncoding: [OFLocalization encoding]]; promptCString = [prompt cStringWithEncoding: [OFLocalization encoding]];
if (keyfilePath != nil) if (keyFilePath != nil)
keyfile = [OFMutableData dataWithContentsOfFile: keyfilePath]; keyFile = [OFMutableData dataWithContentsOfFile: keyFilePath];
passphrase = getpass(promptCString); passphrase = getpass(promptCString);
@try { @try {
@ -173,7 +173,7 @@ showHelp(OFStream *output, bool verbose)
} }
} }
generator.keyfile = keyfile; generator.keyFile = keyFile;
generator.passphrase = passphrase; generator.passphrase = passphrase;
[generator derivePassword]; [generator derivePassword];
@ -189,8 +189,8 @@ showHelp(OFStream *output, bool verbose)
} @finally { } @finally {
of_explicit_memset(passphrase, 0, strlen(passphrase)); of_explicit_memset(passphrase, 0, strlen(passphrase));
if (keyfile != nil) if (keyFile != nil)
of_explicit_memset(keyfile.items, 0, keyfile.count); of_explicit_memset(keyFile.items, 0, keyFile.count);
} }
[OFApplication terminate]; [OFApplication terminate];

View file

@ -24,10 +24,11 @@
#import "MainViewController.h" #import "MainViewController.h"
@interface AddSiteController: UITableViewController @interface AddSiteController: UITableViewController <UITableViewDelegate>
@property (nonatomic, retain) IBOutlet UITextField *nameField; @property (nonatomic, retain) IBOutlet UITextField *nameField;
@property (nonatomic, retain) IBOutlet UITextField *lengthField; @property (nonatomic, retain) IBOutlet UITextField *lengthField;
@property (nonatomic, retain) IBOutlet UISwitch *legacySwitch; @property (nonatomic, retain) IBOutlet UISwitch *legacySwitch;
@property (nonatomic, retain) IBOutlet UILabel *keyFileLabel;
@property (retain) MainViewController *mainViewController; @property (retain) MainViewController *mainViewController;
- (IBAction)done: (id)sender; - (IBAction)done: (id)sender;

View file

@ -47,11 +47,36 @@ showAlert(UIViewController *controller, NSString *title, NSString *message)
[_nameField release]; [_nameField release];
[_lengthField release]; [_lengthField release];
[_legacySwitch release]; [_legacySwitch release];
[_keyFileLabel release];
[_mainViewController release]; [_mainViewController release];
[super dealloc]; [super dealloc];
} }
- (void)tableView: (UITableView *)tableView
didSelectRowAtIndexPath: (NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath: indexPath
animated: YES];
if (indexPath.section == 1 && indexPath.row == 1)
[self selectKeyFile];
}
- (NSIndexPath *)tableView: (UITableView *)tableView
willSelectRowAtIndexPath: (NSIndexPath *)indexPath
{
if (indexPath.section == 1 && indexPath.row == 1)
return indexPath;
return nil;
}
- (void)selectKeyFile
{
showAlert(self, @"Not Supported", @"Key files are not supported yet");
}
- (IBAction)done: (id)sender - (IBAction)done: (id)sender
{ {
OFString *name = self.nameField.text.OFObject; OFString *name = self.nameField.text.OFObject;
@ -87,7 +112,8 @@ showAlert(UIViewController *controller, NSString *title, NSString *message)
[self.mainViewController.siteStorage setSite: name [self.mainViewController.siteStorage setSite: name
length: length length: length
legacy: self.legacySwitch.on]; legacy: self.legacySwitch.on
keyFile: nil];
[self.mainViewController reset]; [self.mainViewController reset];
[self.navigationController popViewControllerAnimated: YES]; [self.navigationController popViewControllerAnimated: YES];

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BN3-Y7-zvx"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BN3-Y7-zvx">
<device id="retina4_7" orientation="portrait"> <device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/> <adaptation id="fullscreen"/>
</device> </device>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13173"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13527"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/> <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
@ -131,7 +131,7 @@
<scene sceneID="IxZ-dn-p6h"> <scene sceneID="IxZ-dn-p6h">
<objects> <objects>
<tableViewController id="mTn-Td-fIF" customClass="AddSiteController" sceneMemberID="viewController"> <tableViewController id="mTn-Td-fIF" customClass="AddSiteController" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" allowsSelection="NO" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="cum-L6-K1B"> <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="cum-L6-K1B">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/> <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
@ -146,7 +146,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Yq7-aM-PNl"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Yq7-aM-PNl">
<rect key="frame" x="8" y="11.5" width="100" height="20.5"/> <rect key="frame" x="16" y="11.5" width="100" height="20.5"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="100" id="nTn-vs-RDo"/> <constraint firstAttribute="width" constant="100" id="nTn-vs-RDo"/>
</constraints> </constraints>
@ -155,7 +155,7 @@
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="apple.com" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="AXY-MA-LhE"> <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="apple.com" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="AXY-MA-LhE">
<rect key="frame" x="116" y="11.5" width="251" height="21"/> <rect key="frame" x="124" y="11.5" width="235" height="21"/>
<nil key="textColor"/> <nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" returnKeyType="next"/> <textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" returnKeyType="next"/>
@ -178,7 +178,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Length" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eFJ-jF-rxJ"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Length" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eFJ-jF-rxJ">
<rect key="frame" x="8" y="11.5" width="100" height="20.5"/> <rect key="frame" x="16" y="11.5" width="100" height="20.5"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="100" id="4bi-Kp-8mJ"/> <constraint firstAttribute="width" constant="100" id="4bi-Kp-8mJ"/>
</constraints> </constraints>
@ -187,7 +187,7 @@
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="16" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="KQA-JL-1zl"> <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="16" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="KQA-JL-1zl">
<rect key="frame" x="116" y="11.5" width="251" height="21"/> <rect key="frame" x="124" y="11.5" width="235" height="21"/>
<nil key="textColor"/> <nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="numberPad" returnKeyType="next"/> <textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="numberPad" returnKeyType="next"/>
@ -214,7 +214,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Legacy" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SVA-v8-zP8"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Legacy" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SVA-v8-zP8">
<rect key="frame" x="8" y="11.5" width="100" height="20.5"/> <rect key="frame" x="16" y="11.5" width="100" height="20.5"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="100" id="KzI-6Z-fGE"/> <constraint firstAttribute="width" constant="100" id="KzI-6Z-fGE"/>
</constraints> </constraints>
@ -223,7 +223,7 @@
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="jcs-6K-Sbe"> <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="jcs-6K-Sbe">
<rect key="frame" x="318" y="6.5" width="51" height="31"/> <rect key="frame" x="310" y="6.5" width="51" height="31"/>
</switch> </switch>
</subviews> </subviews>
<constraints> <constraints>
@ -234,12 +234,44 @@
</constraints> </constraints>
</tableViewCellContentView> </tableViewCellContentView>
</tableViewCell> </tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="Oqt-88-vl9">
<rect key="frame" x="0.0" y="203" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Oqt-88-vl9" id="j4y-Zr-ep4">
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Key file" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Uyw-CW-atj">
<rect key="frame" x="16" y="12" width="100" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="5d9-re-aJA"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="None" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wv8-GU-ahj">
<rect key="frame" x="124" y="11.5" width="208" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="trailingMargin" secondItem="wv8-GU-ahj" secondAttribute="trailing" constant="1" id="0sM-gC-XNC" userLabel="trailingMargin = Label.trailing"/>
<constraint firstItem="wv8-GU-ahj" firstAttribute="leading" secondItem="Uyw-CW-atj" secondAttribute="trailing" constant="8" symbolic="YES" id="McA-uD-gbN"/>
<constraint firstItem="wv8-GU-ahj" firstAttribute="centerY" secondItem="j4y-Zr-ep4" secondAttribute="centerY" id="W3H-tA-b2r"/>
<constraint firstItem="Uyw-CW-atj" firstAttribute="centerY" secondItem="j4y-Zr-ep4" secondAttribute="centerY" id="frr-aH-KZB"/>
<constraint firstItem="Uyw-CW-atj" firstAttribute="leading" secondItem="j4y-Zr-ep4" secondAttribute="leadingMargin" id="oqY-IE-chq"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells> </cells>
</tableViewSection> </tableViewSection>
</sections> </sections>
<connections> <connections>
<outlet property="dataSource" destination="mTn-Td-fIF" id="lRR-7B-Rbz"/> <outlet property="dataSource" destination="mTn-Td-fIF" id="lRR-7B-Rbz"/>
<outlet property="delegate" destination="mTn-Td-fIF" id="UJl-VI-MdQ"/> <outlet property="delegate" destination="mTn-Td-fIF" id="Ved-aO-x8G"/>
</connections> </connections>
</tableView> </tableView>
<toolbarItems/> <toolbarItems/>
@ -257,6 +289,7 @@
</navigationItem> </navigationItem>
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/> <simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
<connections> <connections>
<outlet property="keyFileLabel" destination="wv8-GU-ahj" id="Tdf-2p-DSb"/>
<outlet property="legacySwitch" destination="jcs-6K-Sbe" id="sCo-l6-9n7"/> <outlet property="legacySwitch" destination="jcs-6K-Sbe" id="sCo-l6-9n7"/>
<outlet property="lengthField" destination="KQA-JL-1zl" id="tdI-mj-8Ng"/> <outlet property="lengthField" destination="KQA-JL-1zl" id="tdI-mj-8Ng"/>
<outlet property="nameField" destination="AXY-MA-LhE" id="Noo-It-VNV"/> <outlet property="nameField" destination="AXY-MA-LhE" id="Noo-It-VNV"/>
@ -267,7 +300,7 @@
<cells/> <cells/>
</tableViewSection> </tableViewSection>
</objects> </objects>
<point key="canvasLocation" x="1994" y="-1102"/> <point key="canvasLocation" x="1992.8" y="-1102.3988005997003"/>
</scene> </scene>
<!--Show Details Controller--> <!--Show Details Controller-->
<scene sceneID="rn9-fJ-mg7"> <scene sceneID="rn9-fJ-mg7">
@ -288,7 +321,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SAI-3c-VBt"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SAI-3c-VBt">
<rect key="frame" x="8" y="11.5" width="100" height="20.5"/> <rect key="frame" x="16" y="11.5" width="100" height="20.5"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="100" id="9uC-jX-ZTa"/> <constraint firstAttribute="width" constant="100" id="9uC-jX-ZTa"/>
</constraints> </constraints>
@ -297,7 +330,7 @@
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="4Le-mO-AdY"> <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="4Le-mO-AdY">
<rect key="frame" x="116" y="11.5" width="251" height="21"/> <rect key="frame" x="124" y="11.5" width="235" height="21"/>
<nil key="textColor"/> <nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits"/> <textInputTraits key="textInputTraits"/>
@ -320,7 +353,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Length" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EKx-FZ-XDX"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Length" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EKx-FZ-XDX">
<rect key="frame" x="8" y="11.5" width="100" height="20.5"/> <rect key="frame" x="16" y="11.5" width="100" height="20.5"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="100" id="ZLB-KT-EH6"/> <constraint firstAttribute="width" constant="100" id="ZLB-KT-EH6"/>
</constraints> </constraints>
@ -329,7 +362,7 @@
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Lp1-jC-8cn"> <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Lp1-jC-8cn">
<rect key="frame" x="116" y="11.5" width="251" height="21"/> <rect key="frame" x="124" y="11.5" width="235" height="21"/>
<nil key="textColor"/> <nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" keyboardType="numberPad"/> <textInputTraits key="textInputTraits" keyboardType="numberPad"/>
@ -356,7 +389,7 @@
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Legacy" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sLx-Wk-oJm"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Legacy" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sLx-Wk-oJm">
<rect key="frame" x="8" y="11.5" width="100" height="20.5"/> <rect key="frame" x="16" y="11.5" width="100" height="20.5"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="100" id="47g-NW-zSf"/> <constraint firstAttribute="width" constant="100" id="47g-NW-zSf"/>
</constraints> </constraints>
@ -365,7 +398,7 @@
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="qW3-51-hZP"> <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="qW3-51-hZP">
<rect key="frame" x="318" y="6.5" width="51" height="31"/> <rect key="frame" x="310" y="6.5" width="51" height="31"/>
</switch> </switch>
</subviews> </subviews>
<constraints> <constraints>
@ -376,19 +409,51 @@
</constraints> </constraints>
</tableViewCellContentView> </tableViewCellContentView>
</tableViewCell> </tableViewCell>
<tableViewCell clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="RPi-sp-ryP">
<rect key="frame" x="0.0" y="203" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="RPi-sp-ryP" id="4am-uF-Se2">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Key file" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PyO-Yg-5aA">
<rect key="frame" x="16" y="11.5" width="100" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="w67-w2-NBo"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="None" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="pZW-y5-2H8">
<rect key="frame" x="124" y="11.5" width="235" height="21"/>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits"/>
</textField>
</subviews>
<constraints>
<constraint firstItem="pZW-y5-2H8" firstAttribute="trailing" secondItem="4am-uF-Se2" secondAttribute="trailingMargin" id="LNC-PD-z2J"/>
<constraint firstItem="PyO-Yg-5aA" firstAttribute="leading" secondItem="4am-uF-Se2" secondAttribute="leadingMargin" id="g1g-dd-t6P"/>
<constraint firstItem="pZW-y5-2H8" firstAttribute="centerY" secondItem="4am-uF-Se2" secondAttribute="centerY" id="lcF-a8-qo5"/>
<constraint firstItem="PyO-Yg-5aA" firstAttribute="centerY" secondItem="pZW-y5-2H8" secondAttribute="centerY" id="pCt-QO-MUH"/>
<constraint firstItem="pZW-y5-2H8" firstAttribute="leading" secondItem="PyO-Yg-5aA" secondAttribute="trailing" constant="8" symbolic="YES" id="sxD-pQ-cka"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</cells> </cells>
</tableViewSection> </tableViewSection>
<tableViewSection id="pLW-Tc-sKf"> <tableViewSection id="pLW-Tc-sKf">
<cells> <cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="HHm-l0-c0d"> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="HHm-l0-c0d">
<rect key="frame" x="0.0" y="239" width="375" height="44"/> <rect key="frame" x="0.0" y="283" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="HHm-l0-c0d" id="4qT-tm-wo7"> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="HHm-l0-c0d" id="4qT-tm-wo7">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/> <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Passphrase" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fAW-aP-GN9"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Passphrase" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fAW-aP-GN9">
<rect key="frame" x="8" y="11.5" width="100" height="20.5"/> <rect key="frame" x="16" y="11.5" width="100" height="20.5"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="100" id="wRI-ys-67O"/> <constraint firstAttribute="width" constant="100" id="wRI-ys-67O"/>
</constraints> </constraints>
@ -397,7 +462,7 @@
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" highlighted="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Required" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="DJv-Ey-Hka"> <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" highlighted="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Required" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="DJv-Ey-Hka">
<rect key="frame" x="116" y="11.5" width="251" height="21"/> <rect key="frame" x="124" y="11.5" width="235" height="21"/>
<nil key="textColor"/> <nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" returnKeyType="done" secureTextEntry="YES"/> <textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" returnKeyType="done" secureTextEntry="YES"/>
@ -420,14 +485,14 @@
<tableViewSection id="3SB-Gu-7Nb"> <tableViewSection id="3SB-Gu-7Nb">
<cells> <cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="zL5-5B-O5f"> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="zL5-5B-O5f">
<rect key="frame" x="0.0" y="319" width="375" height="44"/> <rect key="frame" x="0.0" y="363" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="zL5-5B-O5f" id="WMu-8w-qhO"> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="zL5-5B-O5f" id="WMu-8w-qhO">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/> <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Generate and Copy to Clipboard" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sss-5e-vm2"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Generate and Copy to Clipboard" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sss-5e-vm2">
<rect key="frame" x="8" y="8" width="359" height="27.5"/> <rect key="frame" x="16" y="11" width="343" height="21.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@ -442,14 +507,14 @@
</tableViewCellContentView> </tableViewCellContentView>
</tableViewCell> </tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="ojF-JZ-yCg"> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="ojF-JZ-yCg">
<rect key="frame" x="0.0" y="363" width="375" height="44"/> <rect key="frame" x="0.0" y="407" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ojF-JZ-yCg" id="bbw-fx-dOK"> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ojF-JZ-yCg" id="bbw-fx-dOK">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/> <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Generate and Show" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tib-hU-gDm"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Generate and Show" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tib-hU-gDm">
<rect key="frame" x="8" y="8" width="359" height="27.5"/> <rect key="frame" x="16" y="11" width="343" height="21.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@ -480,6 +545,7 @@
</barButtonItem> </barButtonItem>
</navigationItem> </navigationItem>
<connections> <connections>
<outlet property="keyFileField" destination="pZW-y5-2H8" id="oXl-vz-5JQ"/>
<outlet property="legacySwitch" destination="qW3-51-hZP" id="NsI-F3-hVQ"/> <outlet property="legacySwitch" destination="qW3-51-hZP" id="NsI-F3-hVQ"/>
<outlet property="lengthField" destination="Lp1-jC-8cn" id="05B-m5-JnB"/> <outlet property="lengthField" destination="Lp1-jC-8cn" id="05B-m5-JnB"/>
<outlet property="nameField" destination="4Le-mO-AdY" id="kSd-Rz-Zai"/> <outlet property="nameField" destination="4Le-mO-AdY" id="kSd-Rz-Zai"/>

View file

@ -30,11 +30,13 @@
OFString *_name; OFString *_name;
size_t _length; size_t _length;
bool _legacy; bool _legacy;
OFString *_keyFile;
} }
@property (retain, nonatomic) IBOutlet UITextField *nameField; @property (retain, nonatomic) IBOutlet UITextField *nameField;
@property (retain, nonatomic) IBOutlet UITextField *lengthField; @property (retain, nonatomic) IBOutlet UITextField *lengthField;
@property (retain, nonatomic) IBOutlet UISwitch *legacySwitch; @property (retain, nonatomic) IBOutlet UISwitch *legacySwitch;
@property (retain, nonatomic) IBOutlet UITextField *keyFileField;
@property (retain, nonatomic) IBOutlet UITextField *passphraseField; @property (retain, nonatomic) IBOutlet UITextField *passphraseField;
@property (retain) MainViewController *mainViewController; @property (retain) MainViewController *mainViewController;

View file

@ -56,6 +56,8 @@ clearNSMutableString(NSMutableString *string)
[_nameField release]; [_nameField release];
[_lengthField release]; [_lengthField release];
[_legacySwitch release]; [_legacySwitch release];
[_keyFile release];
[_keyFileField release];
[_passphraseField release]; [_passphraseField release];
[_mainViewController release]; [_mainViewController release];
@ -73,13 +75,15 @@ clearNSMutableString(NSMutableString *string)
indexPath = self.mainViewController.tableView.indexPathForSelectedRow; indexPath = self.mainViewController.tableView.indexPathForSelectedRow;
[_name release]; [_name release];
_name = [self.mainViewController.sites[indexPath.row] retain]; _name = [self.mainViewController.sites[indexPath.row] copy];
_length = [siteStorage lengthForSite: _name]; _length = [siteStorage lengthForSite: _name];
_legacy = [siteStorage isSiteLegacy: _name]; _legacy = [siteStorage isSiteLegacy: _name];
_keyFile = [[siteStorage keyFileForSite: _name] copy];
self.nameField.text = _name.NSObject; self.nameField.text = _name.NSObject;
self.lengthField.text = [NSString stringWithFormat: @"%zu", _length]; self.lengthField.text = [NSString stringWithFormat: @"%zu", _length];
self.legacySwitch.on = _legacy; self.legacySwitch.on = _legacy;
self.keyFileField.text = _keyFile.NSObject;
[self.mainViewController.tableView deselectRowAtIndexPath: indexPath [self.mainViewController.tableView deselectRowAtIndexPath: indexPath
animated: YES]; animated: YES];

View file

@ -25,7 +25,7 @@
@interface SiteStorage: OFObject @interface SiteStorage: OFObject
{ {
OFString *_path; OFString *_path;
OFMutableDictionary<OFString *, OFDictionary<OFNumber *, OFNumber *> *> OFMutableDictionary<OFString *, OFDictionary<OFNumber *, id> *>
*_storage; *_storage;
OFArray *_sites; OFArray *_sites;
} }
@ -34,8 +34,10 @@
- (bool)hasSite: (OFString *)name; - (bool)hasSite: (OFString *)name;
- (size_t)lengthForSite: (OFString *)name; - (size_t)lengthForSite: (OFString *)name;
- (bool)isSiteLegacy: (OFString *)name; - (bool)isSiteLegacy: (OFString *)name;
- (OFString *)keyFileForSite: (OFString *)name;
- (void)setSite: (OFString *)site - (void)setSite: (OFString *)site
length: (size_t)length length: (size_t)length
legacy: (bool)legacy; legacy: (bool)legacy
keyFile: (OFString *)keyFile;
- (void)removeSite: (OFString *)name; - (void)removeSite: (OFString *)name;
@end @end

View file

@ -28,40 +28,42 @@
- (void)_update; - (void)_update;
@end @end
static OFNumber *lengthField, *legacyField; static OFNumber *lengthField, *legacyField, *keyFileField;
@implementation SiteStorage @implementation SiteStorage
+ (void)initialize + (void)initialize
{ {
lengthField = [@(UINT8_C(0)) retain]; lengthField = [@(UINT8_C(0)) retain];
legacyField = [@(UINT8_C(1)) retain]; legacyField = [@(UINT8_C(1)) retain];
keyFileField = [@(UINT8_C(2)) retain];
} }
- init - (instancetype)init
{ {
self = [super init]; self = [super init];
@try { @try {
void *pool = objc_autoreleasePoolPush(); @autoreleasepool {
OFFileManager *fileManager = [OFFileManager defaultManager]; OFFileManager *fileManager =
OFString *userDataPath = [OFSystemInfo userDataPath]; OFFileManager.defaultManager;
OFString *userDataPath = OFSystemInfo.userDataPath;
if (![fileManager directoryExistsAtPath: userDataPath]) if (![fileManager directoryExistsAtPath: userDataPath])
[fileManager createDirectoryAtPath: userDataPath]; [fileManager
createDirectoryAtPath: userDataPath];
_path = [[userDataPath stringByAppendingPathComponent: _path = [[userDataPath stringByAppendingPathComponent:
@"sites.msgpack"] retain]; @"sites.msgpack"] copy];
@try { @try {
_storage = [[[OFData dataWithContentsOfFile: _path] _storage = [[OFData dataWithContentsOfFile:
messagePackValue] mutableCopy]; _path].messagePackValue mutableCopy];
} @catch (id e) { } @catch (id e) {
_storage = [[OFMutableDictionary alloc] init]; _storage = [[OFMutableDictionary alloc] init];
} }
_sites = [[[_storage allKeys] sortedArray] retain]; _sites = [_storage.allKeys.sortedArray retain];
}
objc_autoreleasePoolPop(pool);
} @catch (id e) { } @catch (id e) {
[self release]; [self release];
@throw e; @throw e;
@ -81,21 +83,25 @@ static OFNumber *lengthField, *legacyField;
- (OFArray<OFString *> *)sitesWithFilter: (OFString *)filter - (OFArray<OFString *> *)sitesWithFilter: (OFString *)filter
{ {
void *pool = objc_autoreleasePoolPush(); OFArray<OFString *> *sites;
@autoreleasepool {
/* /*
* FIXME: We need case folding here, but there is no method for it yet. * FIXME: We need case folding here, but there is no method for
* it yet.
*/ */
filter = [filter lowercaseString]; filter = filter.lowercaseString;
OFArray *sites = [[[_storage allKeys] sortedArray] sites = [_storage.allKeys.sortedArray
filteredArrayUsingBlock: ^ (id name, size_t index) { filteredArrayUsingBlock: ^ (OFString *name, size_t index) {
if (filter == nil) if (filter == nil)
return true; return true;
return [[name lowercaseString] containsString: filter]; return [name.lowercaseString containsString: filter];
}]; }];
[sites retain]; [sites retain];
objc_autoreleasePoolPop(pool); }
return [sites autorelease]; return [sites autorelease];
} }
@ -106,7 +112,7 @@ static OFNumber *lengthField, *legacyField;
- (size_t)lengthForSite: (OFString *)name - (size_t)lengthForSite: (OFString *)name
{ {
OFDictionary *site = _storage[name]; OFDictionary<OFNumber *, id> *site = _storage[name];
if (site == nil) if (site == nil)
@throw [OFInvalidArgumentException exception]; @throw [OFInvalidArgumentException exception];
@ -116,7 +122,7 @@ static OFNumber *lengthField, *legacyField;
- (bool)isSiteLegacy: (OFString *)name - (bool)isSiteLegacy: (OFString *)name
{ {
OFDictionary *site = _storage[name]; OFDictionary<OFNumber *, id> *site = _storage[name];
if (site == nil) if (site == nil)
@throw [OFInvalidArgumentException exception]; @throw [OFInvalidArgumentException exception];
@ -124,19 +130,41 @@ static OFNumber *lengthField, *legacyField;
return [site[legacyField] boolValue]; return [site[legacyField] boolValue];
} }
- (OFString *)keyFileForSite: (OFString *)name
{
OFDictionary<OFNumber *, id> *site = _storage[name];
OFString *keyFile;
if (site == nil)
@throw [OFInvalidArgumentException exception];
keyFile = site[keyFileField];
if ([keyFile isEqual: [OFNull null]])
return nil;
return keyFile;
}
- (void)setSite: (OFString *)site - (void)setSite: (OFString *)site
length: (size_t)length length: (size_t)length
legacy: (bool)legacy legacy: (bool)legacy
keyFile: (OFString *)keyFile
{ {
void *pool = objc_autoreleasePoolPush(); @autoreleasepool {
OFMutableDictionary *siteDictionary =
[OFMutableDictionary dictionary];
siteDictionary[lengthField] = @(length);
siteDictionary[legacyField] = @(legacy);
siteDictionary[keyFileField] = keyFile;
[siteDictionary makeImmutable];
_storage[site] = siteDictionary;
_storage[site] = @{
lengthField: @(length),
legacyField: @(legacy)
};
[self _update]; [self _update];
}
objc_autoreleasePoolPop(pool);
} }
- (void)removeSite: (OFString *)name - (void)removeSite: (OFString *)name
@ -147,13 +175,11 @@ static OFNumber *lengthField, *legacyField;
- (void)_update - (void)_update
{ {
void *pool = objc_autoreleasePoolPush(); @autoreleasepool {
[_storage.messagePackRepresentation writeToFile: _path];
[[_storage messagePackRepresentation] writeToFile: _path];
[_sites release]; [_sites release];
_sites = [[[_storage allKeys] sortedArray] retain]; _sites = [_storage.allKeys.sortedArray retain];
}
objc_autoreleasePoolPop(pool);
} }
@end @end