You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@whirr.apache.org by to...@apache.org on 2011/01/04 01:02:22 UTC
svn commit: r1054836 - in /incubator/whirr/trunk: ./ core/
core/src/main/java/org/apache/whirr/service/
core/src/main/java/org/apache/whirr/ssh/
core/src/test/java/org/apache/whirr/service/
core/src/test/java/org/apache/whirr/ssh/ src/site/confluence/
Author: tomwhite
Date: Tue Jan 4 00:02:22 2011
New Revision: 1054836
URL: http://svn.apache.org/viewvc?rev=1054836&view=rev
Log:
WHIRR-161. Check that both SSH keys belong to the same pair. Contributed by Andrei Savu.
Modified:
incubator/whirr/trunk/CHANGES.txt
incubator/whirr/trunk/core/pom.xml
incubator/whirr/trunk/core/src/main/java/org/apache/whirr/service/ClusterSpec.java
incubator/whirr/trunk/core/src/main/java/org/apache/whirr/ssh/KeyPair.java
incubator/whirr/trunk/core/src/test/java/org/apache/whirr/service/ClusterSpecTest.java
incubator/whirr/trunk/core/src/test/java/org/apache/whirr/ssh/KeyPairTest.java
incubator/whirr/trunk/pom.xml
incubator/whirr/trunk/src/site/confluence/configuration-guide.confluence
incubator/whirr/trunk/src/site/confluence/quick-start-guide.confluence
Modified: incubator/whirr/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/CHANGES.txt?rev=1054836&r1=1054835&r2=1054836&view=diff
==============================================================================
--- incubator/whirr/trunk/CHANGES.txt (original)
+++ incubator/whirr/trunk/CHANGES.txt Tue Jan 4 00:02:22 2011
@@ -52,6 +52,9 @@ Trunk (unreleased changes)
WHIRR-181. Add descriptions for CLI command options.
(Andrei Savu via tomwhite)
+ WHIRR-161. Check that both SSH keys belong to the same pair.
+ (Andrei Savu via tomwhite)
+
BUG FIXES
WHIRR-128. Fix DNS resolution for clients running within EC2.
Modified: incubator/whirr/trunk/core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/core/pom.xml?rev=1054836&r1=1054835&r2=1054836&view=diff
==============================================================================
--- incubator/whirr/trunk/core/pom.xml (original)
+++ incubator/whirr/trunk/core/pom.xml Tue Jan 4 00:02:22 2011
@@ -30,6 +30,10 @@
<name>Apache Whirr Core</name>
<dependencies>
<dependency>
+ <groupId>ca.juliusdavies</groupId>
+ <artifactId>not-yet-commons-ssl</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-allcompute</artifactId>
</dependency>
@@ -78,6 +82,10 @@
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
Modified: incubator/whirr/trunk/core/src/main/java/org/apache/whirr/service/ClusterSpec.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/core/src/main/java/org/apache/whirr/service/ClusterSpec.java?rev=1054836&r1=1054835&r2=1054836&view=diff
==============================================================================
--- incubator/whirr/trunk/core/src/main/java/org/apache/whirr/service/ClusterSpec.java (original)
+++ incubator/whirr/trunk/core/src/main/java/org/apache/whirr/service/ClusterSpec.java Tue Jan 4 00:02:22 2011
@@ -23,6 +23,7 @@ import static com.google.common.base.Pre
import static org.jclouds.io.Payloads.newFilePayload;
import static org.jclouds.io.Payloads.newStringPayload;
import static org.jclouds.util.Utils.toStringAndClose;
+import static org.apache.whirr.ssh.KeyPair.sameKeyPair;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
@@ -253,6 +254,10 @@ public class ClusterSpec {
if (pair.isEncrypted()) {
throw new ConfigurationException("Key pair is encrypted");
}
+ if (!sameKeyPair(new File(privateKeyPath), new File(publicKeyPath))) {
+ throw new ConfigurationException("Both keys should belong " +
+ "to the same key pair");
+ }
setPrivateKey(new File(privateKeyPath));
setPublicKey(new File(publicKeyPath));
Modified: incubator/whirr/trunk/core/src/main/java/org/apache/whirr/ssh/KeyPair.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/core/src/main/java/org/apache/whirr/ssh/KeyPair.java?rev=1054836&r1=1054835&r2=1054836&view=diff
==============================================================================
--- incubator/whirr/trunk/core/src/main/java/org/apache/whirr/ssh/KeyPair.java (original)
+++ incubator/whirr/trunk/core/src/main/java/org/apache/whirr/ssh/KeyPair.java Tue Jan 4 00:02:22 2011
@@ -21,18 +21,34 @@ package org.apache.whirr.ssh;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.GeneralSecurityException;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.ssl.PKCS8Key;
+import org.apache.commons.codec.binary.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* A convenience class for generating an RSA key pair.
*/
public class KeyPair {
+ private static final Logger LOG =
+ LoggerFactory.getLogger(KeyPair.class);
+
public static Map<String, String> generate() throws JSchException {
return generate(null);
}
@@ -82,4 +98,47 @@ public class KeyPair {
return ImmutableMap.<String, File> of("public", publicKeyFile,
"private", privateKeyFile);
}
+
+ public static boolean sameKeyPair(File privateKeyFile, File publicKeyFile) throws IOException {
+ try {
+ PKCS8Key decodedKey = new PKCS8Key(
+ new FileInputStream(privateKeyFile), null);
+ PrivateKey privateKey = decodedKey.getPrivateKey();
+ PublicKey publicKey = decodedKey.getPublicKey();
+
+ byte[] actual = encodePublicKey((RSAPublicKey) publicKey);
+ byte[] expected = IOUtils.toByteArray(new FileReader(publicKeyFile));
+
+ for(int i=0; i<actual.length; i += 1) {
+ if (actual[i] != expected[i]) {
+ return false;
+ }
+ }
+ return true;
+ } catch (GeneralSecurityException e) {
+ LOG.error("Key pair validation failed", e);
+ return false;
+ }
+ }
+
+ private static byte[] encodePublicKey(RSAPublicKey key) throws IOException {
+ ByteArrayOutputStream keyBlob = new ByteArrayOutputStream();
+ write("ssh-rsa".getBytes(), keyBlob);
+ write(key.getPublicExponent().toByteArray(), keyBlob);
+ write(key.getModulus().toByteArray(), keyBlob);
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ out.write("ssh-rsa ".getBytes());
+ out.write(Base64.encodeBase64(keyBlob.toByteArray()));
+
+ return out.toByteArray();
+ }
+
+ private static void write(byte[] str, OutputStream os)
+ throws IOException {
+ for (int shift = 24; shift >= 0; shift -= 8)
+ os.write((str.length >>> shift) & 0xFF);
+ os.write(str);
+ }
+
}
Modified: incubator/whirr/trunk/core/src/test/java/org/apache/whirr/service/ClusterSpecTest.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/core/src/test/java/org/apache/whirr/service/ClusterSpecTest.java?rev=1054836&r1=1054835&r2=1054836&view=diff
==============================================================================
--- incubator/whirr/trunk/core/src/test/java/org/apache/whirr/service/ClusterSpecTest.java (original)
+++ incubator/whirr/trunk/core/src/test/java/org/apache/whirr/service/ClusterSpecTest.java Tue Jan 4 00:02:22 2011
@@ -179,4 +179,15 @@ public class ClusterSpecTest {
ClusterSpec spec = new ClusterSpec(conf);
}
+ @Test(expected = ConfigurationException.class)
+ public void testNotSameKeyPair() throws JSchException, IOException, ConfigurationException {
+ Map<String, File> first = KeyPair.generateTemporaryFiles();
+ Map<String, File> second = KeyPair.generateTemporaryFiles();
+
+ Configuration conf = new PropertiesConfiguration();
+ conf.setProperty("whirr.private-key-file", first.get("private").getAbsolutePath());
+ conf.setProperty("whirr.public-key-file", second.get("public").getAbsolutePath());
+
+ ClusterSpec spec = new ClusterSpec(conf);
+ }
}
Modified: incubator/whirr/trunk/core/src/test/java/org/apache/whirr/ssh/KeyPairTest.java
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/core/src/test/java/org/apache/whirr/ssh/KeyPairTest.java?rev=1054836&r1=1054835&r2=1054836&view=diff
==============================================================================
--- incubator/whirr/trunk/core/src/test/java/org/apache/whirr/ssh/KeyPairTest.java (original)
+++ incubator/whirr/trunk/core/src/test/java/org/apache/whirr/ssh/KeyPairTest.java Tue Jan 4 00:02:22 2011
@@ -18,9 +18,16 @@
package org.apache.whirr.ssh;
+import static org.apache.whirr.ssh.KeyPair.sameKeyPair;
+import static org.apache.whirr.ssh.KeyPair.generate;
+import static org.apache.whirr.ssh.KeyPair.generateTemporaryFiles;
+
import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
+import java.io.File;
+import java.io.IOException;
import java.util.Map;
import org.junit.Test;
@@ -30,8 +37,20 @@ import com.jcraft.jsch.JSchException;
public class KeyPairTest {
@Test
+ public void testNotFromSamePair() throws JSchException, IOException {
+ Map<String, File> keys = generateTemporaryFiles();
+ assertThat(sameKeyPair(keys.get("private"), keys.get("public")), is(true));
+
+ Map<String, File> other = generateTemporaryFiles();
+ assertThat(sameKeyPair(other.get("private"), other.get("public")), is(true));
+
+ assertThat(sameKeyPair(keys.get("private"), other.get("public")), is(false));
+ assertThat(sameKeyPair(other.get("private"), keys.get("public")), is(false));
+ }
+
+ @Test
public void testGenerate() throws JSchException {
- Map<String, String> pair = KeyPair.generate();
+ Map<String, String> pair = generate();
assertThat(pair.get("public"),
containsString("ssh-rsa "));
assertThat(pair.get("private"),
Modified: incubator/whirr/trunk/pom.xml
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/pom.xml?rev=1054836&r1=1054835&r2=1054836&view=diff
==============================================================================
--- incubator/whirr/trunk/pom.xml (original)
+++ incubator/whirr/trunk/pom.xml Tue Jan 4 00:02:22 2011
@@ -53,6 +53,11 @@
<dependencyManagement>
<dependencies>
<dependency>
+ <groupId>ca.juliusdavies</groupId>
+ <artifactId>not-yet-commons-ssl</artifactId>
+ <version>0.3.11</version>
+ </dependency>
+ <dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-allcompute</artifactId>
<version>${jclouds.version}</version>
@@ -116,6 +121,11 @@
<version>1.4</version>
</dependency>
<dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.0</version>
Modified: incubator/whirr/trunk/src/site/confluence/configuration-guide.confluence
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/src/site/confluence/configuration-guide.confluence?rev=1054836&r1=1054835&r2=1054836&view=diff
==============================================================================
--- incubator/whirr/trunk/src/site/confluence/configuration-guide.confluence (original)
+++ incubator/whirr/trunk/src/site/confluence/configuration-guide.confluence Tue Jan 4 00:02:22 2011
@@ -10,8 +10,8 @@ Whirr is configured using a properties f
| {{whirr.provider}} | {{\--provider}} | {{ec2}} | The name of the cloud provider. See the [table below|#cloud-provider-config] for possible provider names.|
| {{whirr.identity}} | {{\--identity}} | none | The cloud identity. See the [table below|#cloud-provider-config] for how this maps to the credentials for your provider. |
| {{whirr.credential}} | {{\--credential}} | none | The cloud credential. See the [table below|#cloud-provider-config] for how this maps to the credentials for your provider. |
-| {{whirr.private-key-file}} | {{\--private-key-file}} | _\~/.ssh/id\_rsa_ | The filename of the private key used to connect to instances. Note: the public/private key must be set together, and must be passwordless. |
-| {{whirr.public-key-file}} | {{\--public-key-file}} | _\~/.ssh/id\_rsa_.pub | The filename of the public key used to connect to instances. Note: the public/private key must be set together, and must be passwordless.|
+| {{whirr.private-key-file}} | {{\--private-key-file}} | _\~/.ssh/id\_rsa_ | The filename of the private RSA key used to connect to instances. Note: the public/private key must be set together, and must be passwordless. |
+| {{whirr.public-key-file}} | {{\--public-key-file}} | _\~/.ssh/id\_rsa_.pub | The filename of the public RSA key used to connect to instances. Note: the public/private key must be set together, and must be passwordless.|
| {{whirr.image-id}} | {{\--image-id}} | none | The ID of the image to use for instances. If not specified then a vanilla Linux image is chosen. |
| {{whirr.hardware-id}} | {{\--hardware-id}} | none | The type of hardware to use for the instance. This must be compatible with the image ID. |
| {{whirr.location-id}} | {{\--location-id}} | none | The location to launch instances in. If not specified then an arbitrary location will be chosen. |
Modified: incubator/whirr/trunk/src/site/confluence/quick-start-guide.confluence
URL: http://svn.apache.org/viewvc/incubator/whirr/trunk/src/site/confluence/quick-start-guide.confluence?rev=1054836&r1=1054835&r2=1054836&view=diff
==============================================================================
--- incubator/whirr/trunk/src/site/confluence/quick-start-guide.confluence (original)
+++ incubator/whirr/trunk/src/site/confluence/quick-start-guide.confluence Tue Jan 4 00:02:22 2011
@@ -48,6 +48,8 @@ Note that you do not need to choose a pa
choose a particular image if you want to; see the [Configuration Guide|configuration-guide]
for details.
+Also note that you should use only RSA SSH keys, DSA keys are not accepted yet.
+
Run the following command to launch a cluster:
{code}