mirror of https://github.com/apache/cloudstack.git
framework-jobs,server: fix password obfuscation for job result and password with display=false (#13388)
* framework-jobs: fix password obfuscation for job result Fixes #13387 Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com> * add password as hidden Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com> --------- Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
parent
b36f06482f
commit
2eb9820f3c
|
|
@ -31,6 +31,8 @@ import java.util.concurrent.Executors;
|
|||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
|
@ -114,6 +116,8 @@ import com.cloud.vm.dao.VMInstanceDao;
|
|||
import org.apache.logging.log4j.ThreadContext;
|
||||
|
||||
public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager, ClusterManagerListener, Configurable {
|
||||
private static final Pattern PASSWORD_FIELD_PATTERN = Pattern.compile("\\\"password\\\":\\\"([^\\\"]*)\\\"+");
|
||||
|
||||
// Advanced
|
||||
public static final ConfigKey<Long> JobExpireMinutes = new ConfigKey<Long>("Advanced", Long.class, "job.expire.minutes", "1440",
|
||||
"Time (in minutes) for async-jobs to be kept in system", true, ConfigKey.Scope.Global);
|
||||
|
|
@ -517,22 +521,26 @@ public class AsyncJobManagerImpl extends ManagerBase implements AsyncJobManager,
|
|||
}
|
||||
|
||||
public String obfuscatePassword(String result, boolean hidePassword) {
|
||||
if (hidePassword) {
|
||||
String pattern = "\"password\":";
|
||||
if (result != null) {
|
||||
if (result.contains(pattern)) {
|
||||
String[] resp = result.split(pattern);
|
||||
String psswd = resp[1].toString().split(",")[0];
|
||||
if (psswd.endsWith("}")) {
|
||||
psswd = psswd.substring(0, psswd.length() - 1);
|
||||
result = resp[0] + pattern + psswd.replace(psswd.substring(2, psswd.length() - 1), "*****") + "}," + resp[1].split(",", 2)[1];
|
||||
} else {
|
||||
result = resp[0] + pattern + psswd.replace(psswd.substring(2, psswd.length() - 1), "*****") + "," + resp[1].split(",", 2)[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hidePassword || StringUtils.isBlank(result)) {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
|
||||
Matcher matcher = PASSWORD_FIELD_PATTERN.matcher(result);
|
||||
StringBuilder obfuscatedResult = new StringBuilder();
|
||||
while (matcher.find()) {
|
||||
String password = matcher.group(1);
|
||||
String replacement = "\"password\":\"" + obfuscatePasswordValue(password) + "\"";
|
||||
matcher.appendReplacement(obfuscatedResult, Matcher.quoteReplacement(replacement));
|
||||
}
|
||||
matcher.appendTail(obfuscatedResult);
|
||||
return obfuscatedResult.toString();
|
||||
}
|
||||
|
||||
private String obfuscatePasswordValue(String password) {
|
||||
if (StringUtils.isEmpty(password)) {
|
||||
return password;
|
||||
}
|
||||
return password.charAt(0) + "*****";
|
||||
}
|
||||
|
||||
private void scheduleExecution(final AsyncJobVO job) {
|
||||
|
|
|
|||
|
|
@ -17,12 +17,15 @@
|
|||
package org.apache.cloudstack.framework.jobs;
|
||||
|
||||
import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import com.cloud.utils.HumanReadableJson;
|
||||
|
||||
@RunWith (MockitoJUnitRunner.class)
|
||||
public class AsyncJobManagerTest {
|
||||
|
||||
|
|
@ -37,6 +40,12 @@ public class AsyncJobManagerTest {
|
|||
String inputNoBraces = "\"password\":\"password\"\",\"action\":\"OFF\"";
|
||||
String expectedNoBraces = "\"password\":\"p*****\",\"action\":\"OFF\"";
|
||||
|
||||
String realUserVmResponseWithPasswordInput = "{\"id\":\"f75b0990-5801-4b78-bcb0-58a503afa49c\",\"name\":\"pw-vm\"," +
|
||||
"\"displayname\":\"pw-vm\",\"account\":\"admin\",\"password\":\"67wSK5\",\"instancename\":\"i-2-17-VM\"," +
|
||||
"\"details\":{\"password\":\"3WTVryPJZJwMZGcJJ+OOYf84+uixk/1FraomPG9N6/Uvng\\u003d\\u003d\"," +
|
||||
"\"Message.ReservedCapacityFreed.Flag\":\"true\",\"rootDiskController\":\"osdefault\"}," +
|
||||
"\"arch\":\"x86_64\",\"jobid\":\"c13865d3-61ec-4269-979a-3d799181d5fe\",\"jobstatus\":0}";
|
||||
|
||||
@Test
|
||||
public void obfuscatePasswordTest() {
|
||||
String result = asyncJobManager.obfuscatePassword(input, true);
|
||||
|
|
@ -79,4 +88,15 @@ public class AsyncJobManagerTest {
|
|||
Assert.assertEquals(noPassword, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void obfuscatePasswordTestHidePasswordRealInput() {
|
||||
String result = asyncJobManager.obfuscatePassword(realUserVmResponseWithPasswordInput, true);
|
||||
|
||||
Assert.assertNotNull(result);
|
||||
Assert.assertFalse(result.contains("\"password\":\"3WTVryPJZJwMZGcJJ+OOYf84+uixk\""));
|
||||
String jsonObject = HumanReadableJson.getHumanReadableBytesJson(result);
|
||||
Assert.assertTrue(StringUtils.isNotEmpty(jsonObject));
|
||||
Assert.assertTrue(jsonObject.contains("\"password\":\"3*****\""));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,28 +24,21 @@ import java.util.Set;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.network.BgpPeer;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.vm.VirtualMachineProfileImpl;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.network.BgpPeer;
|
||||
import org.apache.cloudstack.network.router.deployment.RouterDeploymentDefinition;
|
||||
import org.apache.cloudstack.network.router.deployment.RouterDeploymentDefinitionBuilder;
|
||||
import org.apache.cloudstack.network.topology.NetworkTopology;
|
||||
import org.apache.cloudstack.network.topology.NetworkTopologyContext;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import com.cloud.agent.api.to.LoadBalancerTO;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
|
|
@ -101,6 +94,7 @@ import com.cloud.network.vpc.Vpc;
|
|||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offerings.NetworkOfferingVO;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
|
|
@ -117,8 +111,12 @@ import com.cloud.vm.UserVmVO;
|
|||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.VirtualMachineProfileImpl;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, UserDataServiceProvider, SourceNatServiceProvider,
|
||||
StaticNatServiceProvider, FirewallServiceProvider, LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer,
|
||||
|
|
@ -736,7 +734,7 @@ NetworkMigrationResponder, AggregatedCommandExecutor, RedundantResource, DnsServ
|
|||
|
||||
_userVmDao.loadDetails(userVmVO);
|
||||
userVmVO.setDetail(VmDetailConstants.PASSWORD, password_encrypted);
|
||||
_userVmDao.saveDetails(userVmVO);
|
||||
_userVmDao.saveDetails(userVmVO, List.of(VmDetailConstants.PASSWORD));
|
||||
|
||||
userVmVO.setUpdateParameters(true);
|
||||
_userVmDao.update(userVmVO.getId(), userVmVO);
|
||||
|
|
|
|||
Loading…
Reference in New Issue