Frank Kobzik has uploaded a new change for review.

Change subject: core: Detect inability to decrypt password in RunOnce
......................................................................

core: Detect inability to decrypt password in RunOnce

This change detects password decryption errors for sysprepped VMs that
are run via Run Once.

When the passwords can't be decrypted (and aren't overriden in params),
RunVmOnceCommand.canDoAction will prevent running VM.

TODO:
 - add corresponding entry to VdcBllMessages

Change-Id: I37760cce844f394e480d712e6ed024f22b848348
Signed-off-by: Frantisek Kobzik <fkob...@redhat.com>
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1029126
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmOnceCommand.java
A 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmOnceCommandTest.java
2 files changed, 139 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/87/31387/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmOnceCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmOnceCommand.java
index b33035f..5ec853e 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmOnceCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RunVmOnceCommand.java
@@ -1,5 +1,6 @@
 package org.ovirt.engine.core.bll;
 
+import java.security.GeneralSecurityException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -25,12 +26,15 @@
 import org.ovirt.engine.core.common.businessentities.VmDevice;
 import org.ovirt.engine.core.common.businessentities.VmDeviceGeneralType;
 import org.ovirt.engine.core.common.businessentities.VmPayload;
+import org.ovirt.engine.core.common.config.ConfigValues;
 import org.ovirt.engine.core.common.errors.VdcBllMessages;
 import org.ovirt.engine.core.common.utils.VmDeviceType;
 import org.ovirt.engine.core.common.vdscommands.CreateVmVDSCommandParameters;
 import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
 import org.ovirt.engine.core.dao.VmDeviceDAO;
 import org.ovirt.engine.core.utils.OsRepositoryImpl;
+import org.ovirt.engine.core.utils.crypt.EngineEncryptionUtils;
 
 @NonTransactiveCommandAttribute
 public class RunVmOnceCommand<T extends RunVmOnceParams> extends 
RunVmCommand<T> implements QuotaStorageDependent {
@@ -56,7 +60,7 @@
 
     @Override
     protected boolean canDoAction() {
-        if (!super.canDoAction()) {
+        if (!superCanDoAction()) {
             return false;
         }
 
@@ -66,9 +70,14 @@
             return 
failCanDoAction(VdcBllMessages.VM_CANNOT_RUN_ONCE_WITH_ILLEGAL_SYSPREP_PARAM);
         }
 
+        if (getVm().isSysprepUsed()) {
+            if (!containsValidAdminPass() || !containsValidDomainAdminPass()) {
+                return 
failCanDoAction(VdcBllMessages.VM_CANNOT_RUN_ONCE_WITH_ILLEGAL_SYSPREP_PARAM); 
// todo msg
+            }
+        }
+
         if (getParameters().getVmInit() != null) {
-            if (!OsRepositoryImpl.INSTANCE.isWindows(getVm().getOs()) &&
-                    
!FeatureSupported.cloudInit(getVm().getVdsGroupCompatibilityVersion())) {
+            if (!isWindowsVm() && 
!FeatureSupported.cloudInit(getVm().getVdsGroupCompatibilityVersion())) {
                 return 
failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_CLOUD_INIT_IS_NOT_SUPPORTED);
             }
 
@@ -83,6 +92,36 @@
         return true;
     }
 
+    boolean isWindowsVm() {
+        return OsRepositoryImpl.INSTANCE.isWindows(getVm().getOs());
+    }
+
+    boolean superCanDoAction() {
+        return super.canDoAction();
+    }
+
+    private boolean containsValidAdminPass() {
+        return (getParameters().getVmInit() == null || 
getParameters().getVmInit().getRootPassword() == null)
+                ? canConfigValBeDecrypted(ConfigValues.LocalAdminPassword) // 
adminPassword not overriden in params
+                : true;
+    }
+
+    private boolean containsValidDomainAdminPass() {
+        return (getParameters().getSysPrepPassword() == null)
+                ? canConfigValBeDecrypted(ConfigValues.SysPrepDefaultPassword)
+                : true;
+    }
+
+    boolean canConfigValBeDecrypted(ConfigValues c) {
+        String value = 
DbFacade.getInstance().getVdcOptionDao().getByNameAndVersion(c.name(), 
"general").getoption_value();
+        try {
+            EngineEncryptionUtils.decrypt(value);
+            return true;
+        } catch (GeneralSecurityException e) {
+            return false;
+        }
+    }
+
     private void loadPayload() {
         VmDeviceDAO dao = getDbFacade().getVmDeviceDao();
         List<VmDevice> disks = 
dao.getVmDeviceByVmIdAndType(getParameters().getVmId(), 
VmDeviceGeneralType.DISK);
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmOnceCommandTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmOnceCommandTest.java
new file mode 100644
index 0000000..25e8524
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/RunVmOnceCommandTest.java
@@ -0,0 +1,97 @@
+package org.ovirt.engine.core.bll;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.ovirt.engine.core.common.action.RunVmOnceParams;
+import org.ovirt.engine.core.common.businessentities.VM;
+import org.ovirt.engine.core.common.businessentities.VmInit;
+import org.ovirt.engine.core.common.businessentities.VmPayload;
+import org.ovirt.engine.core.common.config.ConfigValues;
+import org.ovirt.engine.core.compat.Guid;
+
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+@RunWith(JUnit4.class)
+public class RunVmOnceCommandTest {
+
+    RunVmOnceCommand cmd;
+
+    RunVmOnceParams params = new RunVmOnceParams(Guid.newGuid());
+
+    VM vm;
+
+    @Before
+    public void setup() {
+        VmPayload payload = mock(VmPayload.class);
+        params.setVmPayload(payload);
+        cmd = spy(new RunVmOnceCommand<>(params));
+        doReturn(true).when(cmd).superCanDoAction();
+        vm = mock(VM.class);
+        doReturn(true).when(vm).isSysprepUsed();
+        doReturn(vm).when(cmd).getVm();
+    }
+
+    @Test
+    public void testCanDoActionNoSysprep() {
+        doReturn(false).when(vm).isSysprepUsed();
+        assertTrue(cmd.canDoAction());
+    }
+
+    @Test
+    public void testCanDoActionSysprepPasswordDecryption() {
+        
doReturn(true).when(cmd).canConfigValBeDecrypted(ConfigValues.LocalAdminPassword);
+        
doReturn(true).when(cmd).canConfigValBeDecrypted(ConfigValues.SysPrepDefaultPassword);
+
+        assertTrue(cmd.canDoAction());
+    }
+
+    @Test
+    public void testCanDoActionSysprepPassNotDecryptable() {
+        
doReturn(true).when(cmd).canConfigValBeDecrypted(ConfigValues.LocalAdminPassword);
+        
doReturn(false).when(cmd).canConfigValBeDecrypted(ConfigValues.SysPrepDefaultPassword);
+
+        assertFalse(cmd.canDoAction());
+    }
+
+    @Test
+    public void testCanDoActionAdminPassNotDecryptable() {
+        
doReturn(false).when(cmd).canConfigValBeDecrypted(ConfigValues.LocalAdminPassword);
+        
doReturn(true).when(cmd).canConfigValBeDecrypted(ConfigValues.SysPrepDefaultPassword);
+
+        assertFalse(cmd.canDoAction());
+    }
+
+    @Test
+    public void testCanDoActionSysprepOverriden() {
+        params.setSysPrepUserName("user");
+        params.setSysPrepPassword("overriden");
+
+        
doReturn(true).when(cmd).canConfigValBeDecrypted(ConfigValues.LocalAdminPassword);
+        
doReturn(false).when(cmd).canConfigValBeDecrypted(ConfigValues.SysPrepDefaultPassword);
+
+        assertTrue(cmd.canDoAction());
+    }
+
+    @Test
+    public void testCanDoActionAdminPassOverriden() {
+        doReturn(true).when(cmd).isWindowsVm();
+
+        VmInit mockInit = mock(VmInit.class);
+        when(mockInit.getRootPassword()).thenReturn("overriden");
+        params.setVmInit(mockInit);
+
+        
doReturn(false).when(cmd).canConfigValBeDecrypted(ConfigValues.LocalAdminPassword);
+        
doReturn(true).when(cmd).canConfigValBeDecrypted(ConfigValues.SysPrepDefaultPassword);
+
+        assertTrue(cmd.canDoAction());
+    }
+
+}


-- 
To view, visit http://gerrit.ovirt.org/31387
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I37760cce844f394e480d712e6ed024f22b848348
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Frank Kobzik <fkob...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to