Merge release branch 4.18 to main

* 4.18:
  cleanup removal of physical network (#7630)
  console proxy: use AeadBase64Encryptor instead of AES/CBC/PKCS5Padding (#7237)
This commit is contained in:
Daan Hoogland 2023-07-05 11:52:23 +02:00
commit 02be2cdf67
4 changed files with 69 additions and 162 deletions

View File

@ -85,7 +85,6 @@ import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command; import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.IpAddressTO;
@ -148,7 +147,6 @@ import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao; import com.cloud.network.dao.Ipv6GuestPrefixSubnetNetworkMapDao;
import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.LoadBalancerDao;
import com.cloud.network.dao.NetworkAccountDao;
import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkDetailVO; import com.cloud.network.dao.NetworkDetailVO;
import com.cloud.network.dao.NetworkDetailsDao; import com.cloud.network.dao.NetworkDetailsDao;
@ -163,7 +161,6 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao; import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.dao.VirtualRouterProviderDao;
import com.cloud.network.element.NetworkElement; import com.cloud.network.element.NetworkElement;
import com.cloud.network.element.OvsProviderVO; import com.cloud.network.element.OvsProviderVO;
import com.cloud.network.element.VirtualRouterElement; import com.cloud.network.element.VirtualRouterElement;
@ -385,8 +382,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
@Inject @Inject
AccountService _accountService; AccountService _accountService;
@Inject @Inject
NetworkAccountDao _networkAccountDao;
@Inject
VirtualMachineManager vmManager; VirtualMachineManager vmManager;
@Inject @Inject
Ipv6Service ipv6Service; Ipv6Service ipv6Service;
@ -395,16 +390,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
@Inject @Inject
AlertManager alertManager; AlertManager alertManager;
@Inject @Inject
VirtualRouterProviderDao vrProviderDao;
@Inject
DomainRouterDao routerDao; DomainRouterDao routerDao;
@Inject @Inject
DomainRouterJoinDao routerJoinDao; DomainRouterJoinDao routerJoinDao;
@Inject @Inject
CommandSetupHelper commandSetupHelper; CommandSetupHelper commandSetupHelper;
@Inject @Inject
AgentManager agentManager;
@Inject
ServiceOfferingDao serviceOfferingDao; ServiceOfferingDao serviceOfferingDao;
@Autowired @Autowired
@ -4395,23 +4386,37 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
return Transaction.execute(new TransactionCallback<Boolean>() { return Transaction.execute(new TransactionCallback<Boolean>() {
@Override @Override
public Boolean doInTransaction(TransactionStatus status) { public Boolean doInTransaction(TransactionStatus status) {
// delete vlans for this zone disablePhysicalNetwork(physicalNetworkId, pNetwork);
List<VlanVO> vlans = _vlanDao.listVlansByPhysicalNetworkId(physicalNetworkId); deleteIpAddresses();
for (VlanVO vlan : vlans) { deleteVlans();
_vlanDao.remove(vlan.getId()); deleteNetworks();
}
// Delete networks
List<NetworkVO> networks = _networksDao.listByPhysicalNetwork(physicalNetworkId);
if (networks != null && !networks.isEmpty()) {
for (NetworkVO network : networks) {
_networksDao.remove(network.getId());
}
}
// delete vnets // delete vnets
_dcDao.deleteVnet(physicalNetworkId); _dcDao.deleteVnet(physicalNetworkId);
if (!deleteProviders()) {
return false;
}
// delete traffic types
_pNTrafficTypeDao.deleteTrafficTypes(physicalNetworkId);
return _physicalNetworkDao.remove(physicalNetworkId);
}
private void disablePhysicalNetwork(Long physicalNetworkId, PhysicalNetworkVO pNetwork) {
pNetwork.setState(PhysicalNetwork.State.Disabled);
_physicalNetworkDao.update(physicalNetworkId, pNetwork);
}
private void deleteIpAddresses() {
List<IPAddressVO> ipAddresses = _ipAddressDao.listByPhysicalNetworkId(physicalNetworkId);
for (IPAddressVO ipaddress : ipAddresses) {
_ipAddressDao.remove(ipaddress.getId());
}
}
private boolean deleteProviders() {
// delete service providers // delete service providers
List<PhysicalNetworkServiceProviderVO> providers = _pNSPDao.listBy(physicalNetworkId); List<PhysicalNetworkServiceProviderVO> providers = _pNSPDao.listBy(physicalNetworkId);
@ -4426,11 +4431,25 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
return false; return false;
} }
} }
return true;
}
// delete traffic types private void deleteNetworks() {
_pNTrafficTypeDao.deleteTrafficTypes(physicalNetworkId); // Delete networks
List<NetworkVO> networks = _networksDao.listByPhysicalNetwork(physicalNetworkId);
if (CollectionUtils.isNotEmpty(networks)) {
for (NetworkVO network : networks) {
_networksDao.remove(network.getId());
}
}
}
return _physicalNetworkDao.remove(physicalNetworkId); private void deleteVlans() {
// delete vlans for this zone
List<VlanVO> vlans = _vlanDao.listVlansByPhysicalNetworkId(physicalNetworkId);
for (VlanVO vlan : vlans) {
_vlanDao.remove(vlan.getId());
}
} }
}); });
} }

View File

@ -16,23 +16,15 @@
// under the License. // under the License.
package com.cloud.servlet; package com.cloud.servlet;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.cloud.utils.crypt.AeadBase64Encryptor;
import com.cloud.utils.crypt.Base64Encryptor;
// To maintain independency of console proxy project, we duplicate this class from console proxy project // To maintain independency of console proxy project, we duplicate this class from console proxy project
public class ConsoleProxyPasswordBasedEncryptor { public class ConsoleProxyPasswordBasedEncryptor {
private static final Logger s_logger = Logger.getLogger(ConsoleProxyPasswordBasedEncryptor.class); private static final Logger s_logger = Logger.getLogger(ConsoleProxyPasswordBasedEncryptor.class);
@ -51,65 +43,16 @@ public class ConsoleProxyPasswordBasedEncryptor {
if (text == null || text.isEmpty()) if (text == null || text.isEmpty())
return text; return text;
try { Base64Encryptor encryptor = new AeadBase64Encryptor(keyIvPair.getKeyBytes(), keyIvPair.getIvBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); return encryptor.encrypt(text);
SecretKeySpec keySpec = new SecretKeySpec(keyIvPair.getKeyBytes(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(keyIvPair.getIvBytes()));
byte[] encryptedBytes = cipher.doFinal(text.getBytes());
return Base64.encodeBase64URLSafeString(encryptedBytes);
} catch (NoSuchAlgorithmException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (NoSuchPaddingException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (IllegalBlockSizeException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (BadPaddingException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (InvalidKeyException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (InvalidAlgorithmParameterException e) {
s_logger.error("Unexpected exception ", e);
return null;
}
} }
public String decryptText(String encryptedText) { public String decryptText(String encryptedText) {
if (encryptedText == null || encryptedText.isEmpty()) if (encryptedText == null || encryptedText.isEmpty())
return encryptedText; return encryptedText;
try { Base64Encryptor encryptor = new AeadBase64Encryptor(keyIvPair.getKeyBytes(), keyIvPair.getIvBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); return encryptor.decrypt(encryptedText);
SecretKeySpec keySpec = new SecretKeySpec(keyIvPair.getKeyBytes(), "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(keyIvPair.getIvBytes()));
byte[] encryptedBytes = Base64.decodeBase64(encryptedText);
return new String(cipher.doFinal(encryptedBytes));
} catch (NoSuchAlgorithmException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (NoSuchPaddingException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (IllegalBlockSizeException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (BadPaddingException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (InvalidKeyException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (InvalidAlgorithmParameterException e) {
s_logger.error("Unexpected exception ", e);
return null;
}
} }
public <T> String encryptObject(Class<?> clz, T obj) { public <T> String encryptObject(Class<?> clz, T obj) {

View File

@ -16,30 +16,15 @@
// under the License. // under the License.
package com.cloud.consoleproxy; package com.cloud.consoleproxy;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
/** import com.cloud.utils.crypt.AeadBase64Encryptor;
* import com.cloud.utils.crypt.Base64Encryptor;
* @author Kelven Yang
* A simple password based encyrptor based on AES/CBC. It can serialize simple POJO object into URL safe string
* and deserialize it back.
*
*/
public class ConsoleProxyPasswordBasedEncryptor { public class ConsoleProxyPasswordBasedEncryptor {
private static final Logger s_logger = Logger.getLogger(ConsoleProxyPasswordBasedEncryptor.class); private static final Logger s_logger = Logger.getLogger(ConsoleProxyPasswordBasedEncryptor.class);
@ -57,65 +42,16 @@ public class ConsoleProxyPasswordBasedEncryptor {
if (text == null || text.isEmpty()) if (text == null || text.isEmpty())
return text; return text;
try { Base64Encryptor encryptor = new AeadBase64Encryptor(keyIvPair.getKeyBytes(), keyIvPair.getIvBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); return encryptor.encrypt(text);
SecretKeySpec keySpec = new SecretKeySpec(keyIvPair.getKeyBytes(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(keyIvPair.getIvBytes()));
byte[] encryptedBytes = cipher.doFinal(text.getBytes());
return Base64.encodeBase64URLSafeString(encryptedBytes);
} catch (NoSuchAlgorithmException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (NoSuchPaddingException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (IllegalBlockSizeException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (BadPaddingException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (InvalidKeyException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (InvalidAlgorithmParameterException e) {
s_logger.error("Unexpected exception ", e);
return null;
}
} }
public String decryptText(String encryptedText) { public String decryptText(String encryptedText) {
if (encryptedText == null || encryptedText.isEmpty()) if (encryptedText == null || encryptedText.isEmpty())
return encryptedText; return encryptedText;
try { Base64Encryptor encryptor = new AeadBase64Encryptor(keyIvPair.getKeyBytes(), keyIvPair.getIvBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); return encryptor.decrypt(encryptedText);
SecretKeySpec keySpec = new SecretKeySpec(keyIvPair.getKeyBytes(), "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(keyIvPair.getIvBytes()));
byte[] encryptedBytes = Base64.decodeBase64(encryptedText);
return new String(cipher.doFinal(encryptedBytes));
} catch (NoSuchAlgorithmException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (NoSuchPaddingException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (IllegalBlockSizeException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (BadPaddingException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (InvalidKeyException e) {
s_logger.error("Unexpected exception ", e);
return null;
} catch (InvalidAlgorithmParameterException e) {
s_logger.error("Unexpected exception ", e);
return null;
}
} }
public <T> String encryptObject(Class<?> clz, T obj) { public <T> String encryptObject(Class<?> clz, T obj) {

View File

@ -29,9 +29,9 @@ import java.util.Base64;
public class AeadBase64Encryptor implements Base64Encryptor { public class AeadBase64Encryptor implements Base64Encryptor {
Aead aead = null; Aead aead = null;
private final byte[] aad = new byte[]{}; private byte[] aad = new byte[]{};
public AeadBase64Encryptor(byte[] key) { private void initEncryptor(byte[] key) {
try { try {
AeadConfig.register(); AeadConfig.register();
MessageDigest digest = MessageDigest.getInstance("SHA-256"); MessageDigest digest = MessageDigest.getInstance("SHA-256");
@ -42,6 +42,15 @@ public class AeadBase64Encryptor implements Base64Encryptor {
} }
} }
public AeadBase64Encryptor(byte[] key) {
initEncryptor(key);
}
public AeadBase64Encryptor(byte[] key, byte[] aad) {
initEncryptor(key);
this.aad = aad;
}
@Override @Override
public String encrypt(String plain) { public String encrypt(String plain) {
try { try {