CLOUDSTACK-5692: obscure passwords when using cifs as storage

This commit is contained in:
Saksham Srivastava 2014-01-16 16:50:40 +05:30 committed by Devdeep Singh
parent c0f60651b9
commit 06f8c1de75
6 changed files with 107 additions and 15 deletions

View File

@ -23,6 +23,7 @@ import java.io.StringReader;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.zip.GZIPInputStream;
@ -49,6 +50,7 @@ import com.cloud.exception.UnsupportedVersionException;
import com.cloud.serializer.GsonHelper;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
import com.cloud.utils.exception.CloudRuntimeException;
/**
@ -436,11 +438,35 @@ public class Request {
}
buf.append(", Ver: ").append(_ver.toString());
buf.append(", Flags: ").append(Integer.toBinaryString(getFlags())).append(", ");
buf.append(content);
String cleanContent = content.toString();
if(cleanContent.contains("password")) {
buf.append(cleanPassword(cleanContent));
} else {
buf.append(content);
}
buf.append(" }");
return buf.toString();
}
public static String cleanPassword(String logString) {
String cleanLogString = null;
if (logString != null) {
cleanLogString = logString;
String[] temp = logString.split(",");
int i = 0;
if (temp != null) {
while (i < temp.length) {
temp[i] = StringUtils.cleanString(temp[i]);
i++;
}
List<String> stringList = new ArrayList<String>();
Collections.addAll(stringList, temp);
cleanLogString = StringUtils.join(stringList, ",");
}
}
return cleanLogString;
}
/**
* Factory method for Request and Response. It expects the bytes to be
* correctly formed so it's possible that it throws underflow exceptions

View File

@ -31,6 +31,8 @@ import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -41,6 +43,7 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
@ -130,7 +133,6 @@ import com.cloud.utils.net.NetUtils;
import com.cloud.utils.ssh.SshHelper;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineName;
/**
* Implementation of dummy resource to be returned from discoverer.
**/
@ -433,7 +435,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
// Only Answer instances are returned by remote agents.
// E.g. see Response.getAnswers()
Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
s_logger.debug("executeRequest received response " + s_gson.toJson(result));
String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result.toString()));
s_logger.debug("executeRequest received response " + logResult);
if (result.length > 0) {
return result[0];
}
@ -1679,7 +1682,10 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
// comment to use Apache HttpClient
// http://stackoverflow.com/a/2793153/939250, but final comment is to
// use Apache.
s_logger.debug("POST request to" + agentUri.toString() + " with contents" + jsonCmd);
String logMessage = StringEscapeUtils.unescapeJava(jsonCmd);
logMessage = cleanPassword(logMessage);
s_logger.debug("POST request to " + agentUri.toString()
+ " with contents " + logMessage);
// Create request
HttpClient httpClient = null;
@ -1719,7 +1725,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
StringEntity cmdJson = new StringEntity(jsonCmd);
request.addHeader("content-type", "application/json");
request.setEntity(cmdJson);
s_logger.debug("Sending cmd to " + agentUri.toString() + " cmd data:" + jsonCmd);
s_logger.debug("Sending cmd to " + agentUri.toString()
+ " cmd data:" + logMessage);
HttpResponse response = httpClient.execute(request);
// Unsupported commands will not route.
@ -1736,7 +1743,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
return null;
} else {
result = EntityUtils.toString(response.getEntity());
s_logger.debug("POST response is" + result);
String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result));
s_logger.debug("POST response is " + logResult);
}
} catch (ClientProtocolException protocolEx) {
// Problem with HTTP message exchange
@ -1862,4 +1870,22 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
return "Unable to connect";
}
public static String cleanPassword(String logString) {
String cleanLogString = null;
if (logString != null) {
cleanLogString = logString;
String[] temp = logString.split(",");
int i = 0;
if (temp != null) {
while (i < temp.length) {
temp[i] = StringUtils.cleanString(temp[i]);
i++;
}
List<String> stringList = new ArrayList<String>();
Collections.addAll(stringList, temp);
cleanLogString = StringUtils.join(stringList, ",");
}
}
return cleanLogString;
}
}

View File

@ -18,6 +18,8 @@ package org.apache.cloudstack.storage.datastore.lifecycle;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -26,7 +28,7 @@ import javax.inject.Inject;
import org.apache.log4j.Logger;
import com.ibm.wsdl.util.StringUtils;
import com.cloud.utils.StringUtils;
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
@ -86,7 +88,13 @@ public class CloudStackImageStoreLifeCycleImpl implements ImageStoreLifeCycle {
DataStoreRole role = (DataStoreRole)dsInfos.get("role");
Map<String, String> details = (Map<String, String>)dsInfos.get("details");
s_logger.info("Trying to add a new data store at " + StringUtils.cleanString(url) + " to data center " + dcId);
String logString = "";
if(url.contains("cifs")) {
logString = cleanPassword(url);
} else {
logString = StringUtils.cleanString(url);
}
s_logger.info("Trying to add a new data store at " + logString + " to data center " + dcId);
URI uri = null;
try {
@ -167,4 +175,22 @@ public class CloudStackImageStoreLifeCycleImpl implements ImageStoreLifeCycle {
return imageStoreHelper.convertToStagingStore(store);
}
public static String cleanPassword(String logString) {
String cleanLogString = null;
if (logString != null) {
cleanLogString = logString;
String[] temp = logString.split(",");
int i = 0;
if (temp != null) {
while (i < temp.length) {
temp[i] = StringUtils.cleanString(temp[i]);
i++;
}
List<String> stringList = new ArrayList<String>();
Collections.addAll(stringList, temp);
cleanLogString = StringUtils.join(stringList, ",");
}
}
return cleanLogString;
}
}

View File

@ -23,17 +23,17 @@ import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.api.response.ImageStoreDetailResponse;
import org.apache.cloudstack.api.response.ImageStoreResponse;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.springframework.stereotype.Component;
import com.cloud.api.query.vo.ImageStoreJoinVO;
import com.cloud.storage.ImageStore;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.StringUtils;
@Component
@Local(value = {ImageStoreJoinDao.class})
@ -67,7 +67,12 @@ public class ImageStoreJoinDaoImpl extends GenericDaoBase<ImageStoreJoinVO, Long
osResponse.setName(ids.getName());
osResponse.setProviderName(ids.getProviderName());
osResponse.setProtocol(ids.getProtocol());
osResponse.setUrl(ids.getUrl());
String url = ids.getUrl();
//if store is type cifs, remove the password
if(ids.getProtocol().equals("cifs".toString())) {
url = StringUtils.cleanString(url);
}
osResponse.setUrl(url);
osResponse.setScope(ids.getScope());
osResponse.setZoneId(ids.getZoneUuid());
osResponse.setZoneName(ids.getZoneName());

View File

@ -34,6 +34,7 @@ import com.cloud.capacity.Capacity;
import com.cloud.storage.ScopeType;
import com.cloud.storage.StoragePool;
import com.cloud.storage.StorageStats;
import com.cloud.utils.StringUtils;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@ -60,7 +61,7 @@ public class StoragePoolJoinDaoImpl extends GenericDaoBase<StoragePoolJoinVO, Lo
spIdSearch.and("id", spIdSearch.entity().getId(), SearchCriteria.Op.EQ);
spIdSearch.done();
this._count = "select count(distinct id) from storage_pool_view WHERE ";
_count = "select count(distinct id) from storage_pool_view WHERE ";
}
@Override
@ -69,7 +70,10 @@ public class StoragePoolJoinDaoImpl extends GenericDaoBase<StoragePoolJoinVO, Lo
poolResponse.setId(pool.getUuid());
poolResponse.setName(pool.getName());
poolResponse.setState(pool.getStatus());
poolResponse.setPath(pool.getPath());
String path = pool.getPath();
//cifs store may contain password entry, remove the password
path = StringUtils.cleanString(path);
poolResponse.setPath(path);
poolResponse.setIpAddress(pool.getHostAddress());
poolResponse.setZoneId(pool.getZoneUuid());
poolResponse.setZoneName(pool.getZoneName());
@ -129,7 +133,10 @@ public class StoragePoolJoinDaoImpl extends GenericDaoBase<StoragePoolJoinVO, Lo
poolResponse.setId(pool.getUuid());
poolResponse.setName(pool.getName());
poolResponse.setState(pool.getStatus());
poolResponse.setPath(pool.getPath());
String path = pool.getPath();
//cifs store may contain password entry, remove the password
path = StringUtils.cleanString(path);
poolResponse.setPath(path);
poolResponse.setIpAddress(pool.getHostAddress());
poolResponse.setZoneId(pool.getZoneUuid());
poolResponse.setZoneName(pool.getZoneName());

View File

@ -1201,7 +1201,9 @@ var processPropertiesInImagestoreObject = function(jsonObj) {
var url = jsonObj.url; //e.g. 'cifs://10.1.1.1/aaa/aaa2/aaa3?user=bbb&password=ccc&domain=ddd'
var passwordIndex = url.indexOf('&password='); //38
var domainIndex = url.indexOf('&domain='); //51
jsonObj.url = url.substring(0, passwordIndex) + url.substring(domainIndex); //remove '&password=ccc' from jsonObj.url
if (passwordIndex >= 0) {
jsonObj.url = url.substring(0, passwordIndex) + url.substring(domainIndex); //remove '&password=ccc' from jsonObj.url
}
}
}