Configuration to disable URL validation when registering templates/ISOs (#8751)

This commit is contained in:
Fabricio Duarte 2024-08-27 16:12:31 -03:00 committed by GitHub
parent d32ace6731
commit ede39d8edc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 45 additions and 15 deletions

View File

@ -51,6 +51,11 @@ public interface TemplateManager {
static final ConfigKey<Integer> TemplatePreloaderPoolSize = new ConfigKey<Integer>("Advanced", Integer.class, TemplatePreloaderPoolSizeCK, "8",
"Size of the TemplateManager threadpool", false, ConfigKey.Scope.Global);
ConfigKey<Boolean> ValidateUrlIsResolvableBeforeRegisteringTemplate = new ConfigKey<>("Advanced", Boolean.class,
"validate.url.is.resolvable.before.registering.template", "true", "Indicates whether CloudStack "
+ "will validate if the provided URL is resolvable during the register of templates/ISOs before persisting them in the database.",
true);
static final String VMWARE_TOOLS_ISO = "vmware-tools.iso";
static final String XS_TOOLS_ISO = "xs-tools.iso";
@ -139,4 +144,8 @@ public interface TemplateManager {
TemplateType validateTemplateType(BaseCmd cmd, boolean isAdmin, boolean isCrossZones);
List<DatadiskTO> getTemplateDisksOnImageStore(Long templateId, DataStoreRole role, String configurationId);
static Boolean getValidateUrlIsResolvableBeforeRegisteringTemplateValue() {
return ValidateUrlIsResolvableBeforeRegisteringTemplate.value();
}
}

View File

@ -204,7 +204,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException {
TemplateProfile profile = super.prepare(cmd);
String url = profile.getUrl();
UriUtils.validateUrl(ImageFormat.ISO.getFileExtension(), url);
UriUtils.validateUrl(ImageFormat.ISO.getFileExtension(), url, !TemplateManager.getValidateUrlIsResolvableBeforeRegisteringTemplateValue(), false);
boolean followRedirects = StorageManager.DataStoreDownloadFollowRedirects.value();
if (cmd.isDirectDownload()) {
DigestHelper.validateChecksumString(cmd.getChecksum());
@ -238,7 +238,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException {
TemplateProfile profile = super.prepare(cmd);
String url = profile.getUrl();
UriUtils.validateUrl(cmd.getFormat(), url, cmd.isDirectDownload());
UriUtils.validateUrl(cmd.getFormat(), url, !TemplateManager.getValidateUrlIsResolvableBeforeRegisteringTemplateValue(), cmd.isDirectDownload());
Hypervisor.HypervisorType hypervisor = Hypervisor.HypervisorType.getType(cmd.getHypervisor());
boolean followRedirects = StorageManager.DataStoreDownloadFollowRedirects.value();
if (cmd.isDirectDownload()) {

View File

@ -2349,7 +2349,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {AllowPublicUserTemplates, TemplatePreloaderPoolSize};
return new ConfigKey<?>[] {AllowPublicUserTemplates, TemplatePreloaderPoolSize, ValidateUrlIsResolvableBeforeRegisteringTemplate};
}
public List<TemplateAdapter> getTemplateAdapters() {

View File

@ -263,10 +263,17 @@ public class UriUtils {
}
public static Pair<String, Integer> validateUrl(String format, String url) throws IllegalArgumentException {
return validateUrl(format, url, false);
return validateUrl(format, url, false, false);
}
public static Pair<String, Integer> validateUrl(String format, String url, boolean skipIpv6Check) throws IllegalArgumentException {
/**
* Verifies whether the provided URL is valid.
* @param skipHostCheck if false, this function will verify whether the provided URL is resolvable, if it is a legal address and if it does not use IPv6 (configured by `skipIpv6Check`). If any of these conditions are false, an exception will be thrown.
* @param skipIpv6Check if false, this function will verify whether the host uses IPv6 and, if it does, an exception will be thrown. This check is also skipped if `skipHostCheck` is true.
* @return a pair containing the host and the corresponding port.
* @throws IllegalArgumentException if the provided URL is invalid.
*/
public static Pair<String, Integer> validateUrl(String format, String url, boolean skipHostCheck, boolean skipIpv6Check) throws IllegalArgumentException {
try {
URI uri = new URI(url);
if ((uri.getScheme() == null) ||
@ -282,16 +289,8 @@ public class UriUtils {
}
String host = uri.getHost();
try {
InetAddress hostAddr = InetAddress.getByName(host);
if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) {
throw new IllegalArgumentException("Illegal host specified in url");
}
if (!skipIpv6Check && hostAddr instanceof Inet6Address) {
throw new IllegalArgumentException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")");
}
} catch (UnknownHostException uhe) {
throw new IllegalArgumentException("Unable to resolve " + host);
if (!skipHostCheck) {
checkHost(host, skipIpv6Check);
}
// verify format
@ -305,6 +304,28 @@ public class UriUtils {
}
}
/**
* Verifies whether the provided host is valid. Throws an `IllegalArgumentException` if:
* <ul>
* <li>The host is not resolvable;</li>
* <li>The host address is illegal (any local, link local, loopback or multicast address);</li>
* <li>The host uses IPv6. This check is skipped if `skipIv6Check` is set to true.</li>
* </ul>
*/
private static void checkHost(String host, boolean skipIpv6Check) {
try {
InetAddress hostAddr = InetAddress.getByName(host);
if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) {
throw new IllegalArgumentException("Illegal host specified in URL.");
}
if (!skipIpv6Check && hostAddr instanceof Inet6Address) {
throw new IllegalArgumentException(String.format("IPv6 addresses are not supported (%s).", hostAddr.getHostAddress()));
}
} catch (UnknownHostException uhe) {
throw new IllegalArgumentException(String.format("Unable to resolve %s.", host));
}
}
/**
* Add element to priority list examining node attributes: priority (for urls) and type (for checksums)
*/