iOS: Add initial parts of support for key files
This commit is contained in:
parent
f886262722
commit
fa21a9d8f3
13 changed files with 226 additions and 99 deletions
|
@ -26,7 +26,7 @@
|
|||
{
|
||||
size_t _length;
|
||||
OFString *_site;
|
||||
OFData *_keyfile;
|
||||
OFData *_keyFile;
|
||||
const char *_passphrase;
|
||||
unsigned char *_output;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
{
|
||||
size_t _length;
|
||||
OFString *_site;
|
||||
OFData *_keyfile;
|
||||
OFData *_keyFile;
|
||||
const char *_passphrase;
|
||||
unsigned char *_output;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
[fileManager
|
||||
createDirectoryAtPath: userDataPath];
|
||||
|
||||
_path = [[userDataPath stringByAppendingPathComponent:
|
||||
@"sites.msgpack"] retain];
|
||||
@"sites.msgpack"] copy];
|
||||
|
||||
@try {
|
||||
_storage = [[[OFData dataWithContentsOfFile: _path]
|
||||
messagePackValue] mutableCopy];
|
||||
_storage = [[OFData dataWithContentsOfFile:
|
||||
_path].messagePackValue mutableCopy];
|
||||
} @catch (id e) {
|
||||
_storage = [[OFMutableDictionary alloc] init];
|
||||
}
|
||||
|
||||
_sites = [[[_storage allKeys] sortedArray] retain];
|
||||
|
||||
objc_autoreleasePoolPop(pool);
|
||||
_sites = [_storage.allKeys.sortedArray retain];
|
||||
}
|
||||
} @catch (id e) {
|
||||
[self release];
|
||||
@throw e;
|
||||
|
@ -81,21 +83,25 @@ static OFNumber *lengthField, *legacyField;
|
|||
|
||||
- (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];
|
||||
OFArray *sites = [[[_storage allKeys] sortedArray]
|
||||
filteredArrayUsingBlock: ^ (id name, size_t index) {
|
||||
filter = filter.lowercaseString;
|
||||
sites = [_storage.allKeys.sortedArray
|
||||
filteredArrayUsingBlock: ^ (OFString *name, size_t index) {
|
||||
if (filter == nil)
|
||||
return true;
|
||||
|
||||
return [[name lowercaseString] containsString: filter];
|
||||
return [name.lowercaseString containsString: filter];
|
||||
}];
|
||||
|
||||
[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];
|
||||
|
||||
siteDictionary[lengthField] = @(length);
|
||||
siteDictionary[legacyField] = @(legacy);
|
||||
siteDictionary[keyFileField] = keyFile;
|
||||
|
||||
[siteDictionary makeImmutable];
|
||||
|
||||
_storage[site] = siteDictionary;
|
||||
|
||||
_storage[site] = @{
|
||||
lengthField: @(length),
|
||||
legacyField: @(legacy)
|
||||
};
|
||||
[self _update];
|
||||
|
||||
objc_autoreleasePoolPop(pool);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeSite: (OFString *)name
|
||||
|
@ -147,13 +175,11 @@ static OFNumber *lengthField, *legacyField;
|
|||
|
||||
- (void)_update
|
||||
{
|
||||
void *pool = objc_autoreleasePoolPush();
|
||||
|
||||
[[_storage messagePackRepresentation] writeToFile: _path];
|
||||
@autoreleasepool {
|
||||
[_storage.messagePackRepresentation writeToFile: _path];
|
||||
|
||||
[_sites release];
|
||||
_sites = [[[_storage allKeys] sortedArray] retain];
|
||||
|
||||
objc_autoreleasePoolPop(pool);
|
||||
_sites = [_storage.allKeys.sortedArray retain];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue