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
