Francesco Romani has uploaded a new change for review.

Change subject: core: VirtIO console access key management
......................................................................

core: VirtIO console access key management

This change introduces a command to edit of public keys to be used to
grant the user access into a SSH-based proxy that exposes the
serial console of every running VM.

Change-Id: I5ff5403823e752e695ebde76a4b7fb83e07099b6
Signed-off-by: Francesco Romani <[email protected]>
---
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetSshPublicKeyQuery.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SetSshPublicKeyCommand.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
A 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/SetSshPublicKeyParameters.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
M 
backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
M 
backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
M 
backend/manager/modules/uutils/src/main/java/org/ovirt/engine/core/uutils/ssh/OpenSSHUtils.java
10 files changed, 170 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/12/39512/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetSshPublicKeyQuery.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetSshPublicKeyQuery.java
new file mode 100644
index 0000000..e823ef2
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetSshPublicKeyQuery.java
@@ -0,0 +1,22 @@
+package org.ovirt.engine.core.bll;
+
+import org.ovirt.engine.core.common.businessentities.UserProfile;
+import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+
+public class GetSshPublicKeyQuery<P extends VdcQueryParametersBase> extends 
QueriesCommandBase<P> {
+    public GetSshPublicKeyQuery(P parameters) {
+        super(parameters);
+    }
+
+    @Override
+    protected void executeQueryCommand() {
+        UserProfile profile = 
DbFacade.getInstance().getUserProfileDao().getByUserId(getUserID());
+
+        if (profile != null) {
+            getQueryReturnValue().setReturnValue(profile.getSshPublicKey());
+        } else {
+            getQueryReturnValue().setReturnValue("");
+        }
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SetSshPublicKeyCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SetSshPublicKeyCommand.java
new file mode 100644
index 0000000..7a8876e
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SetSshPublicKeyCommand.java
@@ -0,0 +1,76 @@
+package org.ovirt.engine.core.bll;
+
+import org.ovirt.engine.core.bll.context.CommandContext;
+import org.ovirt.engine.core.bll.utils.PermissionSubject;
+import org.ovirt.engine.core.common.AuditLogType;
+import org.ovirt.engine.core.common.VdcObjectType;
+import org.ovirt.engine.core.common.action.SetSshPublicKeyParameters;
+import org.ovirt.engine.core.common.businessentities.ActionGroup;
+import org.ovirt.engine.core.common.businessentities.UserProfile;
+import org.ovirt.engine.core.common.errors.VdcBllMessages;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.core.uutils.ssh.OpenSSHUtils;
+
+import java.util.Collections;
+import java.util.List;
+
+public class SetSshPublicKeyCommand <T extends SetSshPublicKeyParameters> 
extends CommandBase<T> {
+
+    static final private String SSH_RSA = "ssh-rsa";
+
+    public SetSshPublicKeyCommand(T parameters) {
+        this(parameters, null);
+    }
+
+    public SetSshPublicKeyCommand(T parameters, CommandContext commandContext) 
{
+        super(parameters, commandContext);
+    }
+
+    @Override
+    protected boolean canDoAction() {
+        boolean result = true;
+
+        if (!OpenSSHUtils.isPublicKeyValid(getParameters().getSshPublicKey())) 
{
+            
addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_INVALID_PUBLIC_SSH_KEY);
+            result = false;
+        }
+
+        return result;
+    }
+
+    @Override
+    protected void executeCommand() {
+        UserProfile profile = getUserProfileDAO().getByUserId(getUserId());
+
+        if (profile == null) {
+            profile = new UserProfile();
+
+            profile.setId(Guid.newGuid());
+            profile.setUserId(getUserId());
+            profile.setSshPublicKey(getParameters().getSshPublicKey());
+
+            getUserProfileDAO().save(profile);
+
+        } else {
+            profile.setSshPublicKey(getParameters().getSshPublicKey());
+
+            getUserProfileDAO().update(profile);
+        }
+
+        setSucceeded(true);
+    }
+
+    @Override
+    public AuditLogType getAuditLogTypeValue() {
+        if (!getSucceeded()) {
+            return AuditLogType.USER_FAILED_TO_SET_SSH_PUBLIC_KEY;
+        } else {
+            return AuditLogType.UNASSIGNED;
+        }
+    }
+
+    @Override
+    public List<PermissionSubject> getPermissionCheckSubjects() {
+        return Collections.singletonList(new PermissionSubject(getUserId(), 
VdcObjectType.User, ActionGroup.MANIPULATE_USERS));
+    }
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
index f5630ff..45d8c8d 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
@@ -842,6 +842,7 @@
     USER_ADD_SYSTEM_PERMISSION_FAILED(867, AuditLogSeverity.ERROR),
     USER_REMOVE_SYSTEM_PERMISSION(868),
     USER_REMOVE_SYSTEM_PERMISSION_FAILED(869, AuditLogSeverity.ERROR),
+    USER_FAILED_TO_SET_SSH_PUBLIC_KEY(870, AuditLogSeverity.ERROR),
 
     // AD Computer Account
     AD_COMPUTER_ACCOUNT_SUCCEEDED(900),
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/SetSshPublicKeyParameters.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/SetSshPublicKeyParameters.java
new file mode 100644
index 0000000..2f04f5d
--- /dev/null
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/SetSshPublicKeyParameters.java
@@ -0,0 +1,18 @@
+package org.ovirt.engine.core.common.action;
+
+public class SetSshPublicKeyParameters extends VdcActionParametersBase {
+    private static final long serialVersionUID = -4168302609852555079L;
+
+    private String sshPublicKey;
+
+    public SetSshPublicKeyParameters() {
+    }
+
+    public SetSshPublicKeyParameters(String sshPublicKey) {
+        this.sshPublicKey = sshPublicKey;
+    }
+
+    public String getSshPublicKey() {
+        return sshPublicKey;
+    }
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
index c73ebbe..421f3d0 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/VdcActionType.java
@@ -177,6 +177,7 @@
     LoginAdminUser(418, ActionGroup.LOGIN, false, QuotaDependency.NONE),
     AddUser(419, ActionGroup.MANIPULATE_USERS, false, QuotaDependency.NONE),
     AddGroup(420, ActionGroup.MANIPULATE_USERS, false, QuotaDependency.NONE),
+    SetSshPublicKey(421, ActionGroup.MANIPULATE_USERS, false, 
QuotaDependency.NONE),
     // Tags
     AddTag(501, false, QuotaDependency.NONE),
     RemoveTag(502, false, QuotaDependency.NONE),
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
index 8c9935c..5831c48 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
@@ -806,6 +806,8 @@
     
ACTION_TYPE_FAILED_NETWORK_CUSTOM_PROPERTIES_NOT_SUPPORTED(ErrorType.NOT_SUPPORTED),
     
ACTION_TYPE_FAILED_NETWORK_CUSTOM_PROPERTIES_BAD_INPUT(ErrorType.BAD_PARAMETERS),
 
+    ACTION_TYPE_FAILED_INVALID_PUBLIC_SSH_KEY(ErrorType.BAD_PARAMETERS),
+
     NETWORK_ILEGAL_NETWORK_NAME(ErrorType.BAD_PARAMETERS),
     NETWORK_ATTACH_ILLEGAL_GATEWAY(ErrorType.BAD_PARAMETERS),
     MISSING_DIRECTORY_ELEMENT_ID(ErrorType.BAD_PARAMETERS),
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
index f858899..2d62af3 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
@@ -172,6 +172,7 @@
     GetDbUserByUserNameAndDomain(VdcQueryAuthType.User),
     GetUserBySessionId(VdcQueryAuthType.User),
     GetEngineSessionIdToken(VdcQueryAuthType.User),
+    GetSshPublicKey(VdcQueryAuthType.User),
 
     // Directory queries:
     GetDirectoryUserById(VdcQueryAuthType.User),
diff --git 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
index f884866..aa1ffd8 100644
--- 
a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
+++ 
b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/dbbroker/auditloghandling/AuditLogableBase.java
@@ -37,6 +37,7 @@
 import org.ovirt.engine.core.dao.StorageDomainOvfInfoDao;
 import org.ovirt.engine.core.dao.StorageDomainStaticDAO;
 import org.ovirt.engine.core.dao.StoragePoolDAO;
+import org.ovirt.engine.core.dao.UserProfileDAO;
 import org.ovirt.engine.core.dao.VdsDAO;
 import org.ovirt.engine.core.dao.VdsDynamicDAO;
 import org.ovirt.engine.core.dao.VdsGroupDAO;
@@ -698,6 +699,10 @@
         return getDbFacade().getDbUserDao();
     }
 
+    public UserProfileDAO getUserProfileDAO() {
+        return getDbFacade().getUserProfileDao();
+    }
+
     public DbGroupDAO getAdGroupDAO() {
         return getDbFacade().getDbGroupDao();
     }
diff --git 
a/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
 
b/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
index 5a84f06..0e08c28 100644
--- 
a/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
+++ 
b/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
@@ -404,6 +404,7 @@
 USER_ADD_SYSTEM_PERMISSION_FAILED=User ${UserName} failed to grant permission 
for Role ${RoleName} on ${VdcObjectType} to User/Group ${SubjectName}.
 USER_REMOVE_SYSTEM_PERMISSION=User/Group ${SubjectName} Role ${RoleName} 
permission was removed from ${VdcObjectType} by ${UserName}
 USER_REMOVE_SYSTEM_PERMISSION_FAILED=User ${UserName} failed to remove 
permission for Role ${RoleName} from ${VdcObjectType} to User/Group 
${SubjectName}
+USER_FAILED_TO_SET_SSH_PUBLIC_KEY=Failed to set SSH public key for user 
${UserName}
 USER_ADD_ROLE=Role ${RoleName} granted to ${UserName}
 USER_ADD_ROLE_FAILED=Failed to grant role ${RoleName} (User ${UserName})
 USER_REMOVE_ROLE=Role ${RoleName} removed from ${UserName}
diff --git 
a/backend/manager/modules/uutils/src/main/java/org/ovirt/engine/core/uutils/ssh/OpenSSHUtils.java
 
b/backend/manager/modules/uutils/src/main/java/org/ovirt/engine/core/uutils/ssh/OpenSSHUtils.java
index 1faccec..8b5a532 100644
--- 
a/backend/manager/modules/uutils/src/main/java/org/ovirt/engine/core/uutils/ssh/OpenSSHUtils.java
+++ 
b/backend/manager/modules/uutils/src/main/java/org/ovirt/engine/core/uutils/ssh/OpenSSHUtils.java
@@ -1,10 +1,14 @@
 package org.ovirt.engine.core.uutils.ssh;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.nio.charset.Charset;
 import java.security.PublicKey;
 import java.security.interfaces.RSAPublicKey;
+import java.util.Arrays;
 
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.codec.binary.Hex;
@@ -192,4 +196,43 @@
         return fingerprintString;
     }
 
+    private static boolean verifyByteArray(DataInputStream dataInputStream, 
byte[] expected) throws IOException {
+        int length = dataInputStream.readInt();
+        byte[] contents = new byte[length];
+        int numBytes = dataInputStream.read(contents, 0, length);
+
+        if (numBytes != length) {
+            return false;
+        }
+
+        if (expected != null) {
+            return Arrays.equals(contents, expected);
+        }
+
+        return true;
+    }
+
+    public static boolean isPublicKeyValid(String publicKey) {
+        String[] words = publicKey.split("\\s+", 3);
+
+        if (!words[0].equals(SSH_RSA)) {
+            return false;
+        }
+
+        try {
+            byte[] decodedBytes = Base64.decodeBase64(words[1]);
+
+            try (ByteArrayInputStream inputStream = new 
ByteArrayInputStream(decodedBytes);
+                 DataInputStream dataInputStream = new 
DataInputStream(inputStream)) {
+
+                verifyByteArray(dataInputStream, 
SSH_RSA.getBytes(Charset.forName("UTF-8")));
+                verifyByteArray(dataInputStream, null);
+                verifyByteArray(dataInputStream, null);
+
+                return true;
+            }
+        } catch (IOException e) {
+            return false;
+        }
+    }
 }


-- 
To view, visit https://gerrit.ovirt.org/39512
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I5ff5403823e752e695ebde76a4b7fb83e07099b6
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to