Skip to content

Removed password prompt #70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 18 additions & 44 deletions Sources/Shout/SSHAuthMethod.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,56 +13,54 @@ public protocol SSHAuthMethod {

/// Password-based authentication method
public struct SSHPassword: SSHAuthMethod {

let password: String

/// Creates a new password-based authentication using the given password
///
/// - Parameter password: the password to authenticate with
public init(_ password: String) {
self.password = password
}

public func authenticate(ssh: SSH, username: String) throws {
try ssh.session.authenticate(username: username, password: password)
}

}

/// Agent-based authentication method
public struct SSHAgent: SSHAuthMethod {

/// Creates a new agent-based authentication
public init() {}

public func authenticate(ssh: SSH, username: String) throws {
let agent = try ssh.session.openAgent()
try agent.connect()
try agent.listIdentities()

var last: Agent.PublicKey? = nil
var success: Bool = false

while let identity = try agent.getIdentity(last: last) {
if agent.authenticate(username: username, key: identity) {
success = true
break
}

last = identity
}

guard success else {
throw SSHError.genericError("failed to authenticate using the agent")
}
}

}

/// Key-based authentication method
public struct SSHKey: SSHAuthMethod {

public let privateKey: String
public let publicKey: String
public let passphrase: String?

/// Creates a new key-based authentication
///
/// - Parameters:
Expand All @@ -71,46 +69,22 @@ public struct SSHKey: SSHAuthMethod {
/// - passphrase: the passphrase encrypting the key; defaults to nil
public init(privateKey: String, publicKey: String? = nil, passphrase: String? = nil) {
self.privateKey = NSString(string: privateKey).expandingTildeInPath
if let publicKey = publicKey {

if let publicKey {
self.publicKey = NSString(string: publicKey).expandingTildeInPath
} else {
self.publicKey = self.privateKey + ".pub"
}

self.passphrase = passphrase
}

public func authenticate(ssh: SSH, username: String) throws {
// If programatically given a passphrase, use it
if let passphrase = passphrase {
try ssh.session.authenticate(username: username,
privateKey: privateKey,
publicKey: publicKey,
passphrase: passphrase)
return
}

// Otherwise, try logging in without any passphrase
do {
try ssh.session.authenticate(username: username,
privateKey: privateKey,
publicKey: publicKey,
passphrase: nil)
return
} catch {}

// If that doesn't work, try using the Agent in case the passphrase has been saved there
do {
try SSHAgent().authenticate(ssh: ssh, username: username)
return
} catch {}

// Finally, as a fallback, ask for the passphrase
let enteredPassphrase = String(cString: getpass("Enter passphrase for \(privateKey) (empty for no passphrase):"))
try ssh.session.authenticate(username: username,
privateKey: privateKey,
publicKey: publicKey,
passphrase: enteredPassphrase)
try ssh.session.authenticate(
username: username,
privateKey: privateKey,
publicKey: publicKey,
passphrase: passphrase
)
}

}