@@ -18,8 +18,10 @@ package com.decodified.scalassh
18
18
19
19
import java .util .concurrent .TimeUnit
20
20
import net .schmizz .sshj .SSHClient
21
- import java .io .File
22
21
import org .slf4j .LoggerFactory
22
+ import net .schmizz .sshj .userauth .keyprovider .KeyProvider
23
+ import io .Source
24
+ import java .io .{InputStream , FileNotFoundException , FileInputStream , File }
23
25
24
26
class SshClient (val config : HostConfig ) {
25
27
lazy val log = LoggerFactory .getLogger(getClass)
@@ -63,9 +65,26 @@ class SshClient(val config: HostConfig) {
63
65
}
64
66
65
67
protected def authenticate (client : SSHClient ) = {
66
- def existing (filenames : List [String ]) = filenames.filter(new File (_).exists) match {
67
- case Nil => sys.error(" None of the configured keyfiles exists: " + filenames.mkString(" , " ))
68
- case files => files
68
+ def keyProviders (locations : List [String ], passProducer : PasswordProducer ): List [KeyProvider ] = {
69
+ def inputStream (location : String ): Option [InputStream ] = {
70
+ if (location.startsWith(" classpath:" )) {
71
+ val resource = location.substring(" classpath:" .length)
72
+ Option (getClass.getClassLoader.getResourceAsStream(resource))
73
+ .orElse(throw new RuntimeException (" Classpath resource '" + resource + " ' containing private key could not be found" ))
74
+ } else {
75
+ try Some (new FileInputStream (location))
76
+ catch { case _ : FileNotFoundException => None }
77
+ }
78
+ }
79
+ locations.flatMap { location =>
80
+ inputStream(location).map { stream =>
81
+ val privateKey = Source .fromInputStream(stream).getLines().mkString(" \n " )
82
+ client.loadKeys(privateKey, null , passProducer)
83
+ }
84
+ } match {
85
+ case Nil => sys.error(" None of the configured keyfiles exists: " + locations.mkString(" , " ))
86
+ case x => x
87
+ }
69
88
}
70
89
71
90
require(client.isConnected && ! client.isAuthenticated)
@@ -76,14 +95,9 @@ class SshClient(val config: HostConfig) {
76
95
client.authPassword(user, passProducer)
77
96
client
78
97
}
79
- case PublicKeyLogin (user, None , keyfileLocations) =>
98
+ case PublicKeyLogin (user, passProducer , keyfileLocations) =>
80
99
protect(" Could not authenticate (with keyfile) to" ) {
81
- client.authPublickey(user, existing(keyfileLocations): _* )
82
- client
83
- }
84
- case PublicKeyLogin (user, Some (passProducer), keyfileLocations) =>
85
- protect(" Could not authenticate (with encrypted keyfile) to" ) {
86
- client.authPublickey(user, existing(keyfileLocations).map(client.loadKeys(_, passProducer)): _* )
100
+ client.authPublickey(user, keyProviders(keyfileLocations, passProducer.getOrElse(null )): _* )
87
101
client
88
102
}
89
103
}
0 commit comments