You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by hu...@apache.org on 2013/06/17 19:05:23 UTC

git commit: updated refs/heads/master to b0ea02e

Updated Branches:
  refs/heads/master 76d3c27bf -> b0ea02e65


Allow DSA public keys.

DSA can't be used for encryption with the bouncycastle library, so make
sure this situation is properly handled.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/b0ea02e6
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/b0ea02e6
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/b0ea02e6

Branch: refs/heads/master
Commit: b0ea02e65a01cf62004de0851284da7a8868d406
Parents: 76d3c27
Author: Hugo Trippaers <tr...@gmail.com>
Authored: Sun Jun 16 14:37:48 2013 -0700
Committer: Hugo Trippaers <tr...@gmail.com>
Committed: Mon Jun 17 10:04:59 2013 -0700

----------------------------------------------------------------------
 server/src/com/cloud/vm/UserVmManagerImpl.java  | 63 +++++++-----------
 .../src/com/cloud/utils/ssh/SSHKeysHelper.java  |  2 +-
 .../com/cloud/utils/crypto/RSAHelperTest.java   | 50 ++++++++++++++
 .../com/cloud/utils/ssh/SSHKeysHelperTest.java  | 69 ++++++++++++++++++++
 4 files changed, 143 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b0ea02e6/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 1c8ab75..44a7d06 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -509,18 +509,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
             // update the password in vm_details table too
             // Check if an SSH key pair was selected for the instance and if so
             // use it to encrypt & save the vm password
-            String sshPublicKey = userVm.getDetail("SSH.PublicKey");
-            if (sshPublicKey != null && !sshPublicKey.equals("")
-                    && password != null && !password.equals("saved_password")) {
-                String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(
-                        sshPublicKey, password);
-                if (encryptedPasswd == null) {
-                    throw new CloudRuntimeException("Error encrypting password");
-                }
-
-                userVm.setDetail("Encrypted.Password", encryptedPasswd);
-                _vmDao.saveDetails(userVm);
-            }
+            encryptAndStorePassword(userVm, password);
         } else {
             throw new CloudRuntimeException(
                     "Failed to reset password for the virtual machine ");
@@ -643,13 +632,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
             if (template != null && template.getEnablePassword()) {
                 userVm.setPassword(password);
                 //update the encrypted password in vm_details table too
-                if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password")) {
-                    String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password);
-                    if (encryptedPasswd == null) {
-                        throw new CloudRuntimeException("Error encrypting password");
-                    }
-                    userVm.setDetail("Encrypted.Password", encryptedPasswd);
-                }
+                encryptAndStorePassword(userVm, password);
             }
             _vmDao.saveDetails(userVm);
         } else {
@@ -3304,18 +3287,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
 
             // Check if an SSH key pair was selected for the instance and if so
             // use it to encrypt & save the vm password
-            String sshPublicKey = vm.getDetail("SSH.PublicKey");
-            if (sshPublicKey != null && !sshPublicKey.equals("")
-                    && password != null && !password.equals("saved_password")) {
-                String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(
-                        sshPublicKey, password);
-                if (encryptedPasswd == null) {
-                    throw new CloudRuntimeException("Error encrypting password");
-                }
-
-                vm.setDetail("Encrypted.Password", encryptedPasswd);
-                _vmDao.saveDetails(vm);
-            }
+            encryptAndStorePassword(vm, password);
 
             params = new HashMap<VirtualMachineProfile.Param, Object>();
             if (additionalParams != null) {
@@ -4621,15 +4593,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
                 // update the password in vm_details table too
                 // Check if an SSH key pair was selected for the instance and if so
                 // use it to encrypt & save the vm password
-                String sshPublicKey = vm.getDetail("SSH.PublicKey");
-                if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password")) {
-                    String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password);
-                    if (encryptedPasswd == null) {
-                        throw new CloudRuntimeException("VM reset is completed but error occurred when encrypting newly created password");
-                    }
-                    vm.setDetail("Encrypted.Password", encryptedPasswd);
-                    _vmDao.saveDetails(vm);
-                }
+                encryptAndStorePassword(vm, password);
             } else {
                 throw new CloudRuntimeException("VM reset is completed but failed to reset password for the virtual machine ");
             }
@@ -4717,5 +4681,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
         if (vm.getState() == State.Running)
             collectVmDiskStatistics(vm);
     }
+    
+    private void encryptAndStorePassword(UserVmVO vm, String password) {
+        String sshPublicKey = vm.getDetail("SSH.PublicKey");
+        if (sshPublicKey != null && !sshPublicKey.equals("")
+                && password != null && !password.equals("saved_password")) {
+            if (!sshPublicKey.startsWith("ssh-rsa")) {
+                s_logger.warn("Only RSA public keys can be used to encrypt a vm password.");
+                return;
+            }
+            String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(
+                    sshPublicKey, password);
+            if (encryptedPasswd == null) {
+                throw new CloudRuntimeException("Error encrypting password");
+            }
+
+            vm.setDetail("Encrypted.Password", encryptedPasswd);
+            _vmDao.saveDetails(vm);
+        }
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b0ea02e6/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java b/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java
index 2755c54..a14e5a4 100644
--- a/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java
+++ b/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java
@@ -82,7 +82,7 @@ public class SSHKeysHelper {
 		if (!keyMaterial.contains(" ")) 
 			keyMaterial = new String(Base64.decodeBase64(keyMaterial.getBytes()));
 		
-		if (!keyMaterial.startsWith("ssh-rsa") || !keyMaterial.contains(" "))
+		if ((!keyMaterial.startsWith("ssh-rsa") && !keyMaterial.startsWith("ssh-dss")) || !keyMaterial.contains(" "))
 			return null;
 		
 		String[] key = keyMaterial.split(" ");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b0ea02e6/utils/test/com/cloud/utils/crypto/RSAHelperTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/crypto/RSAHelperTest.java b/utils/test/com/cloud/utils/crypto/RSAHelperTest.java
new file mode 100644
index 0000000..d1f496e
--- /dev/null
+++ b/utils/test/com/cloud/utils/crypto/RSAHelperTest.java
@@ -0,0 +1,50 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.crypto;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import com.cloud.utils.crypt.RSAHelper;
+
+public class RSAHelperTest {
+    @Test
+    public void testEncryptWithRSA() {
+        String rsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2D2Cs0XAEqm+ajJpumIPrMpKp0CWtIW+8ZY2/MJCW" + 
+                "hge1eY18u9I3PPnkMVJsTOaN0wQojjw4AkKgKjNZXA9wyUq56UyN/stmipu8zifWPgxQGDRkuzzZ6buk" +
+                "ef8q2Awjpo8hv5/0SRPJxQLEafESnUP+Uu/LUwk5VVC7PHzywJRUGFuzDl/uT72+6hqpL2YpC6aTl4/P" + 
+                "2eDvUQhCdL9dBmUSFX8ftT53W1jhsaQl7mPElVgSCtWz3IyRkogobMPrpJW/IPKEiojKIuvNoNv4CDR6" +
+                "ybeVjHOJMb9wi62rXo+CzUsW0Y4jPOX/OykAm5vrNOhQhw0aaBcv5XVv8BRX";
+        String encryptedString = RSAHelper.encryptWithSSHPublicKey(rsaKey, "content");
+        assertNotNull(encryptedString);
+    }
+    
+    @Test
+    public void testEncryptWithDSA() {
+        String dssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBALbaewDnzZ5AcGbZno7VW1m7Si3Q+yEANXZioVupfSwOP0q9aP2iV"+
+                "tyqq575JnUVZXMDR2Gr254F/qCJ0TKAvucN0gcd2XslX4jBcu1Z7s7YZf6d7fC58k0NE6/keokJNKhQO" +
+                "i56iirRzSA/YFrD64mzfq6rEmai0q7GjGGP0RT1AAAAFQDO5++6JonyqnoRkV9Yl1OaEOPjVwAAAIAYA" +
+                "tqtKtU/INlTIuL3wt3nyKzwPUnz3fqxP5Ger3OlRZsOahalTFt2OF5jGGmCunyBTRteOetZObr0QhUIF" +
+                "4bSDr6UiYYYbH1ES0ws/t1mDIeTh3UUHV1QYACN6c07FKyKLMtB9AthiG2FMLKCEedG3NeXItuNzsuQD" +
+                "+n/K1rzMAAAAIBi5SM4pFPiB7BvTZvARV56vrG5QNgWVazSwbwgl/EACiWYbRauHDUQA9f+Rq+ayWcsR" +
+                "os1CD+Q81y9SmlQaZVKkSPZLxXfu5bi3s4o431xjilhZdt4vKbj2pK364IjghJPNBBfmRXzlj9awKxr/" +
+                "UebZcBgNRyeky7VZSbbF2jQSQ==";
+        String encryptedString = RSAHelper.encryptWithSSHPublicKey(dssKey, "content");
+        assertNull(encryptedString);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b0ea02e6/utils/test/com/cloud/utils/ssh/SSHKeysHelperTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/ssh/SSHKeysHelperTest.java b/utils/test/com/cloud/utils/ssh/SSHKeysHelperTest.java
new file mode 100644
index 0000000..6402e3e
--- /dev/null
+++ b/utils/test/com/cloud/utils/ssh/SSHKeysHelperTest.java
@@ -0,0 +1,69 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.utils.ssh;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class SSHKeysHelperTest {
+    @Test
+    public void rsaKeyTest() {
+        String rsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2D2Cs0XAEqm+ajJpumIPrMpKp0CWtIW+8ZY2/MJCW" + 
+                "hge1eY18u9I3PPnkMVJsTOaN0wQojjw4AkKgKjNZXA9wyUq56UyN/stmipu8zifWPgxQGDRkuzzZ6buk" +
+                "ef8q2Awjpo8hv5/0SRPJxQLEafESnUP+Uu/LUwk5VVC7PHzywJRUGFuzDl/uT72+6hqpL2YpC6aTl4/P" + 
+                "2eDvUQhCdL9dBmUSFX8ftT53W1jhsaQl7mPElVgSCtWz3IyRkogobMPrpJW/IPKEiojKIuvNoNv4CDR6" +
+                "ybeVjHOJMb9wi62rXo+CzUsW0Y4jPOX/OykAm5vrNOhQhw0aaBcv5XVv8BRX test@testkey";
+        String storedRsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2D2Cs0XAEqm+ajJpumIPrMpKp0CWtIW+8ZY2/MJCW" + 
+                "hge1eY18u9I3PPnkMVJsTOaN0wQojjw4AkKgKjNZXA9wyUq56UyN/stmipu8zifWPgxQGDRkuzzZ6buk" +
+                "ef8q2Awjpo8hv5/0SRPJxQLEafESnUP+Uu/LUwk5VVC7PHzywJRUGFuzDl/uT72+6hqpL2YpC6aTl4/P" + 
+                "2eDvUQhCdL9dBmUSFX8ftT53W1jhsaQl7mPElVgSCtWz3IyRkogobMPrpJW/IPKEiojKIuvNoNv4CDR6" +
+                "ybeVjHOJMb9wi62rXo+CzUsW0Y4jPOX/OykAm5vrNOhQhw0aaBcv5XVv8BRX";
+        String parsedKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(rsaKey);
+        String fingerprint = SSHKeysHelper.getPublicKeyFingerprint(parsedKey);
+        
+        assertTrue(storedRsaKey.equals(parsedKey));
+        assertTrue("f6:96:3f:f4:78:f7:80:11:6c:f8:e3:2b:40:20:f1:14".equals(fingerprint));
+        
+    }
+
+    @Test
+    public void dsaKeyTest() {
+        String dssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBALbaewDnzZ5AcGbZno7VW1m7Si3Q+yEANXZioVupfSwOP0q9aP2iV"+
+                "tyqq575JnUVZXMDR2Gr254F/qCJ0TKAvucN0gcd2XslX4jBcu1Z7s7YZf6d7fC58k0NE6/keokJNKhQO" +
+                "i56iirRzSA/YFrD64mzfq6rEmai0q7GjGGP0RT1AAAAFQDO5++6JonyqnoRkV9Yl1OaEOPjVwAAAIAYA" +
+                "tqtKtU/INlTIuL3wt3nyKzwPUnz3fqxP5Ger3OlRZsOahalTFt2OF5jGGmCunyBTRteOetZObr0QhUIF" +
+                "4bSDr6UiYYYbH1ES0ws/t1mDIeTh3UUHV1QYACN6c07FKyKLMtB9AthiG2FMLKCEedG3NeXItuNzsuQD" +
+                "+n/K1rzMAAAAIBi5SM4pFPiB7BvTZvARV56vrG5QNgWVazSwbwgl/EACiWYbRauHDUQA9f+Rq+ayWcsR" +
+                "os1CD+Q81y9SmlQaZVKkSPZLxXfu5bi3s4o431xjilhZdt4vKbj2pK364IjghJPNBBfmRXzlj9awKxr/" +
+                "UebZcBgNRyeky7VZSbbF2jQSQ== test key";
+        String storedDssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBALbaewDnzZ5AcGbZno7VW1m7Si3Q+yEANXZioVupfSwOP0q9aP2iV"+
+                "tyqq575JnUVZXMDR2Gr254F/qCJ0TKAvucN0gcd2XslX4jBcu1Z7s7YZf6d7fC58k0NE6/keokJNKhQO" +
+                "i56iirRzSA/YFrD64mzfq6rEmai0q7GjGGP0RT1AAAAFQDO5++6JonyqnoRkV9Yl1OaEOPjVwAAAIAYA" +
+                "tqtKtU/INlTIuL3wt3nyKzwPUnz3fqxP5Ger3OlRZsOahalTFt2OF5jGGmCunyBTRteOetZObr0QhUIF" +
+                "4bSDr6UiYYYbH1ES0ws/t1mDIeTh3UUHV1QYACN6c07FKyKLMtB9AthiG2FMLKCEedG3NeXItuNzsuQD" +
+                "+n/K1rzMAAAAIBi5SM4pFPiB7BvTZvARV56vrG5QNgWVazSwbwgl/EACiWYbRauHDUQA9f+Rq+ayWcsR" +
+                "os1CD+Q81y9SmlQaZVKkSPZLxXfu5bi3s4o431xjilhZdt4vKbj2pK364IjghJPNBBfmRXzlj9awKxr/" +
+                "UebZcBgNRyeky7VZSbbF2jQSQ==";
+        String parsedKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(dssKey);
+        String fingerprint = SSHKeysHelper.getPublicKeyFingerprint(parsedKey);
+        
+        assertTrue(storedDssKey.equals(parsedKey));
+        assertTrue("fc:6e:ef:31:93:f8:92:2b:a9:03:c7:06:90:f5:ec:bb".equals(fingerprint));
+        
+    }
+}