Explicit check and error for private keys that require a passphrase, as they're currently unsupported.

This commit is contained in:
Ian Wolfcat Atha 2011-08-17 23:44:06 -07:00
parent 28a5c15ca0
commit ce35fb11b7
3 changed files with 21 additions and 0 deletions

View File

@ -53,5 +53,8 @@ public class CredentialUtils {
.startsWith(Pems.PRIVATE_PKCS8_MARKER)); .startsWith(Pems.PRIVATE_PKCS8_MARKER));
} }
public static boolean isPrivateKeyEncrypted(byte[] privateKey) {
return new String(privateKey).contains("Proc-Type: 4,ENCRYPTED");
}
} }

View File

@ -47,6 +47,7 @@ import org.jclouds.net.IPSocket;
import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.AuthorizationException;
import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshException; import org.jclouds.ssh.SshException;
import org.jclouds.util.CredentialUtils;
import org.jclouds.util.Strings2; import org.jclouds.util.Strings2;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
@ -167,6 +168,9 @@ public class JschSshClient implements SshClient {
session.setPassword(password); session.setPassword(password);
} else { } else {
// jsch wipes out your private key // jsch wipes out your private key
if (CredentialUtils.isPrivateKeyEncrypted(privateKey)) {
throw new IllegalArgumentException("JschSshClientModule does not support private keys that require a passphrase");
}
jsch.addIdentity(username, Arrays.copyOf(privateKey, privateKey.length), null, emptyPassPhrase); jsch.addIdentity(username, Arrays.copyOf(privateKey, privateKey.length), null, emptyPassPhrase);
} }
java.util.Properties config = new java.util.Properties(); java.util.Properties config = new java.util.Properties();

View File

@ -26,6 +26,7 @@ import org.jclouds.domain.Credentials;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.AuthorizationException;
import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshException;
import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -105,4 +106,17 @@ public class JschSshClientTest {
new JSchException("Session.connect: java.net.SocketException: Connection reset")).apply("java.net.Socket"); new JSchException("Session.connect: java.net.SocketException: Connection reset")).apply("java.net.Socket");
assert !ssh.causalChainHasMessageContaining(new NullPointerException()).apply(" End of IO Stream Read"); assert !ssh.causalChainHasMessageContaining(new NullPointerException()).apply(" End of IO Stream Read");
} }
public void testPrivateKeyWithPassphrase() throws UnknownHostException {
Injector i = Guice.createInjector(module());
SshClient.Factory factory = i.getInstance(SshClient.Factory.class);
try {
JschSshClient ssh = JschSshClient.class.cast(factory.create(new IPSocket("localhost", 22), new Credentials(
"username", "-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: AES-128-CBC,123\n\n123")));
ssh.connect();
assert false; // this code should never be reached.
} catch (SshException e) {
// Success!
}
}
} }