From 2388edccfbb1bc06a19131d37962bb8635485e28 Mon Sep 17 00:00:00 2001 From: Yishi Lin Date: Wed, 7 Jun 2017 21:11:01 +0800 Subject: [PATCH] Polish logics about PGP passphrase - Ask passphrase only when users want to save them for later usage - Provide a second change to enter passphrase during the decryption --- ...GPKeyArmorSettingTableViewController.swift | 46 +++++---- .../PGPKeySettingTableViewController.swift | 45 +++++---- .../PasswordDetailTableViewController.swift | 8 +- .../SettingsTableViewController.swift | 96 +++++++++---------- pass/Models/PasswordStore.swift | 14 +-- 5 files changed, 104 insertions(+), 105 deletions(-) diff --git a/pass/Controllers/PGPKeyArmorSettingTableViewController.swift b/pass/Controllers/PGPKeyArmorSettingTableViewController.swift index 28f00d8..71f2a95 100644 --- a/pass/Controllers/PGPKeyArmorSettingTableViewController.swift +++ b/pass/Controllers/PGPKeyArmorSettingTableViewController.swift @@ -107,20 +107,6 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe scanPrivateKeyCell?.accessoryType = .disclosureIndicator } - private func createSavePassphraseAndSegueAlert() -> UIAlertController { - let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert) - savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in - Defaults[.isRememberPassphraseOn] = false - self.pgpPassphrase = nil - self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) - }) - savePassphraseAlert.addAction(UIAlertAction(title: "Save", style: UIAlertActionStyle.destructive) {_ in - Defaults[.isRememberPassphraseOn] = true - self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) - }) - return savePassphraseAlert - } - override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { if identifier == "savePGPKeySegue" { if armorPublicKeyTextView.text.isEmpty { @@ -136,17 +122,29 @@ class PGPKeyArmorSettingTableViewController: UITableViewController, UITextViewDe } @IBAction func save(_ sender: Any) { - let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert) - alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in - self.pgpPassphrase = alert.textFields?.first?.text - let savePassphraseAndSegueAlert = self.createSavePassphraseAndSegueAlert() - self.present(savePassphraseAndSegueAlert, animated: true, completion: nil) - })) - alert.addTextField(configurationHandler: {(textField: UITextField!) in - textField.text = self.pgpPassphrase - textField.isSecureTextEntry = true + let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert) + // no + savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in + self.pgpPassphrase = nil + Defaults[.isRememberPassphraseOn] = false + self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) }) - self.present(alert, animated: true, completion: nil) + // yes + savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in + // ask for the passphrase + let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert) + alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in + self.pgpPassphrase = alert.textFields?.first?.text + Defaults[.isRememberPassphraseOn] = true + self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) + })) + alert.addTextField(configurationHandler: {(textField: UITextField!) in + textField.text = self.pgpPassphrase + textField.isSecureTextEntry = true + }) + self.present(alert, animated: true, completion: nil) + }) + self.present(savePassphraseAlert, animated: true, completion: nil) } func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { diff --git a/pass/Controllers/PGPKeySettingTableViewController.swift b/pass/Controllers/PGPKeySettingTableViewController.swift index c7ab7db..d022f31 100644 --- a/pass/Controllers/PGPKeySettingTableViewController.swift +++ b/pass/Controllers/PGPKeySettingTableViewController.swift @@ -24,19 +24,6 @@ class PGPKeySettingTableViewController: UITableViewController { pgpPassphrase = passwordStore.pgpKeyPassphrase } - private func createSavePassphraseAndSegueAlert() -> UIAlertController { - let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert) - savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in - Defaults[.isRememberPassphraseOn] = false - self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) - }) - savePassphraseAlert.addAction(UIAlertAction(title: "Save", style: UIAlertActionStyle.destructive) {_ in - Defaults[.isRememberPassphraseOn] = true - self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) - }) - return savePassphraseAlert - } - override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { if identifier == "savePGPKeySegue" { guard validatePGPKeyURL(input: pgpPublicKeyURLTextField.text) == true, @@ -60,16 +47,28 @@ class PGPKeySettingTableViewController: UITableViewController { } @IBAction func save(_ sender: Any) { - let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert) - alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in - self.pgpPassphrase = alert.textFields?.first?.text - let savePassphraseAndSegueAlert = self.createSavePassphraseAndSegueAlert() - self.present(savePassphraseAndSegueAlert, animated: true, completion: nil) - })) - alert.addTextField(configurationHandler: {(textField: UITextField!) in - textField.text = self.pgpPassphrase - textField.isSecureTextEntry = true + let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert) + // no + savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in + self.pgpPassphrase = nil + Defaults[.isRememberPassphraseOn] = false + self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) }) - self.present(alert, animated: true, completion: nil) + // yes + savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in + // ask for the passphrase + let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert) + alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in + self.pgpPassphrase = alert.textFields?.first?.text + Defaults[.isRememberPassphraseOn] = true + self.performSegue(withIdentifier: "savePGPKeySegue", sender: self) + })) + alert.addTextField(configurationHandler: {(textField: UITextField!) in + textField.text = self.pgpPassphrase + textField.isSecureTextEntry = true + }) + self.present(alert, animated: true, completion: nil) + }) + self.present(savePassphraseAlert, animated: true, completion: nil) } } diff --git a/pass/Controllers/PasswordDetailTableViewController.swift b/pass/Controllers/PasswordDetailTableViewController.swift index 0ab30c9..8459139 100644 --- a/pass/Controllers/PasswordDetailTableViewController.swift +++ b/pass/Controllers/PasswordDetailTableViewController.swift @@ -155,9 +155,15 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni DispatchQueue.main.async { // remove the wrong passphrase so that users could enter it next time self.passwordStore.pgpKeyPassphrase = nil - Utils.alert(title: "Cannot Show Password", message: error.localizedDescription, controller: self, handler: {(UIAlertAction) -> Void in + // alert: cancel or try again + let alert = UIAlertController(title: "Cannot Show Password", message: error.localizedDescription, preferredStyle: UIAlertControllerStyle.alert) + alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.default) { _ in self.navigationController!.popViewController(animated: true) }) + alert.addAction(UIAlertAction(title: "Try again", style: UIAlertActionStyle.destructive) {_ in + self.decryptThenShowPassword() + }) + self.present(alert, animated: true, completion: nil) } return } diff --git a/pass/Controllers/SettingsTableViewController.swift b/pass/Controllers/SettingsTableViewController.swift index eedd76e..2c8bf03 100644 --- a/pass/Controllers/SettingsTableViewController.swift +++ b/pass/Controllers/SettingsTableViewController.swift @@ -92,6 +92,30 @@ class SettingsTableViewController: UITableViewController { } } + private func saveImportedPGPKey() { + // load keys + Defaults[.pgpKeySource] = "file" + + SVProgressHUD.setDefaultMaskType(.black) + SVProgressHUD.setDefaultStyle(.light) + SVProgressHUD.show(withStatus: "Fetching PGP Key") + DispatchQueue.global(qos: .userInitiated).async { [unowned self] in + do { + try self.passwordStore.initPGPKeys() + DispatchQueue.main.async { + self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID + SVProgressHUD.showSuccess(withStatus: "Success") + SVProgressHUD.dismiss(withDelay: 1) + } + } catch { + DispatchQueue.main.async { + self.pgpKeyTableViewCell.detailTextLabel?.text = "Not Set" + Utils.alert(title: "Error", message: error.localizedDescription, controller: self, completion: nil) + } + } + } + } + @IBAction func cancelGitServerSetting(segue: UIStoryboardSegue) { } @@ -233,55 +257,31 @@ class SettingsTableViewController: UITableViewController { if passwordStore.pgpKeyExists() { let fileAction = UIAlertAction(title: fileActionTitle, style: .default) { _ in - - SVProgressHUD.setDefaultMaskType(.black) - SVProgressHUD.setDefaultStyle(.light) - SVProgressHUD.show(withStatus: "Reading PGP key") - - let alert = UIAlertController( - title: "PGP Passphrase", - message: "Please fill in the passphrase for your PGP key.", - preferredStyle: UIAlertControllerStyle.alert - ) - - alert.addAction( - UIAlertAction( - title: "OK", - style: UIAlertActionStyle.default, - handler: {_ in - Utils.addPasswordToKeychain( - name: "pgpKeyPassphrase", - password: alert.textFields!.first!.text! - ) - } - ) - ) - - alert.addTextField( - configurationHandler: {(textField: UITextField!) in - textField.text = Utils.getPasswordFromKeychain(name: "pgpKeyPassphrase") ?? "" - textField.isSecureTextEntry = true - } - ) - - - DispatchQueue.main.async { - self.passwordStore.initPGPKeys() - - let key: PGPKey = self.passwordStore.getPgpPrivateKey() - Defaults[.pgpKeySource] = "file" - - if (key.isEncrypted) { - SVProgressHUD.dismiss() - self.present(alert, animated: true, completion: nil) - } - - SVProgressHUD.dismiss() - self.pgpKeyTableViewCell.detailTextLabel?.text = self.passwordStore.pgpKeyID - } - + // passphrase related + let savePassphraseAlert = UIAlertController(title: "Passphrase", message: "Do you want to save the passphrase for later decryption?", preferredStyle: UIAlertControllerStyle.alert) + // no + savePassphraseAlert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.default) { _ in + self.passwordStore.pgpKeyPassphrase = nil + Defaults[.isRememberPassphraseOn] = false + self.saveImportedPGPKey() + }) + // yes + savePassphraseAlert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.destructive) {_ in + // ask for the passphrase + let alert = UIAlertController(title: "Passphrase", message: "Please fill in the passphrase of your PGP secret key.", preferredStyle: UIAlertControllerStyle.alert) + alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in + self.passwordStore.pgpKeyPassphrase = alert.textFields?.first?.text + Defaults[.isRememberPassphraseOn] = true + self.saveImportedPGPKey() + })) + alert.addTextField(configurationHandler: {(textField: UITextField!) in + textField.text = "" + textField.isSecureTextEntry = true + }) + self.present(alert, animated: true, completion: nil) + }) + self.present(savePassphraseAlert, animated: true, completion: nil) } - optionMenu.addAction(fileAction) } else { let fileAction = UIAlertAction(title: "iTunes File Sharing", style: .default) { _ in diff --git a/pass/Models/PasswordStore.swift b/pass/Models/PasswordStore.swift index 157eba0..26e8ab0 100644 --- a/pass/Models/PasswordStore.swift +++ b/pass/Models/PasswordStore.swift @@ -93,10 +93,10 @@ class PasswordStore { if FileManager.default.fileExists(atPath: storeURL.path) { try storeRepository = GTRepository.init(url: storeURL) } + try initPGPKeys() } catch { print(error) } - initPGPKeys() } enum SSHKeyType { @@ -111,13 +111,9 @@ class PasswordStore { try armorKey.write(toFile: keyPath, atomically: true, encoding: .ascii) } - public func initPGPKeys() { - do { - try initPGPKey(.public) - try initPGPKey(.secret) - } catch { - print(error) - } + public func initPGPKeys() throws { + try initPGPKey(.public) + try initPGPKey(.secret) } public func initPGPKey(_ keyType: PGPKeyType) throws { @@ -139,7 +135,7 @@ class PasswordStore { } } - public func initPGPKey(from url: URL, keyType: PGPKeyType) throws{ + public func initPGPKey(from url: URL, keyType: PGPKeyType) throws { var pgpKeyLocalPath = "" if keyType == .public { pgpKeyLocalPath = Globals.pgpPublicKeyPath