diff --git a/.gitignore b/.gitignore
index 347a4a0..0ee7fca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
.DS_Store
.build
+.idea/
diff --git a/NMSSH/NMSSH-iOS.xcodeproj/xcuserdata/ld.xcuserdatad/xcschemes/xcschememanagement.plist b/NMSSH/NMSSH-iOS.xcodeproj/xcuserdata/ld.xcuserdatad/xcschemes/xcschememanagement.plist
index a4dff35..f3f97b2 100644
--- a/NMSSH/NMSSH-iOS.xcodeproj/xcuserdata/ld.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/NMSSH/NMSSH-iOS.xcodeproj/xcuserdata/ld.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -25,12 +25,12 @@
18A0964E17D6A8C4008B76FB
primary
-
+
18A0965D17D6A97C008B76FB
primary
-
+
diff --git a/SCP.xcodeproj/project.pbxproj b/SCP.xcodeproj/project.pbxproj
index 7fa125b..caa2809 100644
--- a/SCP.xcodeproj/project.pbxproj
+++ b/SCP.xcodeproj/project.pbxproj
@@ -224,6 +224,7 @@
6BC17E5220774D6300E2A999 /* Frameworks */,
6BC17E5320774D6300E2A999 /* Resources */,
6BC17E7E2077602000E2A999 /* Embed Frameworks */,
+ 6B9CEB9B208DF296006E2332 /* ShellScript */,
);
buildRules = (
);
@@ -335,6 +336,22 @@
};
/* End PBXResourcesBuildPhase section */
+/* Begin PBXShellScriptBuildPhase section */
+ 6B9CEB9B208DF296006E2332 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "buildNumber=$(/usr/libexec/PlistBuddy -c \"Print CFBundleVersion\" \"$INFOPLIST_FILE\")\nbuildNumber=$(($buildNumber + 1))\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $buildNumber\" \"$INFOPLIST_FILE\"";
+ };
+/* End PBXShellScriptBuildPhase section */
+
/* Begin PBXSourcesBuildPhase section */
6BC17E5120774D6300E2A999 /* Sources */ = {
isa = PBXSourcesBuildPhase;
diff --git a/SCP.xcodeproj/project.xcworkspace/xcuserdata/ld.xcuserdatad/UserInterfaceState.xcuserstate b/SCP.xcodeproj/project.xcworkspace/xcuserdata/ld.xcuserdatad/UserInterfaceState.xcuserstate
index 83c9f3f..94e21c1 100644
Binary files a/SCP.xcodeproj/project.xcworkspace/xcuserdata/ld.xcuserdatad/UserInterfaceState.xcuserstate and b/SCP.xcodeproj/project.xcworkspace/xcuserdata/ld.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/SCP.xcodeproj/project.xcworkspace/xcuserdata/ld.xcuserdatad/xcschemes/xcschememanagement.plist b/SCP.xcodeproj/project.xcworkspace/xcuserdata/ld.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..ee3458d
--- /dev/null
+++ b/SCP.xcodeproj/project.xcworkspace/xcuserdata/ld.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/SCP/AddServerViewController.swift b/SCP/AddServerViewController.swift
index 015c86b..56a3c38 100644
--- a/SCP/AddServerViewController.swift
+++ b/SCP/AddServerViewController.swift
@@ -9,80 +9,80 @@
import Eureka
class AddServerViewController: FormViewController {
-
- var serverForm:Form? = nil
-
+
+ var serverForm: Form? = nil
+
override func viewDidLoad() {
- super.viewDidLoad()
-
+ super.viewDidLoad()
+
serverForm = form +++ Section()
- <<< NameRow(){ row in
- row.title = "Name"
- row.placeholder = "Name"
- row.tag = "name"
- }
- <<< TextRow(){
- $0.title = "Host"
- $0.placeholder = "URL or IP of Host"
- $0.tag = "host"
- }
- <<< IntRow(){
- $0.title = "Port"
- $0.placeholder = "Defaults to 22"
- $0.tag = "port"
- }
- <<< TextRow(){
- $0.title = "Username"
- $0.placeholder = "Defaults to root"
- $0.tag = "user"
- }
- <<< PasswordRow(){
- $0.title = "Password"
- $0.placeholder = "password"
- $0.tag = "pass"
- }
- +++ Section()
- <<< ButtonRow(){
- $0.title = "Add Server"
- }.onCellSelection { cell, row in
- let keychain = Keychain()
- do {
- let nameRow: NameRow? = self.serverForm?.rowBy(tag: "name")
- let portRow: IntRow? = self.serverForm?.rowBy(tag: "port")
- let userRow: TextRow? = self.serverForm?.rowBy(tag: "user")
- let hostRow: TextRow? = self.serverForm?.rowBy(tag: "host")
- let passRow: PasswordRow? = self.serverForm?.rowBy(tag: "pass")
-
- let name = nameRow?.value != nil ? nameRow?.value : "SSH Server"
- let port = portRow?.value != nil ? portRow?.value : 22
- let user = userRow?.value != nil ? userRow?.value : "root"
-
- let server = SSHServer(name: name!,
- host: hostRow!.value!,
- port: port!,
- user: user!,
- pass: passRow!.value!)
+ <<< NameRow() { row in
+ row.title = "Name"
+ row.placeholder = "Name"
+ row.tag = "name"
+ }
+ <<< TextRow() {
+ $0.title = "Host"
+ $0.placeholder = "URL or IP of Host"
+ $0.tag = "host"
+ }
+ <<< IntRow() {
+ $0.title = "Port"
+ $0.placeholder = "Defaults to 22"
+ $0.tag = "port"
+ }
+ <<< TextRow() {
+ $0.title = "Username"
+ $0.placeholder = "Defaults to root"
+ $0.tag = "user"
+ }
+ <<< PasswordRow() {
+ $0.title = "Password"
+ $0.placeholder = "password"
+ $0.tag = "pass"
+ }
+ +++ Section()
+ <<< ButtonRow() {
+ $0.title = "Add Server"
+ }.onCellSelection { cell, row in
+ let keychain = Keychain()
+ do {
+ let nameRow: NameRow? = self.serverForm?.rowBy(tag: "name")
+ let portRow: IntRow? = self.serverForm?.rowBy(tag: "port")
+ let userRow: TextRow? = self.serverForm?.rowBy(tag: "user")
+ let hostRow: TextRow? = self.serverForm?.rowBy(tag: "host")
+ let passRow: PasswordRow? = self.serverForm?.rowBy(tag: "pass")
+
+ let name = nameRow?.value != nil ? nameRow?.value : "SSH Server"
+ let port = portRow?.value != nil ? portRow?.value : 22
+ let user = userRow?.value != nil ? userRow?.value : "root"
- let jsonEncoder = JSONEncoder()
- let jsonData = try jsonEncoder.encode(server)
- let jsonString = String(data: jsonData, encoding: .utf8)
-
- try keychain.set(jsonString!, key: UUID().uuidString)
-
- _ = self.navigationController?.popViewController(animated: true)
- } catch let error {
- print("error: \(error)")
- }
- }
+ let server = SSHServer(name: name!,
+ host: hostRow!.value!,
+ port: port!,
+ user: user!,
+ pass: passRow!.value!)
+
+ let jsonEncoder = JSONEncoder()
+ let jsonData = try jsonEncoder.encode(server)
+ let jsonString = String(data: jsonData, encoding: .utf8)
+
+ try keychain.set(jsonString!, key: UUID().uuidString)
+
+ _ = self.navigationController?.popViewController(animated: true)
+ } catch let error {
+ print("error: \(error)")
+ }
+ }
}
-
+
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
-
-
+
+
/*
// MARK: - Navigation
@@ -92,5 +92,5 @@ class AddServerViewController: FormViewController {
// Pass the selected object to the new view controller.
}
*/
-
+
}
diff --git a/SCP/AppDelegate.swift b/SCP/AppDelegate.swift
index 332968e..13f30d5 100644
--- a/SCP/AppDelegate.swift
+++ b/SCP/AppDelegate.swift
@@ -9,17 +9,12 @@
import UIKit
@UIApplicationMain
-class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDelegate {
+class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
- // Override point for customization after application launch.
- let splitViewController = window!.rootViewController as! UISplitViewController
- let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController
- navigationController.topViewController!.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem
- splitViewController.delegate = self
return true
}
@@ -45,17 +40,5 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
- // MARK: - Split view
-
- func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool {
- guard let secondaryAsNavController = secondaryViewController as? UINavigationController else { return false }
- guard let topAsDetailController = secondaryAsNavController.topViewController as? DetailViewController else { return false }
- if topAsDetailController.detailItem == nil {
- // Return true to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
- return true
- }
- return false
- }
-
}
diff --git a/SCP/Base.lproj/Main.storyboard b/SCP/Base.lproj/Main.storyboard
index 5debda8..9fd01b5 100644
--- a/SCP/Base.lproj/Main.storyboard
+++ b/SCP/Base.lproj/Main.storyboard
@@ -1,5 +1,5 @@
-
+
@@ -85,6 +85,7 @@
+
@@ -131,20 +132,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -178,9 +165,6 @@
-
-
-
@@ -194,6 +178,7 @@
+
@@ -232,7 +217,4 @@
-
-
-
diff --git a/SCP/DetailViewController.swift b/SCP/DetailViewController.swift
index 5c89794..aa0448e 100644
--- a/SCP/DetailViewController.swift
+++ b/SCP/DetailViewController.swift
@@ -8,99 +8,130 @@
import UIKit
-class DetailViewController: UIViewController,UIPopoverPresentationControllerDelegate {
-
+class DetailViewController: UIViewController, UIPopoverPresentationControllerDelegate {
+
@IBOutlet var leftTable: UITableView?
@IBOutlet var rightTable: UITableView?
-
- var leftServer:SSHServerTableViewController? = nil
- var rightServer:SSHServerTableViewController? = nil
-
- func configureView() {
- // Update the user interface for the detail item.
+
+ var leftServer: SSHServerTableViewController? = nil
+ var rightServer: SSHServerTableViewController? = nil
+
+ func configureView() {
+
+ if let viewState = UserDefaults.standard.object(forKey: detailItemUUID + "_selected_view") as? Int {
+ DispatchQueue.main.async {
+ if (viewState == 1) {
+ self.showLeft()
+ } else if (viewState == 2) {
+ self.showBoth()
+ } else if (viewState == 3) {
+ self.showRigh()
+ }
+ }
+ }
+
if let detail = detailItem {
do {
let jsonDecoder = JSONDecoder()
let server = try jsonDecoder.decode(SSHServer.self, from: detail.data(using: .utf8)!)
-
+
+ self.title = server.name
+
leftServer = SSHServerTableViewController.init(nibName: nil, bundle: nil)
rightServer = SSHServerTableViewController.init(nibName: nil, bundle: nil)
-
+
leftServer?.isLeft = true
-
+ rightServer?.isLeft = false
+
leftServer?.tableView = leftTable
rightServer?.tableView = rightTable
-
+
leftServer?.SSHServer = server
rightServer?.SSHServer = server
-
+
leftServer?.presenter = self.presenter
rightServer?.presenter = self.presenter
-
+
leftServer?.sideListener = rightServer?.sideReceived
rightServer?.sideListener = leftServer?.sideReceived
-
+
leftServer?.executionListener = rightServer?.handleAfterExecution
rightServer?.executionListener = leftServer?.handleAfterExecution
-
+
+ leftServer?.serverUUID = detailItemUUID
+ rightServer?.serverUUID = detailItemUUID
+
leftServer?.start();
rightServer?.start();
-
+
} catch let error {
print("error: \(error)")
}
}
}
-
+
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
-
+
leftServer?.stop()
rightServer?.stop()
}
-
+
override func viewDidLoad() {
super.viewDidLoad()
- // Do any additional setup after loading the view, typically from a nib.
- configureView()
-
+
+ DispatchQueue.global(qos: .userInteractive).async {
+ self.configureView()
+ }
+
for barButton in self.navigationItem.rightBarButtonItems! {
- if(barButton.tag == 1) {
+ if (barButton.tag == 1) {
barButton.setIcon(icon: .googleMaterialDesign(.borderLeft), iconSize: 30, color: .blue)
- } else if(barButton.tag == 2) {
+ } else if (barButton.tag == 2) {
barButton.setIcon(icon: .googleMaterialDesign(.borderVertical), iconSize: 30, color: .blue)
- } else if(barButton.tag == 3) {
+ } else if (barButton.tag == 3) {
barButton.setIcon(icon: .googleMaterialDesign(.borderRight), iconSize: 30, color: .blue)
}
}
+
+ self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissOnDone))
+ }
+
+ @objc func dismissOnDone() {
+ self.dismiss(animated: true, completion: nil)
}
-
+
private func presenter(_ viewControllerToPresent: UIAlertController, animated flag: Bool, completion: (() -> Void)? = nil) {
self.present(viewControllerToPresent, animated: flag, completion: completion)
}
-
+
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
-
- @IBAction func showLeft(sender: UIBarButtonItem) {
+
+ @IBAction func showLeft(sender: UIBarButtonItem? = nil) {
leftTable?.isHidden = false
rightTable?.isHidden = true
+
+ UserDefaults.standard.set(1, forKey: detailItemUUID + "_selected_view")
}
-
- @IBAction func showBoth(sender: UIBarButtonItem) {
+
+ @IBAction func showBoth(sender: UIBarButtonItem? = nil) {
leftTable?.isHidden = false
rightTable?.isHidden = false
+ UserDefaults.standard.set(2, forKey: detailItemUUID + "_selected_view")
}
-
- @IBAction func showRigh(sender: UIBarButtonItem) {
+
+ @IBAction func showRigh(sender: UIBarButtonItem? = nil) {
leftTable?.isHidden = true
rightTable?.isHidden = false
+ UserDefaults.standard.set(3, forKey: detailItemUUID + "_selected_view")
}
-
+
var detailItem: String?
-
-
+ var detailItemUUID: String = ""
+
+
}
diff --git a/SCP/Info.plist b/SCP/Info.plist
index b32a9e6..55c9b97 100644
--- a/SCP/Info.plist
+++ b/SCP/Info.plist
@@ -15,9 +15,9 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 1.0
+ 1.1
CFBundleVersion
- 19
+ 33
LSRequiresIPhoneOS
UILaunchStoryboardName
diff --git a/SCP/Keychain.swift b/SCP/Keychain.swift
index 5821748..2bf1422 100755
--- a/SCP/Keychain.swift
+++ b/SCP/Keychain.swift
@@ -223,19 +223,19 @@ public struct AuthenticationPolicy: OptionSet {
@available(watchOS, unavailable)
public static let applicationPassword = AuthenticationPolicy(rawValue: 1 << 31)
- #if swift(>=2.3)
+#if swift(>=2.3)
public let rawValue: UInt
public init(rawValue: UInt) {
self.rawValue = rawValue
}
- #else
- public let rawValue: Int
+#else
+public let rawValue:Int
- public init(rawValue: Int) {
- self.rawValue = rawValue
- }
- #endif
+public init(rawValue:Int) {
+self.rawValue = rawValue
+}
+#endif
}
public struct Attributes {
@@ -392,12 +392,12 @@ public final class Keychain {
return options.authenticationPrompt
}
- #if os(iOS) || os(OSX)
+#if os(iOS) || os(OSX)
@available(iOS 9.0, OSX 10.11, *)
public var authenticationContext: LAContext? {
return options.authenticationContext as? LAContext
}
- #endif
+#endif
fileprivate let options: Options
@@ -487,7 +487,9 @@ public final class Keychain {
public func attributes(_ attributes: [String: Any]) -> Keychain {
var options = self.options
- attributes.forEach { options.attributes.updateValue($1, forKey: $0) }
+ attributes.forEach {
+ options.attributes.updateValue($1, forKey: $0)
+ }
return Keychain(options)
}
@@ -499,14 +501,14 @@ public final class Keychain {
return Keychain(options)
}
- #if os(iOS) || os(OSX)
+#if os(iOS) || os(OSX)
@available(iOS 9.0, OSX 10.11, *)
public func authenticationContext(_ authenticationContext: LAContext) -> Keychain {
var options = self.options
options.authenticationContext = authenticationContext
return Keychain(options)
}
- #endif
+#endif
// MARK:
@@ -515,7 +517,7 @@ public final class Keychain {
}
public func getString(_ key: String) throws -> String? {
- guard let data = try getData(key) else {
+ guard let data = try getData(key) else {
return nil
}
guard let string = String(data: data, encoding: .utf8) else {
@@ -590,18 +592,18 @@ public final class Keychain {
public func set(_ value: Data, key: String) throws {
var query = options.query()
query[AttributeAccount] = key
- #if os(iOS)
+#if os(iOS)
if #available(iOS 9.0, *) {
query[UseAuthenticationUI] = UseAuthenticationUIFail
} else {
query[UseNoAuthenticationUI] = kCFBooleanTrue
}
- #elseif os(OSX)
+#elseif os(OSX)
query[ReturnData] = kCFBooleanTrue
if #available(OSX 10.11, *) {
query[UseAuthenticationUI] = UseAuthenticationUIFail
}
- #endif
+#endif
var status = SecItemCopyMatching(query as CFDictionary, nil)
switch status {
@@ -615,9 +617,11 @@ public final class Keychain {
throw error
}
- options.attributes.forEach { attributes.updateValue($1, forKey: $0) }
+ options.attributes.forEach {
+ attributes.updateValue($1, forKey: $0)
+ }
- #if os(iOS)
+#if os(iOS)
if status == errSecInteractionNotAllowed && floor(NSFoundationVersionNumber) <= floor(NSFoundationVersionNumber_iOS_8_0) {
try remove(key)
try set(value, key: key)
@@ -627,12 +631,12 @@ public final class Keychain {
throw securityError(status: status)
}
}
- #else
+#else
status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)
if status != errSecSuccess {
throw securityError(status: status)
}
- #endif
+#endif
case errSecItemNotFound:
var (attributes, error) = options.attributes(key: key, value: value)
if let error = error {
@@ -640,7 +644,9 @@ public final class Keychain {
throw error
}
- options.attributes.forEach { attributes.updateValue($1, forKey: $0) }
+ options.attributes.forEach {
+ attributes.updateValue($1, forKey: $0)
+ }
status = SecItemAdd(attributes as CFDictionary, nil)
if status != errSecSuccess {
@@ -653,18 +659,22 @@ public final class Keychain {
public subscript(key: String) -> String? {
get {
- return (try? get(key)).flatMap { $0 }
+ return (try? get(key)).flatMap {
+ $0
+ }
}
set {
if let value = newValue {
do {
try set(value, key: key)
- } catch {}
+ } catch {
+ }
} else {
do {
try remove(key)
- } catch {}
+ } catch {
+ }
}
}
}
@@ -681,25 +691,33 @@ public final class Keychain {
public subscript(data key: String) -> Data? {
get {
- return (try? getData(key)).flatMap { $0 }
+ return (try? getData(key)).flatMap {
+ $0
+ }
}
set {
if let value = newValue {
do {
try set(value, key: key)
- } catch {}
+ } catch {
+ }
} else {
do {
try remove(key)
- } catch {}
+ } catch {
+ }
}
}
}
public subscript(attributes key: String) -> Attributes? {
get {
- return (try? get(key) { $0 }).flatMap { $0 }
+ return (try? get(key) {
+ $0
+ }).flatMap {
+ $0
+ }
}
}
@@ -717,9 +735,9 @@ public final class Keychain {
public func removeAll() throws {
var query = options.query()
- #if !os(iOS) && !os(watchOS) && !os(tvOS)
+#if !os(iOS) && !os(watchOS) && !os(tvOS)
query[MatchLimit] = MatchLimitAll
- #endif
+#endif
let status = SecItemDelete(query as CFDictionary)
if status != errSecSuccess && status != errSecItemNotFound {
@@ -778,7 +796,9 @@ public final class Keychain {
}
public func allKeys() -> [String] {
- return type(of: self).prettify(itemClass: itemClass, items: items()).compactMap { $0["key"] as? String }
+ return type(of: self).prettify(itemClass: itemClass, items: items()).compactMap {
+ $0["key"] as? String
+ }
}
public class func allItems(_ itemClass: ItemClass) -> [[String: Any]] {
@@ -786,9 +806,9 @@ public final class Keychain {
query[Class] = itemClass.rawValue
query[MatchLimit] = MatchLimitAll
query[ReturnAttributes] = kCFBooleanTrue
- #if os(iOS) || os(watchOS) || os(tvOS)
+#if os(iOS) || os(watchOS) || os(tvOS)
query[ReturnData] = kCFBooleanTrue
- #endif
+#endif
var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)
@@ -811,9 +831,10 @@ public final class Keychain {
return type(of: self).prettify(itemClass: itemClass, items: items())
}
- #if os(iOS)
+#if os(iOS)
@available(iOS 8.0, *)
- public func getSharedPassword(_ completion: @escaping (_ account: String?, _ password: String?, _ error: Error?) -> () = { account, password, error -> () in }) {
+ public func getSharedPassword(_ completion: @escaping (_ account: String?, _ password: String?, _ error: Error?) -> () = { account, password, error -> () in
+ }) {
if let domain = server.host {
type(of: self).requestSharedWebCredential(domain: domain, account: nil) { (credentials, error) -> () in
if let credential = credentials.first {
@@ -829,11 +850,12 @@ public final class Keychain {
completion(nil, nil, error)
}
}
- #endif
+#endif
- #if os(iOS)
+#if os(iOS)
@available(iOS 8.0, *)
- public func getSharedPassword(_ account: String, completion: @escaping (_ password: String?, _ error: Error?) -> () = { password, error -> () in }) {
+ public func getSharedPassword(_ account: String, completion: @escaping (_ password: String?, _ error: Error?) -> () = { password, error -> () in
+ }) {
if let domain = server.host {
type(of: self).requestSharedWebCredential(domain: domain, account: account) { (credentials, error) -> () in
if let credential = credentials.first {
@@ -851,18 +873,20 @@ public final class Keychain {
completion(nil, error)
}
}
- #endif
+#endif
- #if os(iOS)
+#if os(iOS)
@available(iOS 8.0, *)
- public func setSharedPassword(_ password: String, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
+ public func setSharedPassword(_ password: String, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in
+ }) {
setSharedPassword(password as String?, account: account, completion: completion)
}
- #endif
+#endif
- #if os(iOS)
+#if os(iOS)
@available(iOS 8.0, *)
- fileprivate func setSharedPassword(_ password: String?, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
+ fileprivate func setSharedPassword(_ password: String?, account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in
+ }) {
if let domain = server.host {
SecAddSharedWebCredential(domain as CFString, account as CFString, password as CFString?) { error -> () in
if let error = error {
@@ -876,37 +900,41 @@ public final class Keychain {
completion(error)
}
}
- #endif
+#endif
- #if os(iOS)
+#if os(iOS)
@available(iOS 8.0, *)
- public func removeSharedPassword(_ account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in }) {
+ public func removeSharedPassword(_ account: String, completion: @escaping (_ error: Error?) -> () = { e -> () in
+ }) {
setSharedPassword(nil, account: account, completion: completion)
}
- #endif
+#endif
- #if os(iOS)
+#if os(iOS)
@available(iOS 8.0, *)
- public class func requestSharedWebCredential(_ completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
+ public class func requestSharedWebCredential(_ completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in
+ }) {
requestSharedWebCredential(domain: nil, account: nil, completion: completion)
}
- #endif
+#endif
- #if os(iOS)
+#if os(iOS)
@available(iOS 8.0, *)
- public class func requestSharedWebCredential(domain: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
+ public class func requestSharedWebCredential(domain: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in
+ }) {
requestSharedWebCredential(domain: domain, account: nil, completion: completion)
}
- #endif
+#endif
- #if os(iOS)
+#if os(iOS)
@available(iOS 8.0, *)
- public class func requestSharedWebCredential(domain: String, account: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in }) {
+ public class func requestSharedWebCredential(domain: String, account: String, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> () = { credentials, error -> () in
+ }) {
requestSharedWebCredential(domain: Optional(domain), account: Optional(account)!, completion: completion)
}
- #endif
+#endif
- #if os(iOS)
+#if os(iOS)
@available(iOS 8.0, *)
fileprivate class func requestSharedWebCredential(domain: String?, account: String?, completion: @escaping (_ credentials: [[String: String]], _ error: Error?) -> ()) {
SecRequestSharedWebCredential(domain as CFString?, account as CFString?) { (credentials, error) -> () in
@@ -939,9 +967,9 @@ public final class Keychain {
}
}
}
- #endif
+#endif
- #if os(iOS)
+#if os(iOS)
/**
@abstract Returns a randomly generated password.
@return String password in the form xxx-xxx-xxx-xxx where x is taken from the sets "abcdefghkmnopqrstuvwxy", "ABCDEFGHJKLMNPQRSTUVWXYZ", "3456789" with at least one character from each set being present.
@@ -950,7 +978,7 @@ public final class Keychain {
public class func generatePassword() -> String {
return SecCreateSharedWebCredentialPassword()! as String
}
- #endif
+#endif
// MARK:
@@ -958,9 +986,9 @@ public final class Keychain {
var query = options.query()
query[MatchLimit] = MatchLimitAll
query[ReturnAttributes] = kCFBooleanTrue
- #if os(iOS) || os(watchOS) || os(tvOS)
+#if os(iOS) || os(watchOS) || os(tvOS)
query[ReturnData] = kCFBooleanTrue
- #endif
+#endif
var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)
@@ -1015,7 +1043,7 @@ public final class Keychain {
if let data = attributes[ValueData] as? Data {
if let text = String(data: data, encoding: .utf8) {
item["value"] = text
- } else {
+ } else {
item["value"] = data
}
}
@@ -1188,11 +1216,11 @@ extension Options {
case .genericPassword:
query[AttributeService] = service
// Access group is not supported on any simulators.
- #if (!arch(i386) && !arch(x86_64)) || (!os(iOS) && !os(watchOS) && !os(tvOS))
+#if (!arch(i386) && !arch(x86_64)) || (!os(iOS) && !os(watchOS) && !os(tvOS))
if let accessGroup = self.accessGroup {
query[AttributeAccessGroup] = accessGroup
}
- #endif
+#endif
case .internetPassword:
query[AttributeServer] = server.host
query[AttributePort] = server.port
@@ -1206,13 +1234,13 @@ extension Options {
}
}
- #if !os(watchOS)
+#if !os(watchOS)
if #available(iOS 9.0, OSX 10.11, *) {
if authenticationContext != nil {
query[UseAuthenticationContext] = authenticationContext
}
}
- #endif
+#endif
return query
}
@@ -1674,409 +1702,409 @@ extension CFError {
}
public enum Status: OSStatus, Error {
- case success = 0
- case unimplemented = -4
- case diskFull = -34
- case io = -36
- case opWr = -49
- case param = -50
- case wrPerm = -61
- case allocate = -108
- case userCanceled = -128
- case badReq = -909
- case internalComponent = -2070
- case notAvailable = -25291
- case readOnly = -25292
- case authFailed = -25293
- case noSuchKeychain = -25294
- case invalidKeychain = -25295
- case duplicateKeychain = -25296
- case duplicateCallback = -25297
- case invalidCallback = -25298
- case duplicateItem = -25299
- case itemNotFound = -25300
- case bufferTooSmall = -25301
- case dataTooLarge = -25302
- case noSuchAttr = -25303
- case invalidItemRef = -25304
- case invalidSearchRef = -25305
- case noSuchClass = -25306
- case noDefaultKeychain = -25307
- case interactionNotAllowed = -25308
- case readOnlyAttr = -25309
- case wrongSecVersion = -25310
- case keySizeNotAllowed = -25311
- case noStorageModule = -25312
- case noCertificateModule = -25313
- case noPolicyModule = -25314
- case interactionRequired = -25315
- case dataNotAvailable = -25316
- case dataNotModifiable = -25317
- case createChainFailed = -25318
- case invalidPrefsDomain = -25319
- case inDarkWake = -25320
- case aclNotSimple = -25240
- case policyNotFound = -25241
- case invalidTrustSetting = -25242
- case noAccessForItem = -25243
- case invalidOwnerEdit = -25244
- case trustNotAvailable = -25245
- case unsupportedFormat = -25256
- case unknownFormat = -25257
- case keyIsSensitive = -25258
- case multiplePrivKeys = -25259
- case passphraseRequired = -25260
- case invalidPasswordRef = -25261
- case invalidTrustSettings = -25262
- case noTrustSettings = -25263
- case pkcs12VerifyFailure = -25264
- case invalidCertificate = -26265
- case notSigner = -26267
- case policyDenied = -26270
- case invalidKey = -26274
- case decode = -26275
- case `internal` = -26276
- case unsupportedAlgorithm = -26268
- case unsupportedOperation = -26271
- case unsupportedPadding = -26273
- case itemInvalidKey = -34000
- case itemInvalidKeyType = -34001
- case itemInvalidValue = -34002
- case itemClassMissing = -34003
- case itemMatchUnsupported = -34004
- case useItemListUnsupported = -34005
- case useKeychainUnsupported = -34006
- case useKeychainListUnsupported = -34007
- case returnDataUnsupported = -34008
- case returnAttributesUnsupported = -34009
- case returnRefUnsupported = -34010
- case returnPersitentRefUnsupported = -34011
- case valueRefUnsupported = -34012
- case valuePersistentRefUnsupported = -34013
- case returnMissingPointer = -34014
- case matchLimitUnsupported = -34015
- case itemIllegalQuery = -34016
- case waitForCallback = -34017
- case missingEntitlement = -34018
- case upgradePending = -34019
- case mpSignatureInvalid = -25327
- case otrTooOld = -25328
- case otrIDTooNew = -25329
- case serviceNotAvailable = -67585
- case insufficientClientID = -67586
- case deviceReset = -67587
- case deviceFailed = -67588
- case appleAddAppACLSubject = -67589
- case applePublicKeyIncomplete = -67590
- case appleSignatureMismatch = -67591
- case appleInvalidKeyStartDate = -67592
- case appleInvalidKeyEndDate = -67593
- case conversionError = -67594
- case appleSSLv2Rollback = -67595
- case quotaExceeded = -67596
- case fileTooBig = -67597
- case invalidDatabaseBlob = -67598
- case invalidKeyBlob = -67599
- case incompatibleDatabaseBlob = -67600
- case incompatibleKeyBlob = -67601
- case hostNameMismatch = -67602
- case unknownCriticalExtensionFlag = -67603
- case noBasicConstraints = -67604
- case noBasicConstraintsCA = -67605
- case invalidAuthorityKeyID = -67606
- case invalidSubjectKeyID = -67607
- case invalidKeyUsageForPolicy = -67608
- case invalidExtendedKeyUsage = -67609
- case invalidIDLinkage = -67610
- case pathLengthConstraintExceeded = -67611
- case invalidRoot = -67612
- case crlExpired = -67613
- case crlNotValidYet = -67614
- case crlNotFound = -67615
- case crlServerDown = -67616
- case crlBadURI = -67617
- case unknownCertExtension = -67618
- case unknownCRLExtension = -67619
- case crlNotTrusted = -67620
- case crlPolicyFailed = -67621
- case idpFailure = -67622
- case smimeEmailAddressesNotFound = -67623
- case smimeBadExtendedKeyUsage = -67624
- case smimeBadKeyUsage = -67625
- case smimeKeyUsageNotCritical = -67626
- case smimeNoEmailAddress = -67627
- case smimeSubjAltNameNotCritical = -67628
- case sslBadExtendedKeyUsage = -67629
- case ocspBadResponse = -67630
- case ocspBadRequest = -67631
- case ocspUnavailable = -67632
- case ocspStatusUnrecognized = -67633
- case endOfData = -67634
- case incompleteCertRevocationCheck = -67635
- case networkFailure = -67636
- case ocspNotTrustedToAnchor = -67637
- case recordModified = -67638
- case ocspSignatureError = -67639
- case ocspNoSigner = -67640
- case ocspResponderMalformedReq = -67641
- case ocspResponderInternalError = -67642
- case ocspResponderTryLater = -67643
- case ocspResponderSignatureRequired = -67644
- case ocspResponderUnauthorized = -67645
- case ocspResponseNonceMismatch = -67646
- case codeSigningBadCertChainLength = -67647
- case codeSigningNoBasicConstraints = -67648
+ case success = 0
+ case unimplemented = -4
+ case diskFull = -34
+ case io = -36
+ case opWr = -49
+ case param = -50
+ case wrPerm = -61
+ case allocate = -108
+ case userCanceled = -128
+ case badReq = -909
+ case internalComponent = -2070
+ case notAvailable = -25291
+ case readOnly = -25292
+ case authFailed = -25293
+ case noSuchKeychain = -25294
+ case invalidKeychain = -25295
+ case duplicateKeychain = -25296
+ case duplicateCallback = -25297
+ case invalidCallback = -25298
+ case duplicateItem = -25299
+ case itemNotFound = -25300
+ case bufferTooSmall = -25301
+ case dataTooLarge = -25302
+ case noSuchAttr = -25303
+ case invalidItemRef = -25304
+ case invalidSearchRef = -25305
+ case noSuchClass = -25306
+ case noDefaultKeychain = -25307
+ case interactionNotAllowed = -25308
+ case readOnlyAttr = -25309
+ case wrongSecVersion = -25310
+ case keySizeNotAllowed = -25311
+ case noStorageModule = -25312
+ case noCertificateModule = -25313
+ case noPolicyModule = -25314
+ case interactionRequired = -25315
+ case dataNotAvailable = -25316
+ case dataNotModifiable = -25317
+ case createChainFailed = -25318
+ case invalidPrefsDomain = -25319
+ case inDarkWake = -25320
+ case aclNotSimple = -25240
+ case policyNotFound = -25241
+ case invalidTrustSetting = -25242
+ case noAccessForItem = -25243
+ case invalidOwnerEdit = -25244
+ case trustNotAvailable = -25245
+ case unsupportedFormat = -25256
+ case unknownFormat = -25257
+ case keyIsSensitive = -25258
+ case multiplePrivKeys = -25259
+ case passphraseRequired = -25260
+ case invalidPasswordRef = -25261
+ case invalidTrustSettings = -25262
+ case noTrustSettings = -25263
+ case pkcs12VerifyFailure = -25264
+ case invalidCertificate = -26265
+ case notSigner = -26267
+ case policyDenied = -26270
+ case invalidKey = -26274
+ case decode = -26275
+ case `internal` = -26276
+ case unsupportedAlgorithm = -26268
+ case unsupportedOperation = -26271
+ case unsupportedPadding = -26273
+ case itemInvalidKey = -34000
+ case itemInvalidKeyType = -34001
+ case itemInvalidValue = -34002
+ case itemClassMissing = -34003
+ case itemMatchUnsupported = -34004
+ case useItemListUnsupported = -34005
+ case useKeychainUnsupported = -34006
+ case useKeychainListUnsupported = -34007
+ case returnDataUnsupported = -34008
+ case returnAttributesUnsupported = -34009
+ case returnRefUnsupported = -34010
+ case returnPersitentRefUnsupported = -34011
+ case valueRefUnsupported = -34012
+ case valuePersistentRefUnsupported = -34013
+ case returnMissingPointer = -34014
+ case matchLimitUnsupported = -34015
+ case itemIllegalQuery = -34016
+ case waitForCallback = -34017
+ case missingEntitlement = -34018
+ case upgradePending = -34019
+ case mpSignatureInvalid = -25327
+ case otrTooOld = -25328
+ case otrIDTooNew = -25329
+ case serviceNotAvailable = -67585
+ case insufficientClientID = -67586
+ case deviceReset = -67587
+ case deviceFailed = -67588
+ case appleAddAppACLSubject = -67589
+ case applePublicKeyIncomplete = -67590
+ case appleSignatureMismatch = -67591
+ case appleInvalidKeyStartDate = -67592
+ case appleInvalidKeyEndDate = -67593
+ case conversionError = -67594
+ case appleSSLv2Rollback = -67595
+ case quotaExceeded = -67596
+ case fileTooBig = -67597
+ case invalidDatabaseBlob = -67598
+ case invalidKeyBlob = -67599
+ case incompatibleDatabaseBlob = -67600
+ case incompatibleKeyBlob = -67601
+ case hostNameMismatch = -67602
+ case unknownCriticalExtensionFlag = -67603
+ case noBasicConstraints = -67604
+ case noBasicConstraintsCA = -67605
+ case invalidAuthorityKeyID = -67606
+ case invalidSubjectKeyID = -67607
+ case invalidKeyUsageForPolicy = -67608
+ case invalidExtendedKeyUsage = -67609
+ case invalidIDLinkage = -67610
+ case pathLengthConstraintExceeded = -67611
+ case invalidRoot = -67612
+ case crlExpired = -67613
+ case crlNotValidYet = -67614
+ case crlNotFound = -67615
+ case crlServerDown = -67616
+ case crlBadURI = -67617
+ case unknownCertExtension = -67618
+ case unknownCRLExtension = -67619
+ case crlNotTrusted = -67620
+ case crlPolicyFailed = -67621
+ case idpFailure = -67622
+ case smimeEmailAddressesNotFound = -67623
+ case smimeBadExtendedKeyUsage = -67624
+ case smimeBadKeyUsage = -67625
+ case smimeKeyUsageNotCritical = -67626
+ case smimeNoEmailAddress = -67627
+ case smimeSubjAltNameNotCritical = -67628
+ case sslBadExtendedKeyUsage = -67629
+ case ocspBadResponse = -67630
+ case ocspBadRequest = -67631
+ case ocspUnavailable = -67632
+ case ocspStatusUnrecognized = -67633
+ case endOfData = -67634
+ case incompleteCertRevocationCheck = -67635
+ case networkFailure = -67636
+ case ocspNotTrustedToAnchor = -67637
+ case recordModified = -67638
+ case ocspSignatureError = -67639
+ case ocspNoSigner = -67640
+ case ocspResponderMalformedReq = -67641
+ case ocspResponderInternalError = -67642
+ case ocspResponderTryLater = -67643
+ case ocspResponderSignatureRequired = -67644
+ case ocspResponderUnauthorized = -67645
+ case ocspResponseNonceMismatch = -67646
+ case codeSigningBadCertChainLength = -67647
+ case codeSigningNoBasicConstraints = -67648
case codeSigningBadPathLengthConstraint = -67649
- case codeSigningNoExtendedKeyUsage = -67650
- case codeSigningDevelopment = -67651
- case resourceSignBadCertChainLength = -67652
- case resourceSignBadExtKeyUsage = -67653
- case trustSettingDeny = -67654
- case invalidSubjectName = -67655
- case unknownQualifiedCertStatement = -67656
- case mobileMeRequestQueued = -67657
- case mobileMeRequestRedirected = -67658
- case mobileMeServerError = -67659
- case mobileMeServerNotAvailable = -67660
- case mobileMeServerAlreadyExists = -67661
- case mobileMeServerServiceErr = -67662
- case mobileMeRequestAlreadyPending = -67663
- case mobileMeNoRequestPending = -67664
- case mobileMeCSRVerifyFailure = -67665
- case mobileMeFailedConsistencyCheck = -67666
- case notInitialized = -67667
- case invalidHandleUsage = -67668
- case pvcReferentNotFound = -67669
- case functionIntegrityFail = -67670
- case internalError = -67671
- case memoryError = -67672
- case invalidData = -67673
- case mdsError = -67674
- case invalidPointer = -67675
- case selfCheckFailed = -67676
- case functionFailed = -67677
- case moduleManifestVerifyFailed = -67678
- case invalidGUID = -67679
- case invalidHandle = -67680
- case invalidDBList = -67681
- case invalidPassthroughID = -67682
- case invalidNetworkAddress = -67683
- case crlAlreadySigned = -67684
- case invalidNumberOfFields = -67685
- case verificationFailure = -67686
- case unknownTag = -67687
- case invalidSignature = -67688
- case invalidName = -67689
- case invalidCertificateRef = -67690
- case invalidCertificateGroup = -67691
- case tagNotFound = -67692
- case invalidQuery = -67693
- case invalidValue = -67694
- case callbackFailed = -67695
- case aclDeleteFailed = -67696
- case aclReplaceFailed = -67697
- case aclAddFailed = -67698
- case aclChangeFailed = -67699
- case invalidAccessCredentials = -67700
- case invalidRecord = -67701
- case invalidACL = -67702
- case invalidSampleValue = -67703
- case incompatibleVersion = -67704
- case privilegeNotGranted = -67705
- case invalidScope = -67706
- case pvcAlreadyConfigured = -67707
- case invalidPVC = -67708
- case emmLoadFailed = -67709
- case emmUnloadFailed = -67710
- case addinLoadFailed = -67711
- case invalidKeyRef = -67712
- case invalidKeyHierarchy = -67713
- case addinUnloadFailed = -67714
- case libraryReferenceNotFound = -67715
- case invalidAddinFunctionTable = -67716
- case invalidServiceMask = -67717
- case moduleNotLoaded = -67718
- case invalidSubServiceID = -67719
- case attributeNotInContext = -67720
- case moduleManagerInitializeFailed = -67721
- case moduleManagerNotFound = -67722
- case eventNotificationCallbackNotFound = -67723
- case inputLengthError = -67724
- case outputLengthError = -67725
- case privilegeNotSupported = -67726
- case deviceError = -67727
- case attachHandleBusy = -67728
- case notLoggedIn = -67729
- case algorithmMismatch = -67730
- case keyUsageIncorrect = -67731
- case keyBlobTypeIncorrect = -67732
- case keyHeaderInconsistent = -67733
- case unsupportedKeyFormat = -67734
- case unsupportedKeySize = -67735
- case invalidKeyUsageMask = -67736
- case unsupportedKeyUsageMask = -67737
- case invalidKeyAttributeMask = -67738
- case unsupportedKeyAttributeMask = -67739
- case invalidKeyLabel = -67740
- case unsupportedKeyLabel = -67741
- case invalidKeyFormat = -67742
- case unsupportedVectorOfBuffers = -67743
- case invalidInputVector = -67744
- case invalidOutputVector = -67745
- case invalidContext = -67746
- case invalidAlgorithm = -67747
- case invalidAttributeKey = -67748
- case missingAttributeKey = -67749
- case invalidAttributeInitVector = -67750
- case missingAttributeInitVector = -67751
- case invalidAttributeSalt = -67752
- case missingAttributeSalt = -67753
- case invalidAttributePadding = -67754
- case missingAttributePadding = -67755
- case invalidAttributeRandom = -67756
- case missingAttributeRandom = -67757
- case invalidAttributeSeed = -67758
- case missingAttributeSeed = -67759
- case invalidAttributePassphrase = -67760
- case missingAttributePassphrase = -67761
- case invalidAttributeKeyLength = -67762
- case missingAttributeKeyLength = -67763
- case invalidAttributeBlockSize = -67764
- case missingAttributeBlockSize = -67765
- case invalidAttributeOutputSize = -67766
- case missingAttributeOutputSize = -67767
- case invalidAttributeRounds = -67768
- case missingAttributeRounds = -67769
- case invalidAlgorithmParms = -67770
- case missingAlgorithmParms = -67771
- case invalidAttributeLabel = -67772
- case missingAttributeLabel = -67773
- case invalidAttributeKeyType = -67774
- case missingAttributeKeyType = -67775
- case invalidAttributeMode = -67776
- case missingAttributeMode = -67777
- case invalidAttributeEffectiveBits = -67778
- case missingAttributeEffectiveBits = -67779
- case invalidAttributeStartDate = -67780
- case missingAttributeStartDate = -67781
- case invalidAttributeEndDate = -67782
- case missingAttributeEndDate = -67783
- case invalidAttributeVersion = -67784
- case missingAttributeVersion = -67785
- case invalidAttributePrime = -67786
- case missingAttributePrime = -67787
- case invalidAttributeBase = -67788
- case missingAttributeBase = -67789
- case invalidAttributeSubprime = -67790
- case missingAttributeSubprime = -67791
- case invalidAttributeIterationCount = -67792
- case missingAttributeIterationCount = -67793
- case invalidAttributeDLDBHandle = -67794
- case missingAttributeDLDBHandle = -67795
- case invalidAttributeAccessCredentials = -67796
- case missingAttributeAccessCredentials = -67797
- case invalidAttributePublicKeyFormat = -67798
- case missingAttributePublicKeyFormat = -67799
- case invalidAttributePrivateKeyFormat = -67800
- case missingAttributePrivateKeyFormat = -67801
+ case codeSigningNoExtendedKeyUsage = -67650
+ case codeSigningDevelopment = -67651
+ case resourceSignBadCertChainLength = -67652
+ case resourceSignBadExtKeyUsage = -67653
+ case trustSettingDeny = -67654
+ case invalidSubjectName = -67655
+ case unknownQualifiedCertStatement = -67656
+ case mobileMeRequestQueued = -67657
+ case mobileMeRequestRedirected = -67658
+ case mobileMeServerError = -67659
+ case mobileMeServerNotAvailable = -67660
+ case mobileMeServerAlreadyExists = -67661
+ case mobileMeServerServiceErr = -67662
+ case mobileMeRequestAlreadyPending = -67663
+ case mobileMeNoRequestPending = -67664
+ case mobileMeCSRVerifyFailure = -67665
+ case mobileMeFailedConsistencyCheck = -67666
+ case notInitialized = -67667
+ case invalidHandleUsage = -67668
+ case pvcReferentNotFound = -67669
+ case functionIntegrityFail = -67670
+ case internalError = -67671
+ case memoryError = -67672
+ case invalidData = -67673
+ case mdsError = -67674
+ case invalidPointer = -67675
+ case selfCheckFailed = -67676
+ case functionFailed = -67677
+ case moduleManifestVerifyFailed = -67678
+ case invalidGUID = -67679
+ case invalidHandle = -67680
+ case invalidDBList = -67681
+ case invalidPassthroughID = -67682
+ case invalidNetworkAddress = -67683
+ case crlAlreadySigned = -67684
+ case invalidNumberOfFields = -67685
+ case verificationFailure = -67686
+ case unknownTag = -67687
+ case invalidSignature = -67688
+ case invalidName = -67689
+ case invalidCertificateRef = -67690
+ case invalidCertificateGroup = -67691
+ case tagNotFound = -67692
+ case invalidQuery = -67693
+ case invalidValue = -67694
+ case callbackFailed = -67695
+ case aclDeleteFailed = -67696
+ case aclReplaceFailed = -67697
+ case aclAddFailed = -67698
+ case aclChangeFailed = -67699
+ case invalidAccessCredentials = -67700
+ case invalidRecord = -67701
+ case invalidACL = -67702
+ case invalidSampleValue = -67703
+ case incompatibleVersion = -67704
+ case privilegeNotGranted = -67705
+ case invalidScope = -67706
+ case pvcAlreadyConfigured = -67707
+ case invalidPVC = -67708
+ case emmLoadFailed = -67709
+ case emmUnloadFailed = -67710
+ case addinLoadFailed = -67711
+ case invalidKeyRef = -67712
+ case invalidKeyHierarchy = -67713
+ case addinUnloadFailed = -67714
+ case libraryReferenceNotFound = -67715
+ case invalidAddinFunctionTable = -67716
+ case invalidServiceMask = -67717
+ case moduleNotLoaded = -67718
+ case invalidSubServiceID = -67719
+ case attributeNotInContext = -67720
+ case moduleManagerInitializeFailed = -67721
+ case moduleManagerNotFound = -67722
+ case eventNotificationCallbackNotFound = -67723
+ case inputLengthError = -67724
+ case outputLengthError = -67725
+ case privilegeNotSupported = -67726
+ case deviceError = -67727
+ case attachHandleBusy = -67728
+ case notLoggedIn = -67729
+ case algorithmMismatch = -67730
+ case keyUsageIncorrect = -67731
+ case keyBlobTypeIncorrect = -67732
+ case keyHeaderInconsistent = -67733
+ case unsupportedKeyFormat = -67734
+ case unsupportedKeySize = -67735
+ case invalidKeyUsageMask = -67736
+ case unsupportedKeyUsageMask = -67737
+ case invalidKeyAttributeMask = -67738
+ case unsupportedKeyAttributeMask = -67739
+ case invalidKeyLabel = -67740
+ case unsupportedKeyLabel = -67741
+ case invalidKeyFormat = -67742
+ case unsupportedVectorOfBuffers = -67743
+ case invalidInputVector = -67744
+ case invalidOutputVector = -67745
+ case invalidContext = -67746
+ case invalidAlgorithm = -67747
+ case invalidAttributeKey = -67748
+ case missingAttributeKey = -67749
+ case invalidAttributeInitVector = -67750
+ case missingAttributeInitVector = -67751
+ case invalidAttributeSalt = -67752
+ case missingAttributeSalt = -67753
+ case invalidAttributePadding = -67754
+ case missingAttributePadding = -67755
+ case invalidAttributeRandom = -67756
+ case missingAttributeRandom = -67757
+ case invalidAttributeSeed = -67758
+ case missingAttributeSeed = -67759
+ case invalidAttributePassphrase = -67760
+ case missingAttributePassphrase = -67761
+ case invalidAttributeKeyLength = -67762
+ case missingAttributeKeyLength = -67763
+ case invalidAttributeBlockSize = -67764
+ case missingAttributeBlockSize = -67765
+ case invalidAttributeOutputSize = -67766
+ case missingAttributeOutputSize = -67767
+ case invalidAttributeRounds = -67768
+ case missingAttributeRounds = -67769
+ case invalidAlgorithmParms = -67770
+ case missingAlgorithmParms = -67771
+ case invalidAttributeLabel = -67772
+ case missingAttributeLabel = -67773
+ case invalidAttributeKeyType = -67774
+ case missingAttributeKeyType = -67775
+ case invalidAttributeMode = -67776
+ case missingAttributeMode = -67777
+ case invalidAttributeEffectiveBits = -67778
+ case missingAttributeEffectiveBits = -67779
+ case invalidAttributeStartDate = -67780
+ case missingAttributeStartDate = -67781
+ case invalidAttributeEndDate = -67782
+ case missingAttributeEndDate = -67783
+ case invalidAttributeVersion = -67784
+ case missingAttributeVersion = -67785
+ case invalidAttributePrime = -67786
+ case missingAttributePrime = -67787
+ case invalidAttributeBase = -67788
+ case missingAttributeBase = -67789
+ case invalidAttributeSubprime = -67790
+ case missingAttributeSubprime = -67791
+ case invalidAttributeIterationCount = -67792
+ case missingAttributeIterationCount = -67793
+ case invalidAttributeDLDBHandle = -67794
+ case missingAttributeDLDBHandle = -67795
+ case invalidAttributeAccessCredentials = -67796
+ case missingAttributeAccessCredentials = -67797
+ case invalidAttributePublicKeyFormat = -67798
+ case missingAttributePublicKeyFormat = -67799
+ case invalidAttributePrivateKeyFormat = -67800
+ case missingAttributePrivateKeyFormat = -67801
case invalidAttributeSymmetricKeyFormat = -67802
case missingAttributeSymmetricKeyFormat = -67803
- case invalidAttributeWrappedKeyFormat = -67804
- case missingAttributeWrappedKeyFormat = -67805
- case stagedOperationInProgress = -67806
- case stagedOperationNotStarted = -67807
- case verifyFailed = -67808
- case querySizeUnknown = -67809
- case blockSizeMismatch = -67810
- case publicKeyInconsistent = -67811
- case deviceVerifyFailed = -67812
- case invalidLoginName = -67813
- case alreadyLoggedIn = -67814
- case invalidDigestAlgorithm = -67815
- case invalidCRLGroup = -67816
- case certificateCannotOperate = -67817
- case certificateExpired = -67818
- case certificateNotValidYet = -67819
- case certificateRevoked = -67820
- case certificateSuspended = -67821
- case insufficientCredentials = -67822
- case invalidAction = -67823
- case invalidAuthority = -67824
- case verifyActionFailed = -67825
- case invalidCertAuthority = -67826
- case invaldCRLAuthority = -67827
- case invalidCRLEncoding = -67828
- case invalidCRLType = -67829
- case invalidCRL = -67830
- case invalidFormType = -67831
- case invalidID = -67832
- case invalidIdentifier = -67833
- case invalidIndex = -67834
- case invalidPolicyIdentifiers = -67835
- case invalidTimeString = -67836
- case invalidReason = -67837
- case invalidRequestInputs = -67838
- case invalidResponseVector = -67839
- case invalidStopOnPolicy = -67840
- case invalidTuple = -67841
- case multipleValuesUnsupported = -67842
- case notTrusted = -67843
- case noDefaultAuthority = -67844
- case rejectedForm = -67845
- case requestLost = -67846
- case requestRejected = -67847
- case unsupportedAddressType = -67848
- case unsupportedService = -67849
- case invalidTupleGroup = -67850
- case invalidBaseACLs = -67851
- case invalidTupleCredendtials = -67852
- case invalidEncoding = -67853
- case invalidValidityPeriod = -67854
- case invalidRequestor = -67855
- case requestDescriptor = -67856
- case invalidBundleInfo = -67857
- case invalidCRLIndex = -67858
- case noFieldValues = -67859
- case unsupportedFieldFormat = -67860
- case unsupportedIndexInfo = -67861
- case unsupportedLocality = -67862
- case unsupportedNumAttributes = -67863
- case unsupportedNumIndexes = -67864
- case unsupportedNumRecordTypes = -67865
- case fieldSpecifiedMultiple = -67866
- case incompatibleFieldFormat = -67867
- case invalidParsingModule = -67868
- case databaseLocked = -67869
- case datastoreIsOpen = -67870
- case missingValue = -67871
- case unsupportedQueryLimits = -67872
- case unsupportedNumSelectionPreds = -67873
- case unsupportedOperator = -67874
- case invalidDBLocation = -67875
- case invalidAccessRequest = -67876
- case invalidIndexInfo = -67877
- case invalidNewOwner = -67878
- case invalidModifyMode = -67879
- case missingRequiredExtension = -67880
- case extendedKeyUsageNotCritical = -67881
- case timestampMissing = -67882
- case timestampInvalid = -67883
- case timestampNotTrusted = -67884
- case timestampServiceNotAvailable = -67885
- case timestampBadAlg = -67886
- case timestampBadRequest = -67887
- case timestampBadDataFormat = -67888
- case timestampTimeNotAvailable = -67889
- case timestampUnacceptedPolicy = -67890
- case timestampUnacceptedExtension = -67891
- case timestampAddInfoNotAvailable = -67892
- case timestampSystemFailure = -67893
- case signingTimeMissing = -67894
- case timestampRejection = -67895
- case timestampWaiting = -67896
- case timestampRevocationWarning = -67897
- case timestampRevocationNotification = -67898
- case unexpectedError = -99999
+ case invalidAttributeWrappedKeyFormat = -67804
+ case missingAttributeWrappedKeyFormat = -67805
+ case stagedOperationInProgress = -67806
+ case stagedOperationNotStarted = -67807
+ case verifyFailed = -67808
+ case querySizeUnknown = -67809
+ case blockSizeMismatch = -67810
+ case publicKeyInconsistent = -67811
+ case deviceVerifyFailed = -67812
+ case invalidLoginName = -67813
+ case alreadyLoggedIn = -67814
+ case invalidDigestAlgorithm = -67815
+ case invalidCRLGroup = -67816
+ case certificateCannotOperate = -67817
+ case certificateExpired = -67818
+ case certificateNotValidYet = -67819
+ case certificateRevoked = -67820
+ case certificateSuspended = -67821
+ case insufficientCredentials = -67822
+ case invalidAction = -67823
+ case invalidAuthority = -67824
+ case verifyActionFailed = -67825
+ case invalidCertAuthority = -67826
+ case invaldCRLAuthority = -67827
+ case invalidCRLEncoding = -67828
+ case invalidCRLType = -67829
+ case invalidCRL = -67830
+ case invalidFormType = -67831
+ case invalidID = -67832
+ case invalidIdentifier = -67833
+ case invalidIndex = -67834
+ case invalidPolicyIdentifiers = -67835
+ case invalidTimeString = -67836
+ case invalidReason = -67837
+ case invalidRequestInputs = -67838
+ case invalidResponseVector = -67839
+ case invalidStopOnPolicy = -67840
+ case invalidTuple = -67841
+ case multipleValuesUnsupported = -67842
+ case notTrusted = -67843
+ case noDefaultAuthority = -67844
+ case rejectedForm = -67845
+ case requestLost = -67846
+ case requestRejected = -67847
+ case unsupportedAddressType = -67848
+ case unsupportedService = -67849
+ case invalidTupleGroup = -67850
+ case invalidBaseACLs = -67851
+ case invalidTupleCredendtials = -67852
+ case invalidEncoding = -67853
+ case invalidValidityPeriod = -67854
+ case invalidRequestor = -67855
+ case requestDescriptor = -67856
+ case invalidBundleInfo = -67857
+ case invalidCRLIndex = -67858
+ case noFieldValues = -67859
+ case unsupportedFieldFormat = -67860
+ case unsupportedIndexInfo = -67861
+ case unsupportedLocality = -67862
+ case unsupportedNumAttributes = -67863
+ case unsupportedNumIndexes = -67864
+ case unsupportedNumRecordTypes = -67865
+ case fieldSpecifiedMultiple = -67866
+ case incompatibleFieldFormat = -67867
+ case invalidParsingModule = -67868
+ case databaseLocked = -67869
+ case datastoreIsOpen = -67870
+ case missingValue = -67871
+ case unsupportedQueryLimits = -67872
+ case unsupportedNumSelectionPreds = -67873
+ case unsupportedOperator = -67874
+ case invalidDBLocation = -67875
+ case invalidAccessRequest = -67876
+ case invalidIndexInfo = -67877
+ case invalidNewOwner = -67878
+ case invalidModifyMode = -67879
+ case missingRequiredExtension = -67880
+ case extendedKeyUsageNotCritical = -67881
+ case timestampMissing = -67882
+ case timestampInvalid = -67883
+ case timestampNotTrusted = -67884
+ case timestampServiceNotAvailable = -67885
+ case timestampBadAlg = -67886
+ case timestampBadRequest = -67887
+ case timestampBadDataFormat = -67888
+ case timestampTimeNotAvailable = -67889
+ case timestampUnacceptedPolicy = -67890
+ case timestampUnacceptedExtension = -67891
+ case timestampAddInfoNotAvailable = -67892
+ case timestampSystemFailure = -67893
+ case signingTimeMissing = -67894
+ case timestampRejection = -67895
+ case timestampWaiting = -67896
+ case timestampRevocationWarning = -67897
+ case timestampRevocationNotification = -67898
+ case unexpectedError = -99999
}
extension Status: RawRepresentable, CustomStringConvertible {
@@ -2908,7 +2936,7 @@ extension Status: CustomNSError {
return Int(rawValue)
}
- public var errorUserInfo: [String : Any] {
+ public var errorUserInfo: [String: Any] {
return [NSLocalizedDescriptionKey: description]
}
}
diff --git a/SCP/MasterViewController.swift b/SCP/MasterViewController.swift
index 3b6722b..a9d4f2f 100644
--- a/SCP/MasterViewController.swift
+++ b/SCP/MasterViewController.swift
@@ -10,7 +10,6 @@ import UIKit
class MasterViewController: UITableViewController {
- var detailViewController: DetailViewController? = nil
var keys = [String]()
var keychain:Keychain? = nil;
@@ -21,17 +20,12 @@ class MasterViewController: UITableViewController {
let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
navigationItem.rightBarButtonItem = addButton
- if let split = splitViewController {
- let controllers = split.viewControllers
- detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
- }
keychain = Keychain()
keys = (keychain?.allKeys())!;
}
override func viewWillAppear(_ animated: Bool) {
- clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
super.viewWillAppear(animated)
if((keychain) != nil) {
keys = (keychain?.allKeys())!;
@@ -59,17 +53,23 @@ class MasterViewController: UITableViewController {
let Key = keys[indexPath.row]
let Value = try keychain?.get(Key);
controller.detailItem = Value!
+ controller.detailItemUUID = Key
} catch _ {
controller.detailItem = "Key Doesn't Exist"
}
- controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true
+
+ self.tableView.deselectRow(at: indexPath, animated: false)
}
}
}
// MARK: - Table View
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ self.performSegue(withIdentifier: "showDetail", sender: nil)
+ }
+
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
diff --git a/SCP/SSHServerTableViewController.swift b/SCP/SSHServerTableViewController.swift
index 0e4b64a..964eb85 100644
--- a/SCP/SSHServerTableViewController.swift
+++ b/SCP/SSHServerTableViewController.swift
@@ -24,6 +24,7 @@ class SSHServerTableViewController: UIViewController, UITableViewDelegate, UITab
var sideListener: ((_ path:String) -> ())?
var executionListener: (()->())?
var sshQueue:DispatchQueue?
+ var serverUUID:String!
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
@@ -39,10 +40,17 @@ class SSHServerTableViewController: UIViewController, UITableViewDelegate, UITab
}
self.title = SSHServer?.name
- self.tableView?.dataSource = self;
- self.tableView?.delegate = self;
- self.tableView?.register(UITableViewCell.self, forCellReuseIdentifier: isLeft ? "LeftTableCell" : "RightTableCell")
+ DispatchQueue.main.async {
+ self.tableView?.dataSource = self;
+ self.tableView?.delegate = self;
+ self.tableView?.register(UITableViewCell.self, forCellReuseIdentifier: self.isLeft ? "LeftTableCell" : "RightTableCell")
+ }
+ if(isLeft) {
+ pwd = (UserDefaults.standard.object(forKey: self.serverUUID + "_last_path_left") as? String) ?? ""
+ } else {
+ pwd = (UserDefaults.standard.object(forKey: self.serverUUID + "_last_path_right") as? String) ?? ""
+ }
SSHSession = NMSSHSession.connect(toHost: SSHServer?.host, port: (SSHServer?.port)!, withUsername: SSHServer?.user)
if (SSHSession?.isConnected)! {
@@ -77,7 +85,9 @@ class SSHServerTableViewController: UIViewController, UITableViewDelegate, UITab
let dirs = try SSHSession?.channel.execute("cd \"" + pwd + "\" && ls -d1 */")
parseListing(all: list!, dirs: dirs!);
- tableView?.reloadData()
+ DispatchQueue.main.async {
+ self.tableView?.reloadData()
+ }
} catch let error {
print("error: \(error)")
}
@@ -110,7 +120,11 @@ class SSHServerTableViewController: UIViewController, UITableViewDelegate, UITab
do {
pwd = (try SSHSession?.channel.execute("cd \"" + pwd + "\" && cd \"" + path + "\" && pwd"))!
pwd = pwd.trimmingCharacters(in: .whitespacesAndNewlines)
-
+ if(isLeft) {
+ UserDefaults.standard.set(pwd, forKey: self.serverUUID + "_last_path_left")
+ } else {
+ UserDefaults.standard.set(pwd, forKey: self.serverUUID + "_last_path_right")
+ }
sideListener!(pwd)
objects = []
@@ -140,11 +154,12 @@ class SSHServerTableViewController: UIViewController, UITableViewDelegate, UITab
cell.textLabel?.text = item["name"]
if(item["type"] == "folder") {
cell.imageView?.image = UIImage.init(icon: .fontAwesome(.folder), size: CGSize(width: 35, height: 35))
- let holdForAction = UILongPressGestureRecognizer(target: self, action: #selector(SSHServerTableViewController.longPressFolder));
- cell.addGestureRecognizer(holdForAction)
} else if(item["type"] == "file") {
cell.imageView?.image = UIImage.init(icon: .fontAwesome(.file), size: CGSize(width: 35, height: 35))
}
+ let holdForAction = UILongPressGestureRecognizer(target: self, action: #selector(SSHServerTableViewController.longPressFolder));
+ cell.addGestureRecognizer(holdForAction)
+
return cell
}
@@ -156,6 +171,8 @@ class SSHServerTableViewController: UIViewController, UITableViewDelegate, UITab
} else if(item["type"] == "file") {
handleAction(item, indexPath: indexPath)
}
+
+ tableView.deselectRow(at: indexPath, animated: true)
}
@objc public func longPressFolder(sender: UILongPressGestureRecognizer) {
@@ -228,6 +245,10 @@ class SSHServerTableViewController: UIViewController, UITableViewDelegate, UITab
self.handleView(path: self.pwd + "/" + item["name"]!)
}))
+ alert.addAction(UIAlertAction(title: "Stats", style: .default, handler: { (action) in
+ self.handleStats(path: self.pwd + "/" + item["name"]!)
+ }))
+
alert.addAction(UIAlertAction(title: "Move", style: .destructive, handler: { (action) in
self.handleMove(from: self.pwd + "/" + item["name"]!, to: self.sidePWD)
}))
@@ -288,7 +309,21 @@ class SSHServerTableViewController: UIViewController, UITableViewDelegate, UITab
let viewAlert = UIAlertController(title: "Viewing " + path, message: cat, preferredStyle: .alert)
viewAlert.addAction(UIAlertAction(title: "Done", style: .default))
-
+
+ self.presenter!(viewAlert, true, nil)
+ } catch let error {
+ print("error: \(error)")
+ }
+ }
+
+
+ private func handleStats(path: String) {
+ do {
+ let cat = try SSHSession?.channel.execute("ls -alh \"" + path + "\"")
+
+ let viewAlert = UIAlertController(title: "Stats " + path, message: cat, preferredStyle: .alert)
+ viewAlert.addAction(UIAlertAction(title: "Done", style: .default))
+
self.presenter!(viewAlert, true, nil)
} catch let error {
print("error: \(error)")