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;
OFString *_site;
OFData *_keyfile;
OFData *_keyFile;
const char *_passphrase;
unsigned char *_output;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -47,11 +47,36 @@ showAlert(UIViewController *controller, NSString *title, NSString *message)
[_nameField release];
[_lengthField release];
[_legacySwitch release];
[_keyFileLabel release];
[_mainViewController release];
[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
{
OFString *name = self.nameField.text.OFObject;
@ -87,7 +112,8 @@ showAlert(UIViewController *controller, NSString *title, NSString *message)
[self.mainViewController.siteStorage setSite: name
length: length
legacy: self.legacySwitch.on];
legacy: self.legacySwitch.on
keyFile: nil];
[self.mainViewController reset];
[self.navigationController popViewControllerAnimated: YES];

View file

@ -1,11 +1,11 @@
<?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">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<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="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -131,7 +131,7 @@
<scene sceneID="IxZ-dn-p6h">
<objects>
<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"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
@ -146,7 +146,7 @@
<autoresizingMask key="autoresizingMask"/>
<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">
<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>
<constraint firstAttribute="width" constant="100" id="nTn-vs-RDo"/>
</constraints>
@ -155,7 +155,7 @@
<nil key="highlightedColor"/>
</label>
<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"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" returnKeyType="next"/>
@ -178,7 +178,7 @@
<autoresizingMask key="autoresizingMask"/>
<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">
<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>
<constraint firstAttribute="width" constant="100" id="4bi-Kp-8mJ"/>
</constraints>
@ -187,7 +187,7 @@
<nil key="highlightedColor"/>
</label>
<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"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="numberPad" returnKeyType="next"/>
@ -214,7 +214,7 @@
<autoresizingMask key="autoresizingMask"/>
<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">
<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>
<constraint firstAttribute="width" constant="100" id="KzI-6Z-fGE"/>
</constraints>
@ -223,7 +223,7 @@
<nil key="highlightedColor"/>
</label>
<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>
</subviews>
<constraints>
@ -234,12 +234,44 @@
</constraints>
</tableViewCellContentView>
</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>
</tableViewSection>
</sections>
<connections>
<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>
</tableView>
<toolbarItems/>
@ -257,6 +289,7 @@
</navigationItem>
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
<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="lengthField" destination="KQA-JL-1zl" id="tdI-mj-8Ng"/>
<outlet property="nameField" destination="AXY-MA-LhE" id="Noo-It-VNV"/>
@ -267,7 +300,7 @@
<cells/>
</tableViewSection>
</objects>
<point key="canvasLocation" x="1994" y="-1102"/>
<point key="canvasLocation" x="1992.8" y="-1102.3988005997003"/>
</scene>
<!--Show Details Controller-->
<scene sceneID="rn9-fJ-mg7">
@ -288,7 +321,7 @@
<autoresizingMask key="autoresizingMask"/>
<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">
<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>
<constraint firstAttribute="width" constant="100" id="9uC-jX-ZTa"/>
</constraints>
@ -297,7 +330,7 @@
<nil key="highlightedColor"/>
</label>
<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"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits"/>
@ -320,7 +353,7 @@
<autoresizingMask key="autoresizingMask"/>
<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">
<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>
<constraint firstAttribute="width" constant="100" id="ZLB-KT-EH6"/>
</constraints>
@ -329,7 +362,7 @@
<nil key="highlightedColor"/>
</label>
<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"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" keyboardType="numberPad"/>
@ -356,7 +389,7 @@
<autoresizingMask key="autoresizingMask"/>
<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">
<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>
<constraint firstAttribute="width" constant="100" id="47g-NW-zSf"/>
</constraints>
@ -365,7 +398,7 @@
<nil key="highlightedColor"/>
</label>
<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>
</subviews>
<constraints>
@ -376,19 +409,51 @@
</constraints>
</tableViewCellContentView>
</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>
</tableViewSection>
<tableViewSection id="pLW-Tc-sKf">
<cells>
<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"/>
<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"/>
<autoresizingMask key="autoresizingMask"/>
<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">
<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>
<constraint firstAttribute="width" constant="100" id="wRI-ys-67O"/>
</constraints>
@ -397,7 +462,7 @@
<nil key="highlightedColor"/>
</label>
<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"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" returnKeyType="done" secureTextEntry="YES"/>
@ -420,14 +485,14 @@
<tableViewSection id="3SB-Gu-7Nb">
<cells>
<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"/>
<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"/>
<autoresizingMask key="autoresizingMask"/>
<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">
<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"/>
<color key="textColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@ -442,14 +507,14 @@
</tableViewCellContentView>
</tableViewCell>
<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"/>
<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"/>
<autoresizingMask key="autoresizingMask"/>
<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">
<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"/>
<color key="textColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@ -480,6 +545,7 @@
</barButtonItem>
</navigationItem>
<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="lengthField" destination="Lp1-jC-8cn" id="05B-m5-JnB"/>
<outlet property="nameField" destination="4Le-mO-AdY" id="kSd-Rz-Zai"/>

View file

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

View file

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

View file

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

View file

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