rhtyd closed pull request #2046: CLOUDSTACK-7958: Add configuration for limit to CIDRs for Admin API calls URL: https://github.com/apache/cloudstack/pull/2046
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java b/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java index 86d3bebb38b..b3b17e7d970 100644 --- a/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java +++ b/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java @@ -276,12 +276,12 @@ private void addRouteToInternalIpOrCidr(String localgw, String eth1ip, String et s_logger.debug("addRouteToInternalIp: destIp is null"); return; } - if (!NetUtils.isValidIp(destIpOrCidr) && !NetUtils.isValidCIDR(destIpOrCidr)) { + if (!NetUtils.isValidIp4(destIpOrCidr) && !NetUtils.isValidIp4Cidr(destIpOrCidr)) { s_logger.warn(" destIp is not a valid ip address or cidr destIp=" + destIpOrCidr); return; } boolean inSameSubnet = false; - if (NetUtils.isValidIp(destIpOrCidr)) { + if (NetUtils.isValidIp4(destIpOrCidr)) { if (eth1ip != null && eth1mask != null) { inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask); } else { diff --git a/api/src/org/apache/cloudstack/api/ApiServerService.java b/api/src/org/apache/cloudstack/api/ApiServerService.java index 2b5768261b5..382b48a5e02 100644 --- a/api/src/org/apache/cloudstack/api/ApiServerService.java +++ b/api/src/org/apache/cloudstack/api/ApiServerService.java @@ -24,7 +24,7 @@ import com.cloud.exception.CloudAuthenticationException; public interface ApiServerService { - public boolean verifyRequest(Map<String, Object[]> requestParameters, Long userId) throws ServerApiException; + public boolean verifyRequest(Map<String, Object[]> requestParameters, Long userId, InetAddress remoteAddress) throws ServerApiException; public Long fetchDomainId(String domainUUID); diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java index 1f14abf4a5a..9299c3ddd2c 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateEgressFirewallRuleCmd.java @@ -246,10 +246,10 @@ public void create() { String guestCidr = _networkService.getNetwork(getNetworkId()).getCidr(); for (String cidr : getSourceCidrList()) { - if (!NetUtils.isValidCIDR(cidr)) { + if (!NetUtils.isValidIp4Cidr(cidr) && !NetUtils.isValidIp6Cidr(cidr)) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Source cidrs formatting error " + cidr); } - if (cidr.equals(NetUtils.ALL_CIDRS)) { + if (cidr.equals(NetUtils.ALL_IP4_CIDRS)) { continue; } if (!NetUtils.isNetworkAWithinNetworkB(cidr, guestCidr)) { @@ -261,7 +261,7 @@ public void create() { //Destination CIDR formatting check. Since it's optional param, no need to set a default as in the case of source. if(destCidrList != null){ for(String cidr : destCidrList){ - if(!NetUtils.isValidCIDR(cidr)) { + if(!NetUtils.isValidIp4Cidr(cidr) && !NetUtils.isValidIp6Cidr(cidr)) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Destination cidrs formatting error" + cidr); } } diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java index 548b81447fe..fab7d9eef29 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java @@ -108,7 +108,7 @@ public String getProtocol() { return cidrlist; } else { List<String> oneCidrList = new ArrayList<String>(); - oneCidrList.add(NetUtils.ALL_CIDRS); + oneCidrList.add(NetUtils.ALL_IP4_CIDRS); return oneCidrList; } @@ -242,7 +242,7 @@ public long getDomainId() { public void create() { if (getSourceCidrList() != null) { for (String cidr : getSourceCidrList()) { - if (!NetUtils.isValidCIDR(cidr)) { + if (!NetUtils.isValidIp4Cidr(cidr) && !NetUtils.isValidIp6Cidr(cidr)) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Source CIDRs formatting error " + cidr); } } diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java index 69360608df1..ea0cb00301a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java @@ -348,7 +348,7 @@ public void create() { Ip privateIp = getVmSecondaryIp(); if (privateIp != null) { - if (!NetUtils.isValidIp(privateIp.toString())) { + if (!NetUtils.isValidIp4(privateIp.toString())) { throw new InvalidParameterValueException("Invalid vm ip address"); } } diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java index fdc8a31c59a..1e730370801 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignToLoadBalancerRuleCmd.java @@ -140,7 +140,7 @@ public String getEventDescription() { } //check wether the given ip is valid ip or not - if (vmIp == null || !NetUtils.isValidIp(vmIp)) { + if (vmIp == null || !NetUtils.isValidIp4(vmIp)) { throw new InvalidParameterValueException("Invalid ip address "+ vmIp +" passed in vmidipmap for " + "vmid " + vmId); } diff --git a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java index c8a8f8cae39..4b6a836f32a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/CreateNetworkACLCmd.java @@ -134,7 +134,7 @@ public String getProtocol() { return cidrlist; } else { List<String> oneCidrList = new ArrayList<String>(); - oneCidrList.add(NetUtils.ALL_CIDRS); + oneCidrList.add(NetUtils.ALL_IP4_CIDRS); return oneCidrList; } } diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java index 4b805acc396..41481c8ff54 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java @@ -173,7 +173,7 @@ public void create() throws ResourceAllocationException { NicSecondaryIp result; String secondaryIp = null; if ((ip = getIpaddress()) != null) { - if (!NetUtils.isValidIp(ip)) { + if (!NetUtils.isValidIp4(ip)) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip); } } diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java index c6fbedbf631..83fe72e7043 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVmNicIpCmd.java @@ -150,7 +150,7 @@ public void execute() throws ResourceUnavailableException, ResourceAllocationExc CallContext.current().setEventDetails("Nic Id: " + getNicId() ); String ip; if ((ip = getIpaddress()) != null) { - if (!NetUtils.isValidIp(ip)) { + if (!NetUtils.isValidIp4(ip)) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Invalid ip address " + ip); } } diff --git a/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java b/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java index d5df8c34219..485688a3769 100644 --- a/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java +++ b/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java @@ -25,7 +25,10 @@ "API end point. Can be used by CS components/services deployed remotely, for sending CS API requests", true); public static final ConfigKey<Long> DefaultUIPageSize = new ConfigKey<Long>("Advanced", Long.class, "default.ui.page.size", "20", "The default pagesize to be used by UI and other clients when making list* API calls", true, ConfigKey.Scope.Global); - + public static final ConfigKey<Boolean> ApiSourceCidrChecksEnabled = new ConfigKey<>("Advanced", Boolean.class, "api.source.cidr.checks.enabled", + "true", "Are the source checks on API calls enabled (true) or not (false)? See api.allowed.source.cidr.list", true, ConfigKey.Scope.Global); + public static final ConfigKey<String> ApiAllowedSourceCidrList = new ConfigKey<String>("Advanced", String.class, "api.allowed.source.cidr.list", + "0.0.0.0/0,::/0", "Comma separated list of IPv4/IPv6 CIDRs from which API calls can be performed. Can be set on Global and Account levels.", true, ConfigKey.Scope.Account); @Override public String getConfigComponentName() { return ApiServiceConfiguration.class.getSimpleName(); @@ -33,7 +36,7 @@ public String getConfigComponentName() { @Override public ConfigKey<?>[] getConfigKeys() { - return new ConfigKey<?>[] {ManagementHostIPAdr, ApiServletPath, DefaultUIPageSize}; + return new ConfigKey<?>[] {ManagementHostIPAdr, ApiServletPath, DefaultUIPageSize, ApiSourceCidrChecksEnabled, ApiAllowedSourceCidrList}; } } diff --git a/core/src/com/cloud/network/HAProxyConfigurator.java b/core/src/com/cloud/network/HAProxyConfigurator.java index 3b5f23faac1..7bf3bb8ca57 100644 --- a/core/src/com/cloud/network/HAProxyConfigurator.java +++ b/core/src/com/cloud/network/HAProxyConfigurator.java @@ -94,7 +94,7 @@ private List<String> getRulesForPool(final String poolName, final List<PortForwardingRuleTO> fwRules) { final PortForwardingRuleTO firstRule = fwRules.get(0); final String publicIP = firstRule.getSrcIp(); - final String publicPort = Integer.toString(firstRule.getSrcPortRange()[0]); + final int publicPort = firstRule.getSrcPortRange()[0]; // FIXEME: String algorithm = firstRule.getAlgorithm(); final List<String> result = new ArrayList<String>(); @@ -108,9 +108,7 @@ sb = new StringBuilder(); // FIXME sb.append("\t").append("balance ").append(algorithm); result.add(sb.toString()); - if (publicPort.equals(NetUtils.HTTP_PORT) - // && global option httpclose set (or maybe not in this spot???) - ) { + if (publicPort == NetUtils.HTTP_PORT) { sb = new StringBuilder(); sb.append("\t").append("mode http"); result.add(sb.toString()); @@ -473,7 +471,7 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) { StringBuilder sb = new StringBuilder(); final String poolName = sb.append(lbTO.getSrcIp().replace(".", "_")).append('-').append(lbTO.getSrcPort()).toString(); final String publicIP = lbTO.getSrcIp(); - final String publicPort = Integer.toString(lbTO.getSrcPort()); + final int publicPort = lbTO.getSrcPort(); final String algorithm = lbTO.getAlgorithm(); final List<String> result = new ArrayList<String>(); @@ -544,7 +542,7 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) { if (stickinessSubRule != null && !destsAvailable) { s_logger.warn("Haproxy stickiness policy for lb rule: " + lbTO.getSrcIp() + ":" + lbTO.getSrcPort() + ": Not Applied, cause: backends are unavailable"); } - if (publicPort.equals(NetUtils.HTTP_PORT) && !keepAliveEnabled || httpbasedStickiness) { + if (publicPort == NetUtils.HTTP_PORT && !keepAliveEnabled || httpbasedStickiness) { sb = new StringBuilder(); sb.append("\t").append("mode http"); result.add(sb.toString()); diff --git a/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapAppender.java b/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapAppender.java index 3579e245c18..0c9fcf9f68c 100644 --- a/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapAppender.java +++ b/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapAppender.java @@ -161,7 +161,7 @@ private boolean validateIpAddresses() { if (ipAddress.trim().equalsIgnoreCase("localhost")) { continue; } - if (!NetUtils.isValidIp(ipAddress)) { + if (!NetUtils.isValidIp4(ipAddress)) { return false; } } diff --git a/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java b/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java index 7324c200882..b73da2fd421 100644 --- a/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java +++ b/plugins/alert-handlers/syslog-alerts/src/org/apache/cloudstack/syslog/AlertsSyslogAppender.java @@ -168,7 +168,7 @@ private boolean validateIpAddresses() { if (ip.equalsIgnoreCase("localhost")) { continue; } - if (!NetUtils.isValidIp(ip)) { + if (!NetUtils.isValidIp4(ip)) { return false; } } else diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmIpAddressCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmIpAddressCommandWrapper.java index 1545214781c..1d3a60b75e3 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmIpAddressCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmIpAddressCommandWrapper.java @@ -49,7 +49,7 @@ public Answer execute(final GetVmIpAddressCommand command, final LibvirtComputin String ipAddr = Script.runSimpleBashScript(new StringBuilder().append("virt-cat ").append(command.getVmName()) .append(" /var/lib/dhclient/" + leaseFile + " | tail -16 | grep 'fixed-address' | awk '{print $2}' | sed -e 's/;//'").toString()); // Check if the IP belongs to the network - if((ipAddr != null) && NetUtils.isIpWithtInCidrRange(ipAddr, networkCidr)){ + if((ipAddr != null) && NetUtils.isIpWithInCidrRange(ipAddr, networkCidr)){ ip = ipAddr; break; } @@ -65,7 +65,7 @@ public Answer execute(final GetVmIpAddressCommand command, final LibvirtComputin String[] ips = ipList.split("\n"); for (String ipAddr : ips){ // Check if the IP belongs to the network - if((ipAddr != null) && NetUtils.isIpWithtInCidrRange(ipAddr, networkCidr)){ + if((ipAddr != null) && NetUtils.isIpWithInCidrRange(ipAddr, networkCidr)){ ip = ipAddr; break; } diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3Configuration.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3Configuration.java index 6775a146aeb..ba31236a7a8 100644 --- a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3Configuration.java +++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3Configuration.java @@ -130,7 +130,7 @@ private void validatePoolAndCluster() { LOGGER.debug("Clustering requires a pool, setting pool to true"); agentInOvm3Pool = true; } - if (!NetUtils.isValidIp(ovm3PoolVip)) { + if (!NetUtils.isValidIp4(ovm3PoolVip)) { LOGGER.debug("No VIP, Setting ovm3pool and ovm3cluster to false"); agentInOvm3Pool = false; agentInOvm3Cluster = false; diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmIpAddressCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmIpAddressCommandWrapper.java index dd1ee28de31..e425fa70c84 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmIpAddressCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmIpAddressCommandWrapper.java @@ -56,7 +56,7 @@ public Answer execute(final GetVmIpAddressCommand command, final CitrixResourceB Map<String, String> vmIpsMap = rec.networks; for (String ipAddr: vmIpsMap.values()) { - if (NetUtils.isIpWithtInCidrRange(ipAddr, networkCidr)) { + if (NetUtils.isIpWithInCidrRange(ipAddr, networkCidr)) { vmIp = ipAddr; break; } diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java index 15fbdebe50d..f93aaaf96f2 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java @@ -2574,7 +2574,7 @@ private void deleteServersInGuestVlan(final long vlanTag, final String vlanSelfI } private String getNetScalerProtocol(final LoadBalancerTO loadBalancer) throws ExecutionException { - final String port = Integer.toString(loadBalancer.getSrcPort()); + final int port = loadBalancer.getSrcPort(); String lbProtocol = loadBalancer.getLbProtocol(); final StickinessPolicyTO[] stickyPolicies = loadBalancer.getStickinessPolicies(); String nsProtocol = "TCP"; @@ -2596,7 +2596,7 @@ private String getNetScalerProtocol(final LoadBalancerTO loadBalancer) throws Ex return lbProtocol.toUpperCase(); } - if (port.equals(NetUtils.HTTP_PORT)) { + if (port == NetUtils.HTTP_PORT) { nsProtocol = "HTTP"; } else if (NetUtils.TCP_PROTO.equalsIgnoreCase(lbProtocol)) { nsProtocol = "TCP"; diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 9e237741c96..d9671e9b4b7 100644 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -46,6 +46,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.ReflectUtil; import com.cloud.utils.StringUtils; +import com.cloud.utils.net.NetUtils; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.component.PluggableService; @@ -97,6 +98,7 @@ import org.apache.cloudstack.api.response.ExceptionResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.LoginCmdResponse; +import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; @@ -795,7 +797,7 @@ private void buildAuditTrail(final StringBuilder auditTrailSb, final String comm } @Override - public boolean verifyRequest(final Map<String, Object[]> requestParameters, final Long userId) throws ServerApiException { + public boolean verifyRequest(final Map<String, Object[]> requestParameters, final Long userId, InetAddress remoteAddress) throws ServerApiException { try { String apiKey = null; String secretKey = null; @@ -814,21 +816,18 @@ public boolean verifyRequest(final Map<String, Object[]> requestParameters, fina if (userId != null) { final User user = ApiDBUtils.findUserById(userId); - try { - checkCommandAvailable(user, commandName); - } catch (final RequestLimitException ex) { - s_logger.debug(ex.getMessage()); - throw new ServerApiException(ApiErrorCode.API_LIMIT_EXCEED, ex.getMessage()); - } catch (final PermissionDeniedException ex) { - s_logger.debug("The user with id:" + userId + " is not allowed to request the API command or the API command does not exist: " + commandName); - throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The user is not allowed to request the API command or the API command does not exist"); + if (!commandAvailable(remoteAddress, commandName, user)) { + return false; } + return true; } else { // check against every available command to see if the command exists or not if (!s_apiNameCmdClassMap.containsKey(commandName) && !commandName.equals("login") && !commandName.equals("logout")) { - s_logger.debug("The user with id:" + userId + " is not allowed to request the API command or the API command does not exist: " + commandName); - throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The user is not allowed to request the API command or the API command does not exist"); + final String errorMessage = "The given command " + commandName + " either does not exist, is not available" + + " for user, or not available from ip address '" + remoteAddress.getHostAddress() + "'."; + s_logger.debug(errorMessage); + return false; } } @@ -916,15 +915,8 @@ public boolean verifyRequest(final Map<String, Object[]> requestParameters, fina return false; } - try { - checkCommandAvailable(user, commandName); - } catch (final RequestLimitException ex) { - s_logger.debug(ex.getMessage()); - throw new ServerApiException(ApiErrorCode.API_LIMIT_EXCEED, ex.getMessage()); - } catch (final PermissionDeniedException ex) { - s_logger.debug("The given command:" + commandName + " does not exist or it is not available for user"); - throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, "The given command:" + commandName + " does not exist or it is not available for user with id:" - + userId); + if (!commandAvailable(remoteAddress, commandName, user)) { + return false; } // verify secret key exists @@ -959,6 +951,21 @@ public boolean verifyRequest(final Map<String, Object[]> requestParameters, fina return false; } + private boolean commandAvailable(final InetAddress remoteAddress, final String commandName, final User user) { + try { + checkCommandAvailable(user, commandName, remoteAddress); + } catch (final RequestLimitException ex) { + s_logger.debug(ex.getMessage()); + throw new ServerApiException(ApiErrorCode.API_LIMIT_EXCEED, ex.getMessage()); + } catch (final PermissionDeniedException ex) { + final String errorMessage = "The given command '" + commandName + "' either does not exist, is not available" + + " for user, or not available from ip address '" + remoteAddress + "'."; + s_logger.debug(errorMessage); + return false; + } + return true; + } + @Override public Long fetchDomainId(final String domainUUID) { final Domain domain = domainMgr.getDomain(domainUUID); @@ -1113,11 +1120,24 @@ public boolean verifyUser(final Long userId) { return true; } - private void checkCommandAvailable(final User user, final String commandName) throws PermissionDeniedException { + private void checkCommandAvailable(final User user, final String commandName, final InetAddress remoteAddress) throws PermissionDeniedException { if (user == null) { throw new PermissionDeniedException("User is null for role based API access check for command" + commandName); } + final Account account = accountMgr.getAccount(user.getAccountId()); + final String accessAllowedCidrs = ApiServiceConfiguration.ApiAllowedSourceCidrList.valueIn(account.getId()).replaceAll("\\s",""); + final Boolean apiSourceCidrChecksEnabled = ApiServiceConfiguration.ApiSourceCidrChecksEnabled.value(); + + if (apiSourceCidrChecksEnabled) { + s_logger.debug("CIDRs from which account '" + account.toString() + "' is allowed to perform API calls: " + accessAllowedCidrs); + if (!NetUtils.isIpInCidrList(remoteAddress, accessAllowedCidrs.split(","))) { + s_logger.warn("Request by account '" + account.toString() + "' was denied since " + remoteAddress + " does not match " + accessAllowedCidrs); + throw new PermissionDeniedException("Calls for domain '" + account.getAccountName() + "' are not allowed from ip address '" + remoteAddress.getHostAddress()); + } + } + + for (final APIChecker apiChecker : apiAccessCheckers) { apiChecker.checkAccess(user, commandName); } diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 7a607fde773..4002ff8d99b 100644 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -19,6 +19,7 @@ import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.URLDecoder; +import java.net.UnknownHostException; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -132,9 +133,21 @@ public void run() { } void processRequestInContext(final HttpServletRequest req, final HttpServletResponse resp) { - final String remoteAddress = getClientAddress(req); + InetAddress remoteAddress = null; + try { + remoteAddress = getClientAddress(req); + } catch (UnknownHostException e) { + s_logger.warn("UnknownHostException when trying to lookup remote IP-Address. This should never happen. Blocking request.", e); + final String response = apiServer.getSerializedApiError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "UnknownHostException when trying to lookup remote IP-Address", null, + HttpUtils.RESPONSE_TYPE_XML); + HttpUtils.writeHttpResponse(resp, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + HttpUtils.RESPONSE_TYPE_XML, ApiServer.JSONcontentType.value()); + return; + } + final StringBuilder auditTrailSb = new StringBuilder(128); - auditTrailSb.append(" ").append(remoteAddress); + auditTrailSb.append(" ").append(remoteAddress.getHostAddress()); auditTrailSb.append(" -- ").append(req.getMethod()).append(' '); // get the response format since we'll need it in a couple of places String responseType = HttpUtils.RESPONSE_TYPE_XML; @@ -198,7 +211,7 @@ void processRequestInContext(final HttpServletRequest req, final HttpServletResp } try { - responseString = apiAuthenticator.authenticate(command, params, session, InetAddress.getByName(remoteAddress), responseType, auditTrailSb, req, resp); + responseString = apiAuthenticator.authenticate(command, params, session, remoteAddress, responseType, auditTrailSb, req, resp); if (session != null && session.getAttribute(ApiConstants.SESSIONKEY) != null) { resp.addHeader("SET-COOKIE", String.format("%s=%s;HttpOnly", ApiConstants.SESSIONKEY, session.getAttribute(ApiConstants.SESSIONKEY))); } @@ -288,12 +301,12 @@ void processRequestInContext(final HttpServletRequest req, final HttpServletResp CallContext.register(accountMgr.getSystemUser(), accountMgr.getSystemAccount()); } - if (apiServer.verifyRequest(params, userId)) { + if (apiServer.verifyRequest(params, userId, remoteAddress)) { auditTrailSb.insert(0, "(userId=" + CallContext.current().getCallingUserId() + " accountId=" + CallContext.current().getCallingAccount().getId() + " sessionId=" + (session != null ? session.getId() : null) + ")"); // Add the HTTP method (GET/POST/PUT/DELETE) as well into the params map. - params.put("httpmethod", new String[] {req.getMethod()}); + params.put("httpmethod", new String[]{req.getMethod()}); final String response = apiServer.handleRequest(params, responseType, auditTrailSb); HttpUtils.writeHttpResponse(resp, response != null ? response : "", HttpServletResponse.SC_OK, responseType, ApiServer.JSONcontentType.value()); } else { @@ -330,29 +343,29 @@ void processRequestInContext(final HttpServletRequest req, final HttpServletResp } //This method will try to get login IP of user even if servlet is behind reverseProxy or loadBalancer - static String getClientAddress(final HttpServletRequest request) { + static InetAddress getClientAddress(final HttpServletRequest request) throws UnknownHostException { for(final String header : s_clientAddressHeaders) { final String ip = getCorrectIPAddress(request.getHeader(header)); if (ip != null) { - return ip; + return InetAddress.getByName(ip); } } - return request.getRemoteAddr(); + return InetAddress.getByName(request.getRemoteAddr()); } private static String getCorrectIPAddress(String ip) { if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { return null; } - if(NetUtils.isValidIp(ip) || NetUtils.isValidIpv6(ip)) { + if(NetUtils.isValidIp4(ip) || NetUtils.isValidIp6(ip)) { return ip; } //it could be possible to have multiple IPs in HTTP header, this happens if there are multiple proxy in between //the client and the servlet, so parse the client IP String[] ips = ip.split(","); for(String i : ips) { - if(NetUtils.isValidIp(i.trim()) || NetUtils.isValidIpv6(i.trim())) { + if(NetUtils.isValidIp4(i.trim()) || NetUtils.isValidIp6(i.trim())) { return i.trim(); } } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index dfc7c372d48..9cbe30597a9 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -872,7 +872,7 @@ private String validateConfigurationValue(final String name, String value, final throw new InvalidParameterValueException("Error parsing ip address"); } } else if (range.equals("netmask")) { - if (!NetUtils.isValidNetmask(value)) { + if (!NetUtils.isValidIp4Netmask(value)) { s_logger.error("netmask " + value + " is not a valid net mask for configuration variable " + name); return "Please enter a valid netmask."; } @@ -904,7 +904,7 @@ private String validateConfigurationValue(final String name, String value, final for (final String route : routes) { if (route != null) { final String routeToVerify = route.trim(); - if (!NetUtils.isValidCIDR(routeToVerify)) { + if (!NetUtils.isValidIp4Cidr(routeToVerify)) { throw new InvalidParameterValueException("Invalid value for blacklisted route: " + route + ". Valid format is list" + " of cidrs separated by coma. Example: 10.1.1.0/24,192.168.0.0/24"); } @@ -989,7 +989,7 @@ private void checkPodAttributes(final long podId, final String podName, final lo long cidrSize; // Get the individual cidrAddress and cidrSize values, if the CIDR is // valid. If it's not valid, return an error. - if (NetUtils.isValidCIDR(cidr)) { + if (NetUtils.isValidIp4Cidr(cidr)) { cidrAddress = getCidrAddress(cidr); cidrSize = getCidrSize(cidr); } else { @@ -1005,7 +1005,7 @@ private void checkPodAttributes(final long podId, final String podName, final lo } // Check if the gateway is a valid IP address - if (!NetUtils.isValidIp(gateway)) { + if (!NetUtils.isValidIp4(gateway)) { throw new InvalidParameterValueException("The gateway is not a valid IP address."); } @@ -1119,11 +1119,11 @@ public Pod createPodIpRange(final CreateManagementNetworkIpRangeCmd cmd) { final long zoneId = pod.getDataCenterId(); - if(!NetUtils.isValidIp(gateway)) { + if(!NetUtils.isValidIp4(gateway)) { throw new InvalidParameterValueException("The gateway IP address is invalid."); } - if(!NetUtils.isValidNetmask(netmask)) { + if(!NetUtils.isValidIp4Netmask(netmask)) { throw new InvalidParameterValueException("The netmask IP address is invalid."); } @@ -1133,7 +1133,7 @@ public Pod createPodIpRange(final CreateManagementNetworkIpRangeCmd cmd) { final String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask); - if(!NetUtils.isValidCIDR(cidr)) { + if(!NetUtils.isValidIp4Cidr(cidr)) { throw new InvalidParameterValueException("The CIDR is invalid " + cidr); } @@ -1170,7 +1170,7 @@ public Pod createPodIpRange(final CreateManagementNetworkIpRangeCmd cmd) { final String[] existingPodIpRange = podIpRange.split("-"); if (existingPodIpRange.length > 1) { - if (!NetUtils.isValidIp(existingPodIpRange[0]) || !NetUtils.isValidIp(existingPodIpRange[1])) { + if (!NetUtils.isValidIp4(existingPodIpRange[0]) || !NetUtils.isValidIp4(existingPodIpRange[1])) { continue; } // Check if the range overlaps with any existing range. @@ -1236,11 +1236,11 @@ public void deletePodIpRange(final DeleteManagementNetworkIpRangeCmd cmd) throws throw new InvalidParameterValueException("Unable to find pod by id " + podId); } - if (startIp == null || !NetUtils.isValidIp(startIp)) { + if (startIp == null || !NetUtils.isValidIp4(startIp)) { throw new InvalidParameterValueException("The start address of the IP range is not a valid IP address."); } - if (endIp == null || !NetUtils.isValidIp(endIp)) { + if (endIp == null || !NetUtils.isValidIp4(endIp)) { throw new InvalidParameterValueException("The end address of the IP range is not a valid IP address."); } @@ -1390,7 +1390,7 @@ public Pod editPod(final long id, String name, String startIp, String endIp, Str final String[] existingPodIpRange = podIpRange.split("-"); if (existingPodIpRange.length > 1) { - if (!NetUtils.isValidIp(existingPodIpRange[0]) || !NetUtils.isValidIp(existingPodIpRange[1])) { + if (!NetUtils.isValidIp4(existingPodIpRange[0]) || !NetUtils.isValidIp4(existingPodIpRange[1])) { continue; } @@ -1443,11 +1443,11 @@ public void doInTransactionWithoutResult(final TransactionStatus status) { @Override public Pod createPod(final long zoneId, final String name, final String startIp, final String endIp, final String gateway, final String netmask, String allocationState) { // Check if the gateway is a valid IP address - if (!NetUtils.isValidIp(gateway)) { + if (!NetUtils.isValidIp4(gateway)) { throw new InvalidParameterValueException("The gateway is invalid"); } - if (!NetUtils.isValidNetmask(netmask)) { + if (!NetUtils.isValidIp4Netmask(netmask)) { throw new InvalidParameterValueException("The netmask is invalid"); } @@ -1601,27 +1601,27 @@ private void checkZoneParameters(final String zoneName, final String dns1, final // Check IP validity for DNS addresses // Empty strings is a valid input -- hence the length check - if (dns1 != null && dns1.length() > 0 && !NetUtils.isValidIp(dns1)) { + if (dns1 != null && dns1.length() > 0 && !NetUtils.isValidIp4(dns1)) { throw new InvalidParameterValueException("Please enter a valid IP address for DNS1"); } - if (dns2 != null && dns2.length() > 0 && !NetUtils.isValidIp(dns2)) { + if (dns2 != null && dns2.length() > 0 && !NetUtils.isValidIp4(dns2)) { throw new InvalidParameterValueException("Please enter a valid IP address for DNS2"); } - if (internalDns1 != null && internalDns1.length() > 0 && !NetUtils.isValidIp(internalDns1)) { + if (internalDns1 != null && internalDns1.length() > 0 && !NetUtils.isValidIp4(internalDns1)) { throw new InvalidParameterValueException("Please enter a valid IP address for internal DNS1"); } - if (internalDns2 != null && internalDns2.length() > 0 && !NetUtils.isValidIp(internalDns2)) { + if (internalDns2 != null && internalDns2.length() > 0 && !NetUtils.isValidIp4(internalDns2)) { throw new InvalidParameterValueException("Please enter a valid IP address for internal DNS2"); } - if (ip6Dns1 != null && ip6Dns1.length() > 0 && !NetUtils.isValidIpv6(ip6Dns1)) { + if (ip6Dns1 != null && ip6Dns1.length() > 0 && !NetUtils.isValidIp6(ip6Dns1)) { throw new InvalidParameterValueException("Please enter a valid IPv6 address for IP6 DNS1"); } - if (ip6Dns2 != null && ip6Dns2.length() > 0 && !NetUtils.isValidIpv6(ip6Dns2)) { + if (ip6Dns2 != null && ip6Dns2.length() > 0 && !NetUtils.isValidIp6(ip6Dns2)) { throw new InvalidParameterValueException("Please enter a valid IPv6 address for IP6 DNS2"); } @@ -1637,11 +1637,11 @@ private void checkZoneParameters(final String zoneName, final String dns1, final private void checkIpRange(final String startIp, final String endIp, final String cidrAddress, final long cidrSize) { //Checking not null for start IP as well. Previously we assumed to be not null always. //But the check is required for the change in updatePod API. - if (!Strings.isNullOrEmpty(startIp) && !NetUtils.isValidIp(startIp)) { + if (!Strings.isNullOrEmpty(startIp) && !NetUtils.isValidIp4(startIp)) { throw new InvalidParameterValueException("The start address of the IP range is not a valid IP address."); } - if (!Strings.isNullOrEmpty(endIp) && !NetUtils.isValidIp(endIp)) { + if (!Strings.isNullOrEmpty(endIp) && !NetUtils.isValidIp4(endIp)) { throw new InvalidParameterValueException("The end address of the IP range is not a valid IP address."); } @@ -1683,7 +1683,7 @@ private void checkOverlapPrivateIpRange(final Long zoneId, final String startIp, final String[] existingPodIpRange = podIpRange.split("-"); if (existingPodIpRange.length > 1) { - if (!NetUtils.isValidIp(existingPodIpRange[0]) || !NetUtils.isValidIp(existingPodIpRange[1])) { + if (!NetUtils.isValidIp4(existingPodIpRange[0]) || !NetUtils.isValidIp4(existingPodIpRange[1])) { continue; } @@ -3299,18 +3299,18 @@ public Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId, if (ipv4) { // Make sure the gateway is valid - if (!NetUtils.isValidIp(vlanGateway)) { + if (!NetUtils.isValidIp4(vlanGateway)) { throw new InvalidParameterValueException("Please specify a valid gateway"); } // Make sure the netmask is valid - if (!NetUtils.isValidNetmask(vlanNetmask)) { + if (!NetUtils.isValidIp4Netmask(vlanNetmask)) { throw new InvalidParameterValueException("Please specify a valid netmask"); } } if (ipv6) { - if (!NetUtils.isValidIpv6(vlanIp6Gateway)) { + if (!NetUtils.isValidIp6(vlanIp6Gateway)) { throw new InvalidParameterValueException("Please specify a valid IPv6 gateway"); } if (!NetUtils.isValidIp6Cidr(vlanIp6Cidr)) { @@ -3322,7 +3322,7 @@ public Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId, final String newCidr = NetUtils.getCidrFromGatewayAndNetmask(vlanGateway, vlanNetmask); //Make sure start and end ips are with in the range of cidr calculated for this gateway and netmask { - if (!NetUtils.isIpWithtInCidrRange(vlanGateway, newCidr) || !NetUtils.isIpWithtInCidrRange(startIP, newCidr) || !NetUtils.isIpWithtInCidrRange(endIP, newCidr)) { + if (!NetUtils.isIpWithInCidrRange(vlanGateway, newCidr) || !NetUtils.isIpWithInCidrRange(startIP, newCidr) || !NetUtils.isIpWithInCidrRange(endIP, newCidr)) { throw new InvalidParameterValueException("Please specify a valid IP range or valid netmask or valid gateway"); } @@ -3819,11 +3819,11 @@ protected boolean savePublicIPRange(final String startIP, final String endIP, fi private void checkPublicIpRangeErrors(final long zoneId, final String vlanId, final String vlanGateway, final String vlanNetmask, final String startIP, final String endIP) { // Check that the start and end IPs are valid - if (!NetUtils.isValidIp(startIP)) { + if (!NetUtils.isValidIp4(startIP)) { throw new InvalidParameterValueException("Please specify a valid start IP"); } - if (endIP != null && !NetUtils.isValidIp(endIP)) { + if (endIP != null && !NetUtils.isValidIp4(endIP)) { throw new InvalidParameterValueException("Please specify a valid end IP"); } @@ -5422,7 +5422,7 @@ public PortableIpRange createPortableIpRange(final CreatePortableIpRangeCmd cmd) throw new InvalidParameterValueException("Invalid region ID: " + regionId); } - if (!NetUtils.isValidIp(startIP) || !NetUtils.isValidIp(endIP) || !NetUtils.validIpRange(startIP, endIP)) { + if (!NetUtils.isValidIp4(startIP) || !NetUtils.isValidIp4(endIP) || !NetUtils.validIpRange(startIP, endIP)) { throw new InvalidParameterValueException("Invalid portable ip range: " + startIP + "-" + endIP); } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index cee07455d3a..28fff3c7219 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -1395,7 +1395,7 @@ public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, Depl if (nic.getTrafficType() == TrafficType.Management) { String mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key()); - if (NetUtils.isValidCIDR(mgmt_cidr)) { + if (NetUtils.isValidIp4Cidr(mgmt_cidr)) { buf.append(" mgmtcidr=").append(mgmt_cidr); } buf.append(" localgw=").append(dest.getPod().getGateway()); diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index 0495a350d3d..efa9ffbde6b 100644 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -2148,10 +2148,10 @@ public boolean isNetworkInlineMode(Network network) { @Override public void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gateway, String ip6Cidr) throws InvalidParameterValueException { - if (!NetUtils.isValidIpv6(startIPv6)) { + if (!NetUtils.isValidIp6(startIPv6)) { throw new InvalidParameterValueException("Invalid format for the startIPv6 parameter"); } - if (!NetUtils.isValidIpv6(endIPv6)) { + if (!NetUtils.isValidIp6(endIPv6)) { throw new InvalidParameterValueException("Invalid format for the endIPv6 parameter"); } @@ -2159,7 +2159,7 @@ public void checkIp6Parameters(String startIPv6, String endIPv6, String ip6Gatew throw new InvalidParameterValueException("ip6Gateway and ip6Cidr should be defined when startIPv6/endIPv6 are passed in"); } - if (!NetUtils.isValidIpv6(ip6Gateway)) { + if (!NetUtils.isValidIp6(ip6Gateway)) { throw new InvalidParameterValueException("Invalid ip6Gateway"); } if (!NetUtils.isValidIp6Cidr(ip6Cidr)) { @@ -2188,13 +2188,13 @@ public void checkRequestedIpAddresses(long networkId, IpAddresses ips) throws In String ip6 = ips.getIp6Address(); String mac = ips.getMacAddress(); if (ip4 != null) { - if (!NetUtils.isValidIp(ip4)) { + if (!NetUtils.isValidIp4(ip4)) { throw new InvalidParameterValueException("Invalid specified IPv4 address " + ip4); } //Other checks for ipv4 are done in assignPublicIpAddress() } if (ip6 != null) { - if (!NetUtils.isValidIpv6(ip6)) { + if (!NetUtils.isValidIp6(ip6)) { throw new InvalidParameterValueException("Invalid specified IPv6 address " + ip6); } if (_ipv6Dao.findByNetworkIdAndIp(networkId, ip6) != null) { diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 81ab2b141e1..6b431f43a7e 100644 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -1169,12 +1169,12 @@ public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac if (ipv4) { // if end ip is not specified, default it to startIp if (startIP != null) { - if (!NetUtils.isValidIp(startIP)) { + if (!NetUtils.isValidIp4(startIP)) { throw new InvalidParameterValueException("Invalid format for the startIp parameter"); } if (endIP == null) { endIP = startIP; - } else if (!NetUtils.isValidIp(endIP)) { + } else if (!NetUtils.isValidIp4(endIP)) { throw new InvalidParameterValueException("Invalid format for the endIp parameter"); } } @@ -1193,10 +1193,10 @@ public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapac throw new InvalidParameterValueException("Invalid gateway IP provided. Either the IP is broadcast or network IP."); } - if (!NetUtils.isValidIp(gateway)) { + if (!NetUtils.isValidIp4(gateway)) { throw new InvalidParameterValueException("Invalid gateway"); } - if (!NetUtils.isValidNetmask(netmask)) { + if (!NetUtils.isValidIp4Netmask(netmask)) { throw new InvalidParameterValueException("Invalid netmask"); } @@ -2129,7 +2129,7 @@ public Network updateGuestNetwork(final long networkId, String name, String disp throw new InvalidParameterValueException("The network must be in " + Network.State.Implemented + " state. IP Reservation cannot be applied in " + network.getState() + " state"); } - if (!NetUtils.isValidCIDR(guestVmCidr)) { + if (!NetUtils.isValidIp4Cidr(guestVmCidr)) { throw new InvalidParameterValueException("Invalid format of Guest VM CIDR."); } if (!NetUtils.validateGuestCidr(guestVmCidr)) { @@ -4296,19 +4296,19 @@ public Network createPrivateNetwork(final String networkName, final String displ // VALIDATE IP INFO // if end ip is not specified, default it to startIp - if (!NetUtils.isValidIp(startIp)) { + if (!NetUtils.isValidIp4(startIp)) { throw new InvalidParameterValueException("Invalid format for the ip address parameter"); } if (endIp == null) { endIp = startIp; - } else if (!NetUtils.isValidIp(endIp)) { + } else if (!NetUtils.isValidIp4(endIp)) { throw new InvalidParameterValueException("Invalid format for the endIp address parameter"); } - if (!NetUtils.isValidIp(gateway)) { + if (!NetUtils.isValidIp4(gateway)) { throw new InvalidParameterValueException("Invalid gateway"); } - if (!NetUtils.isValidNetmask(netmask)) { + if (!NetUtils.isValidIp4Netmask(netmask)) { throw new InvalidParameterValueException("Invalid netmask"); } diff --git a/server/src/com/cloud/network/StorageNetworkManagerImpl.java b/server/src/com/cloud/network/StorageNetworkManagerImpl.java index 020f7b1b044..ac43c11fbe2 100644 --- a/server/src/com/cloud/network/StorageNetworkManagerImpl.java +++ b/server/src/com/cloud/network/StorageNetworkManagerImpl.java @@ -84,7 +84,7 @@ private void checkOverlapPrivateIpRange(long podId, String startIp, String endIp final String[] existingPodIpRange = podIpRange.split("-"); if (existingPodIpRange.length > 1) { - if (!NetUtils.isValidIp(existingPodIpRange[0]) || !NetUtils.isValidIp(existingPodIpRange[1])) { + if (!NetUtils.isValidIp4(existingPodIpRange[0]) || !NetUtils.isValidIp4(existingPodIpRange[1])) { continue; } @@ -137,7 +137,7 @@ public StorageNetworkIpRange updateIpRange(UpdateStorageNetworkIpRangeCmd cmd) { String endIp = cmd.getEndIp(); final String netmask = cmd.getNetmask(); - if (netmask != null && !NetUtils.isValidNetmask(netmask)) { + if (netmask != null && !NetUtils.isValidIp4Netmask(netmask)) { throw new CloudRuntimeException("Invalid netmask:" + netmask); } @@ -207,7 +207,7 @@ public StorageNetworkIpRange createIpRange(final CreateStorageNetworkIpRangeCmd endIp = startIp; } - if (!NetUtils.isValidNetmask(netmask)) { + if (!NetUtils.isValidIp4Netmask(netmask)) { throw new CloudRuntimeException("Invalid netmask:" + netmask); } diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index a8f4b1714bd..cf72ff28f0c 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -704,7 +704,7 @@ public boolean applyDefaultEgressFirewallRule(Long networkId, boolean defaultPol sourceCidr.add(network.getCidr()); - destCidr.add(NetUtils.ALL_CIDRS); + destCidr.add(NetUtils.ALL_IP4_CIDRS); FirewallRuleVO ruleVO = new FirewallRuleVO(null, null, null, null, "all", networkId, network.getAccountId(), network.getDomainId(), Purpose.Firewall, sourceCidr, destCidr, null, null, null, @@ -905,7 +905,7 @@ public FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer } List<String> oneCidr = new ArrayList<String>(); - oneCidr.add(NetUtils.ALL_CIDRS); + oneCidr.add(NetUtils.ALL_IP4_CIDRS); return createFirewallRule(ipAddrId, caller, null, startPort, endPort, protocol, oneCidr, null, icmpCode, icmpType, relatedRuleId, FirewallRule.FirewallRuleType.User, networkId, FirewallRule.TrafficType.Ingress, true); } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index e0b08d1a70f..f3035d05e61 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1383,7 +1383,7 @@ public boolean finalizeVirtualMachineProfile(final VirtualMachineProfile profile // networking setup, DomR may have two interfaces while both // are on the same subnet _mgmtCidr = _configDao.getValue(Config.ManagementNetwork.key()); - if (NetUtils.isValidCIDR(_mgmtCidr)) { + if (NetUtils.isValidIp4Cidr(_mgmtCidr)) { buf.append(" mgmtcidr=").append(_mgmtCidr); buf.append(" localgw=").append(dest.getPod().getGateway()); } @@ -1955,7 +1955,7 @@ private void createDefaultEgressFirewallRule(final List<FirewallRule> rules, fin final List<String> destCidr = new ArrayList<String>(); sourceCidr.add(network.getCidr()); - destCidr.add(NetUtils.ALL_CIDRS); + destCidr.add(NetUtils.ALL_IP4_CIDRS); final FirewallRule rule = new FirewallRuleVO(null, null, null, null, "all", networkId, network.getAccountId(), network.getDomainId(), Purpose.Firewall, sourceCidr, destCidr, null, null, null, FirewallRule.TrafficType.Egress, FirewallRule.FirewallRuleType.System); diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index f60395bcac4..07d7e4d1b8f 100644 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -611,7 +611,7 @@ protected void handleVmMigrated(VMInstanceVO vm) { if (cidrList != null) { for (String cidr : cidrList) { - if (!NetUtils.isValidCIDR(cidr)) { + if (!NetUtils.isValidIp4Cidr(cidr) && !NetUtils.isValidIp6Cidr(cidr)) { throw new InvalidParameterValueException("Invalid cidr " + cidr); } } diff --git a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java index 4132b606d4e..1743f5c322e 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java @@ -406,7 +406,7 @@ private void validateNetworkACLItem(final Integer portStart, final Integer portE if (sourceCidrList != null) { for (final String cidr : sourceCidrList) { - if (!NetUtils.isValidCIDR(cidr)) { + if (!NetUtils.isValidIp4Cidr(cidr)) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Source cidrs formatting error " + cidr); } } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 1f0753a9509..5622482b0b7 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -792,7 +792,7 @@ public Vpc createVpc(final long zoneId, final long vpcOffId, final long vpcOwner protected Vpc createVpc(final Boolean displayVpc, final VpcVO vpc) { final String cidr = vpc.getCidr(); // Validate CIDR - if (!NetUtils.isValidCIDR(cidr)) { + if (!NetUtils.isValidIp4Cidr(cidr)) { throw new InvalidParameterValueException("Invalid CIDR specified " + cidr); } @@ -2030,7 +2030,7 @@ public StaticRoute createStaticRoute(final long gatewayId, final String cidr) th } _accountMgr.checkAccess(caller, null, false, vpc); - if (!NetUtils.isValidCIDR(cidr)) { + if (!NetUtils.isValidIp4Cidr(cidr)) { throw new InvalidParameterValueException("Invalid format for cidr " + cidr); } diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index 491fb474109..2030a5a4ee5 100644 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -194,7 +194,7 @@ public RemoteAccessVpn createRemoteAccessVpn(final long publicIpId, String ipRan if (range.length != 2) { throw new InvalidParameterValueException("Invalid ip range"); } - if (!NetUtils.isValidIp(range[0]) || !NetUtils.isValidIp(range[1])) { + if (!NetUtils.isValidIp4(range[0]) || !NetUtils.isValidIp4(range[1])) { throw new InvalidParameterValueException("Invalid ip in range specification " + ipRange); } if (!NetUtils.validIpRange(range[0], range[1])) { @@ -271,7 +271,7 @@ private void validateRemoteAccessVpnConfiguration() throws ConfigurationExceptio if (range.length != 2) { throw new ConfigurationException("Remote Access VPN: Invalid ip range " + ipRange); } - if (!NetUtils.isValidIp(range[0]) || !NetUtils.isValidIp(range[1])) { + if (!NetUtils.isValidIp4(range[0]) || !NetUtils.isValidIp4(range[1])) { throw new ConfigurationException("Remote Access VPN: Invalid ip in range specification " + ipRange); } if (!NetUtils.validIpRange(range[0], range[1])) { diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index f188ad3545b..aebc8717485 100644 --- a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -177,7 +177,8 @@ public Site2SiteCustomerGateway createCustomerGateway(CreateVpnCustomerGatewayCm String name = cmd.getName(); String gatewayIp = cmd.getGatewayIp(); - if (!NetUtils.isValidIp(gatewayIp) && !NetUtils.verifyDomainName(gatewayIp)) { + + if (!NetUtils.isValidIp4(gatewayIp) && !NetUtils.verifyDomainName(gatewayIp)) { throw new InvalidParameterValueException("The customer gateway ip/Domain " + gatewayIp + " is invalid!"); } if (name == null) { @@ -428,7 +429,8 @@ public Site2SiteCustomerGateway updateCustomerGateway(UpdateVpnCustomerGatewayCm } String name = cmd.getName(); String gatewayIp = cmd.getGatewayIp(); - if (!NetUtils.isValidIp(gatewayIp) && !NetUtils.verifyDomainName(gatewayIp)) { + + if (!NetUtils.isValidIp4(gatewayIp) && !NetUtils.verifyDomainName(gatewayIp)) { throw new InvalidParameterValueException("The customer gateway ip/Domain " + gatewayIp + " is invalid!"); } if (name == null) { diff --git a/server/src/com/cloud/test/PodZoneConfig.java b/server/src/com/cloud/test/PodZoneConfig.java index 16bc0a06403..c55178f3f79 100644 --- a/server/src/com/cloud/test/PodZoneConfig.java +++ b/server/src/com/cloud/test/PodZoneConfig.java @@ -221,11 +221,11 @@ public long getVlanDbId(String zone, String vlanId) { if (add) { // Make sure the gateway is valid - if (!NetUtils.isValidIp(vlanGateway)) + if (!NetUtils.isValidIp4(vlanGateway)) return genReturnList("false", "Please specify a valid gateway."); // Make sure the netmask is valid - if (!NetUtils.isValidIp(vlanNetmask)) + if (!NetUtils.isValidIp4(vlanNetmask)) return genReturnList("false", "Please specify a valid netmask."); // Check if a vlan with the same vlanId already exists in the specified zone diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index aaaa92ba3c1..fea8b47a0c5 100644 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -172,6 +172,8 @@ import com.cloud.vm.snapshot.VMSnapshotManager; import com.cloud.vm.snapshot.VMSnapshotVO; import com.cloud.vm.snapshot.dao.VMSnapshotDao; +import org.apache.cloudstack.config.ApiServiceConfiguration; + public class AccountManagerImpl extends ManagerBase implements AccountManager, Manager { public static final Logger s_logger = Logger.getLogger(AccountManagerImpl.class); @@ -179,6 +181,8 @@ @Inject private AccountDao _accountDao; @Inject + private AccountManager _accountMgr; + @Inject ConfigurationDao _configDao; @Inject private ResourceCountDao _resourceCountDao; @@ -2076,7 +2080,8 @@ public void logoutUser(long userId) { } @Override - public UserAccount authenticateUser(String username, String password, Long domainId, InetAddress loginIpAddress, Map<String, Object[]> requestParameters) { + public UserAccount authenticateUser(final String username, final String password, final Long domainId, final InetAddress loginIpAddress, final Map<String, Object[]> + requestParameters) { UserAccount user = null; if (password != null && !password.isEmpty()) { user = getUserAccount(username, password, domainId, requestParameters); @@ -2186,6 +2191,27 @@ public UserAccount authenticateUser(String username, String password, Long domai return null; } + // We authenticated successfully by now, let's check if we are allowed to login from the ip address the reqest comes from + final Account account = _accountMgr.getAccount(user.getAccountId()); + final DomainVO domain = (DomainVO) _domainMgr.getDomain(account.getDomainId()); + + // Get the CIDRs from where this account is allowed to make calls + final String accessAllowedCidrs = ApiServiceConfiguration.ApiAllowedSourceCidrList.valueIn(account.getId()).replaceAll("\\s",""); + final Boolean ApiSourceCidrChecksEnabled = ApiServiceConfiguration.ApiSourceCidrChecksEnabled.value(); + + if (ApiSourceCidrChecksEnabled) { + s_logger.debug("CIDRs from which account '" + account.toString() + "' is allowed to perform API calls: " + accessAllowedCidrs); + + // Block when is not in the list of allowed IPs + if (!NetUtils.isIpInCidrList(loginIpAddress, accessAllowedCidrs.split(","))) { + s_logger.warn("Request by account '" + account.toString() + "' was denied since " + loginIpAddress.toString().replaceAll("/","") + + " does not match " + accessAllowedCidrs); + throw new CloudAuthenticationException("Failed to authenticate user '" + username + "' in domain '" + domain.getPath() + "' from ip " + + loginIpAddress.toString().replaceAll("/","") + "; please provide valid credentials"); + } + } + + // Here all is fine! if (s_logger.isDebugEnabled()) { s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in"); } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 72c47931057..df50f5a9162 100644 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -649,7 +649,7 @@ protected void runInContext() { if (answer.getResult()) { String vmIp = answer.getDetails(); - if (NetUtils.isValidIp(vmIp)) { + if (NetUtils.isValidIp4(vmIp)) { // set this vm ip addr in vm nic. if (nic != null) { nic.setIPv4Address(vmIp); @@ -1184,7 +1184,7 @@ public UserVm addNicToVirtualMachine(AddNicToVMCmd cmd) throws InvalidParameterV NicProfile profile = new NicProfile(ipAddress, null, macAddress); if (ipAddress != null) { - if (!(NetUtils.isValidIp(ipAddress) || NetUtils.isValidIpv6(ipAddress))) { + if (!(NetUtils.isValidIp4(ipAddress) || NetUtils.isValidIp6(ipAddress))) { throw new InvalidParameterValueException("Invalid format for IP address parameter: " + ipAddress); } } diff --git a/server/test/com/cloud/api/ApiServletTest.java b/server/test/com/cloud/api/ApiServletTest.java index e7cdf41a38e..037c36e3b95 100644 --- a/server/test/com/cloud/api/ApiServletTest.java +++ b/server/test/com/cloud/api/ApiServletTest.java @@ -174,7 +174,7 @@ public void utf8FixupUtf() throws UnsupportedEncodingException { public void processRequestInContextUnauthorizedGET() { Mockito.when(request.getMethod()).thenReturn("GET"); Mockito.when( - apiServer.verifyRequest(Mockito.anyMap(), Mockito.anyLong())) + apiServer.verifyRequest(Mockito.anyMap(), Mockito.anyLong(), Mockito.any(InetAddress.class))) .thenReturn(false); servlet.processRequestInContext(request, response); Mockito.verify(response).setStatus(HttpServletResponse.SC_UNAUTHORIZED); @@ -188,7 +188,7 @@ public void processRequestInContextUnauthorizedGET() { public void processRequestInContextAuthorizedGet() { Mockito.when(request.getMethod()).thenReturn("GET"); Mockito.when( - apiServer.verifyRequest(Mockito.anyMap(), Mockito.anyLong())) + apiServer.verifyRequest(Mockito.anyMap(), Mockito.anyLong(), Mockito.any(InetAddress.class))) .thenReturn(true); servlet.processRequestInContext(request, response); Mockito.verify(response).setStatus(HttpServletResponse.SC_OK); @@ -242,33 +242,33 @@ public void processRequestInContextLogin() throws UnknownHostException { } @Test - public void getClientAddressWithXForwardedFor() { + public void getClientAddressWithXForwardedFor() throws UnknownHostException { Mockito.when(request.getHeader(Mockito.eq("X-Forwarded-For"))).thenReturn("192.168.1.1"); - Assert.assertEquals("192.168.1.1", ApiServlet.getClientAddress(request)); + Assert.assertEquals(InetAddress.getByName("192.168.1.1"), ApiServlet.getClientAddress(request)); } @Test - public void getClientAddressWithHttpXForwardedFor() { + public void getClientAddressWithHttpXForwardedFor() throws UnknownHostException { Mockito.when(request.getHeader(Mockito.eq("HTTP_X_FORWARDED_FOR"))).thenReturn("192.168.1.1"); - Assert.assertEquals("192.168.1.1", ApiServlet.getClientAddress(request)); + Assert.assertEquals(InetAddress.getByName("192.168.1.1"), ApiServlet.getClientAddress(request)); } @Test - public void getClientAddressWithXRemoteAddr() { + public void getClientAddressWithXRemoteAddr() throws UnknownHostException { Mockito.when(request.getHeader(Mockito.eq("Remote_Addr"))).thenReturn("192.168.1.1"); - Assert.assertEquals("192.168.1.1", ApiServlet.getClientAddress(request)); + Assert.assertEquals(InetAddress.getByName("192.168.1.1"), ApiServlet.getClientAddress(request)); } @Test - public void getClientAddressWithHttpClientIp() { + public void getClientAddressWithHttpClientIp() throws UnknownHostException { Mockito.when(request.getHeader(Mockito.eq("HTTP_CLIENT_IP"))).thenReturn("192.168.1.1"); - Assert.assertEquals("192.168.1.1", ApiServlet.getClientAddress(request)); + Assert.assertEquals(InetAddress.getByName("192.168.1.1"), ApiServlet.getClientAddress(request)); } @Test - public void getClientAddressDefault() { + public void getClientAddressDefault() throws UnknownHostException { Mockito.when(request.getRemoteAddr()).thenReturn("127.0.0.1"); - Assert.assertEquals("127.0.0.1", ApiServlet.getClientAddress(request)); + Assert.assertEquals(InetAddress.getByName("127.0.0.1"), ApiServlet.getClientAddress(request)); } } diff --git a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java index 273fdd0d116..a158c9c0e68 100644 --- a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java +++ b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java @@ -388,7 +388,7 @@ public boolean generateVMSetupCommand(Long ssAHostId) { List<String> allowedCidrs = new ArrayList<String>(); String[] cidrs = _allowedInternalSites.split(","); for (String cidr : cidrs) { - if (NetUtils.isValidCIDR(cidr) || NetUtils.isValidIp(cidr) || !cidr.startsWith("0.0.0.0")) { + if (NetUtils.isValidIp4Cidr(cidr) || NetUtils.isValidIp4(cidr) || !cidr.startsWith("0.0.0.0")) { allowedCidrs.add(cidr); } } @@ -1170,7 +1170,7 @@ public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, Depl } if (nic.getTrafficType() == TrafficType.Management) { String mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key()); - if (NetUtils.isValidCIDR(mgmt_cidr)) { + if (NetUtils.isValidIp4Cidr(mgmt_cidr)) { buf.append(" mgmtcidr=").append(mgmt_cidr); } buf.append(" localgw=").append(dest.getPod().getGateway()); diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 655f11508d7..dd97872d32d 100644 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -2293,12 +2293,12 @@ private void addRouteToInternalIpOrCidr(String localgw, String eth1ip, String et s_logger.debug("addRouteToInternalIp: destIp is null"); return; } - if (!NetUtils.isValidIp(destIpOrCidr) && !NetUtils.isValidCIDR(destIpOrCidr)) { + if (!NetUtils.isValidIp4(destIpOrCidr) && !NetUtils.isValidIp4Cidr(destIpOrCidr)) { s_logger.warn(" destIp is not a valid ip address or cidr destIp=" + destIpOrCidr); return; } boolean inSameSubnet = false; - if (NetUtils.isValidIp(destIpOrCidr)) { + if (NetUtils.isValidIp4(destIpOrCidr)) { if (eth1ip != null && eth1mask != null) { inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask); } else { diff --git a/ui/l10n/en.js b/ui/l10n/en.js index afd95006345..1f31dce7e73 100644 --- a/ui/l10n/en.js +++ b/ui/l10n/en.js @@ -22,7 +22,7 @@ var dictionary = {"ICMP.code":"ICMP Code", "error.could.not.change.your.password.because.non.native.user":"Error could not change your password because user is not a native CloudStack user.", "error.could.not.enable.zone":"Could not enable zone", "error.installWizard.message":"Something went wrong; you may go back and correct any errors", -"error.invalid.username.password":"Invalid username or password", +"error.invalid.username.password": "Invalid username or password.<br/><br/>This could also be a restriction on the IP address you are connecting from.", "error.login":"Your username/password does not match our records.", "error.menu.select":"Unable to perform action due to no items being selected.", "error.mgmt.server.inaccessible":"The Management Server is unaccessible. Please try again later.", diff --git a/utils/src/main/java/com/cloud/utils/net/NetUtils.java b/utils/src/main/java/com/cloud/utils/net/NetUtils.java index c28739a91bd..1bd08a32b25 100644 --- a/utils/src/main/java/com/cloud/utils/net/NetUtils.java +++ b/utils/src/main/java/com/cloud/utils/net/NetUtils.java @@ -24,6 +24,8 @@ import java.io.InputStreamReader; import java.math.BigInteger; import java.net.InetAddress; +import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.net.SocketException; @@ -35,7 +37,6 @@ import java.util.Random; import java.util.Set; import java.util.SortedSet; -import java.util.StringTokenizer; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -61,8 +62,8 @@ private static final int MAX_CIDR = 32; private static final int RFC_3021_31_BIT_CIDR = 31; - public final static String HTTP_PORT = "80"; - public final static String HTTPS_PORT = "443"; + public final static int HTTP_PORT = 80; + public final static int HTTPS_PORT = 443; public final static int VPN_PORT = 500; public final static int VPN_NATT_PORT = 4500; public final static int VPN_L2TP_PORT = 1701; @@ -76,7 +77,8 @@ public final static String HTTP_PROTO = "http"; public final static String SSL_PROTO = "ssl"; - public final static String ALL_CIDRS = "0.0.0.0/0"; + public final static String ALL_IP4_CIDRS = "0.0.0.0/0"; + public final static String ALL_IP6_CIDRS = "::/0"; public final static int PORT_RANGE_MIN = 0; public final static int PORT_RANGE_MAX = 65535; @@ -123,7 +125,7 @@ public static InetAddress getLocalInetAddress() { public static String resolveToIp(final String host) { try { final InetAddress addr = InetAddress.getByName(host); - return ipFromInetAddress(addr); + return addr.getHostAddress(); } catch (final UnknownHostException e) { s_logger.warn("Unable to resolve " + host + " to IP due to UnknownHostException"); return null; @@ -162,7 +164,7 @@ public static String resolveToIp(final String host) { final InetAddress addr = address.getAddress(); final int prefixLength = address.getNetworkPrefixLength(); if (prefixLength < MAX_CIDR && prefixLength > 0) { - final String ip = ipFromInetAddress(addr); + final String ip = addr.getHostAddress(); if (ip.equalsIgnoreCase(defaultHostIp)) { cidrList.add(ipAndNetMaskToCidr(ip, getCidrNetmask(prefixLength))); } @@ -243,67 +245,15 @@ public static String getDefaultEthDevice() { return defaultRouteList[7]; } - public static InetAddress getFirstNonLoopbackLocalInetAddress() { - final InetAddress[] addrs = getAllLocalInetAddresses(); - if (addrs != null) { - for (final InetAddress addr : addrs) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Check local InetAddress : " + addr.toString() + ", total count :" + addrs.length); - } - - if (!addr.isLoopbackAddress()) { - return addr; - } - } - } - - s_logger.warn("Unable to determine a non-loopback address, local inet address count :" + addrs.length); - return null; - } - - public static InetAddress[] getInterfaceInetAddresses(final String ifName) { - final List<InetAddress> addrList = new ArrayList<InetAddress>(); - try { - for (final NetworkInterface ifc : IteratorUtil.enumerationAsIterable(NetworkInterface.getNetworkInterfaces())) { - if (ifc.isUp() && !ifc.isVirtual() && ifc.getName().equals(ifName)) { - for (final InetAddress addr : IteratorUtil.enumerationAsIterable(ifc.getInetAddresses())) { - addrList.add(addr); - } - } - } - } catch (final SocketException e) { - s_logger.warn("SocketException in getAllLocalInetAddresses().", e); - } - - final InetAddress[] addrs = new InetAddress[addrList.size()]; - if (addrList.size() > 0) { - System.arraycopy(addrList.toArray(), 0, addrs, 0, addrList.size()); - } - return addrs; - } - public static String getLocalIPString() { final InetAddress addr = getLocalInetAddress(); if (addr != null) { - return ipFromInetAddress(addr); + return addr.getHostAddress(); } return "127.0.0.1"; } - public static String ipFromInetAddress(final InetAddress addr) { - assert addr != null; - - final byte[] ipBytes = addr.getAddress(); - final StringBuffer sb = new StringBuffer(); - sb.append(ipBytes[0] & 0xff).append("."); - sb.append(ipBytes[1] & 0xff).append("."); - sb.append(ipBytes[2] & 0xff).append("."); - sb.append(ipBytes[3] & 0xff); - - return sb.toString(); - } - public static boolean isLocalAddress(final InetAddress addr) { final InetAddress[] addrs = getAllLocalInetAddresses(); @@ -318,10 +268,8 @@ public static boolean isLocalAddress(final InetAddress addr) { } public static boolean isLocalAddress(final String strAddress) { - - InetAddress addr; try { - addr = InetAddress.getByName(strAddress); + InetAddress addr = InetAddress.getByName(strAddress); return isLocalAddress(addr); } catch (final UnknownHostException e) { } @@ -346,23 +294,6 @@ public static String getMacAddress(final InetAddress address) { return sb.toString(); } - public static long getMacAddressAsLong(final InetAddress address) { - long macAddressAsLong = 0; - try { - final NetworkInterface ni = NetworkInterface.getByInetAddress(address); - final byte[] mac = ni.getHardwareAddress(); - - for (int i = 0; i < mac.length; i++) { - macAddressAsLong |= (long)(mac[i] & 0xff) << (mac.length - i - 1) * 8; - } - - } catch (final SocketException e) { - s_logger.error("SocketException when trying to retrieve MAC address", e); - } - - return macAddressAsLong; - } - /** * This method will fail in case we have a 31 Bit prefix network * See RFC 3021. @@ -498,40 +429,15 @@ public static String long2Mac(final long macAddress) { return result.toString(); } - public static boolean isValidPrivateIp(final String ipAddress, final String guestIPAddress) { - - final InetAddress privIp = parseIpAddress(ipAddress); - if (privIp == null) { - return false; - } - if (!privIp.isSiteLocalAddress()) { - return false; - } - - String firstGuestOctet = "10"; - if (guestIPAddress != null && !guestIPAddress.isEmpty()) { - final String[] guestIPList = guestIPAddress.split("\\."); - firstGuestOctet = guestIPList[0]; - } - - final String[] ipList = ipAddress.split("\\."); - if (!ipList[0].equals(firstGuestOctet)) { - return false; - } - - return true; - } - public static boolean isSiteLocalAddress(final String ipAddress) { - if (ipAddress == null) { - return false; - } else { - final InetAddress ip = parseIpAddress(ipAddress); - if(ip != null) { + try { + final InetAddress ip = InetAddress.getByName(ipAddress); + if (ip != null) { return ip.isSiteLocalAddress(); } - return false; - } + } catch (UnknownHostException e) {} + + return false; } public static boolean validIpRange(final String startIP, final String endIP) { @@ -544,14 +450,16 @@ public static boolean validIpRange(final String startIP, final String endIP) { return startIPLong <= endIPLong; } - public static boolean isValidIp(final String ip) { - final InetAddressValidator validator = InetAddressValidator.getInstance(); + public static boolean isValidIp4(final String ip) { + if (ip == null) + return false; + final InetAddressValidator validator = InetAddressValidator.getInstance(); return validator.isValidInet4Address(ip); } public static boolean is31PrefixCidr(final String cidr) { - final boolean isValidCird = isValidCIDR(cidr); + final boolean isValidCird = isValidIp4Cidr(cidr); if (isValidCird){ final String[] cidrPair = cidr.split("\\/"); final String cidrSize = cidrPair[1]; @@ -564,23 +472,18 @@ public static boolean is31PrefixCidr(final String cidr) { return false; } - public static boolean isValidCIDR(final String cidr) { + public static boolean isValidIp4Cidr(final String cidr) { if (cidr == null || cidr.isEmpty()) { return false; } - try { - IPv6Network.fromString(cidr); - return true; - } catch (IllegalArgumentException e) {} - final String[] cidrPair = cidr.split("\\/"); if (cidrPair.length != 2) { return false; } final String cidrAddress = cidrPair[0]; final String cidrSize = cidrPair[1]; - if (!isValidIp(cidrAddress)) { + if (!isValidIp4(cidrAddress)) { return false; } int cidrSizeNum = -1; @@ -598,8 +501,8 @@ public static boolean isValidCIDR(final String cidr) { return true; } - public static boolean isValidNetmask(final String netmask) { - if (!isValidIp(netmask)) { + public static boolean isValidIp4Netmask(final String netmask) { + if (!isValidIp4(netmask)) { return false; } @@ -624,25 +527,6 @@ public static boolean isValidNetmask(final String netmask) { return true; } - private static InetAddress parseIpAddress(final String address) { - final StringTokenizer st = new StringTokenizer(address, "."); - final byte[] bytes = new byte[4]; - - if (st.countTokens() == 4) { - try { - for (int i = 0; i < 4; i++) { - bytes[i] = (byte)Integer.parseInt(st.nextToken()); - } - return InetAddress.getByAddress(address, bytes); - } catch (final NumberFormatException nfe) { - return null; - } catch (final UnknownHostException uhe) { - return null; - } - } - return null; - } - public static String getCidrFromGatewayAndNetmask(final String gatewayStr, final String netmaskStr) { final long netmask = ip2Long(netmaskStr); final long gateway = ip2Long(gatewayStr); @@ -808,11 +692,11 @@ static long netMaskFromCidr(final long cidrSize) { } public static String ipAndNetMaskToCidr(final String ip, final String netmask) { - if (!isValidIp(ip)) { + if (!isValidIp4(ip)) { return null; } - if (!isValidNetmask(netmask)) { + if (!isValidIp4Netmask(netmask)) { return null; } @@ -909,7 +793,7 @@ static boolean areCidrsNotEmpty(String cidrA, String cidrB) { } final String cidrAddress = cidrPair[0]; final String cidrSize = cidrPair[1]; - if (!isValidIp(cidrAddress)) { + if (!isValidIp4(cidrAddress)) { throw new CloudRuntimeException("cidr is not valid in ip space" + cidr); } long cidrSizeNum = getCidrSizeFromString(cidrSize); @@ -949,7 +833,7 @@ public static String getCidrSubNet(final String cidr) { } final String cidrAddress = cidrPair[0]; final String cidrSize = cidrPair[1]; - if (!isValidIp(cidrAddress)) { + if (!isValidIp4(cidrAddress)) { return null; } long cidrSizeNum = getCidrSizeFromString(cidrSize); @@ -988,23 +872,13 @@ public static long getCidrSize(final String netmask) { return MAX_CIDR - count; } - public static boolean isValidPort(final String p) { - try { - final int port = Integer.parseInt(p); - return !(port > 65535 || port < 1); - } catch (final NumberFormatException e) { - return false; - } - } - public static boolean isValidPort(final int p) { - return !(p > 65535 || p < 1); + return !(p > PORT_RANGE_MAX || p < PORT_RANGE_MIN); } - public static boolean isValidLBPort(final String p) { + public static boolean isValidPort(final String p) { try { - final int port = Integer.parseInt(p); - return !(port > 65535 || port < 1); + return isValidPort(Integer.parseInt(p)); } catch (final NumberFormatException e) { return false; } @@ -1126,11 +1000,11 @@ public static String getDhcpRange(final String cidr) { // Check if 2 CIDRs have exactly same IP Range public static boolean isSameIpRange(final String cidrA, final String cidrB) { - if (!NetUtils.isValidCIDR(cidrA)) { + if (!NetUtils.isValidIp4Cidr(cidrA)) { s_logger.info("Invalid value of cidr " + cidrA); return false; } - if (!NetUtils.isValidCIDR(cidrB)) { + if (!NetUtils.isValidIp4Cidr(cidrB)) { s_logger.info("Invalid value of cidr " + cidrB); return false; } @@ -1164,7 +1038,7 @@ public static boolean validateGuestCidr(final String cidr) { // The allocated address block is 100.64.0.0/10 final String[] allowedNetBlocks = {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "100.64.0.0/10"}; - if (!isValidCIDR(cidr)) { + if (!isValidIp4Cidr(cidr)) { s_logger.warn("Cidr " + cidr + " is not valid"); return false; } @@ -1261,7 +1135,7 @@ public static boolean isValidS2SVpnPolicy(final String policyType, final String public static boolean isValidCidrList(final String cidrList) { for (final String guestCidr : cidrList.split(",")) { - if (!isValidCIDR(guestCidr)) { + if (!isValidIp4Cidr(guestCidr)) { return false; } } @@ -1297,13 +1171,12 @@ public static boolean validateIcmpCode(final long icmpCode) { return true; } - public static boolean isValidIpv6(final String ip) { - try { - IPv6Address.fromString(ip); - } catch (final IllegalArgumentException ex) { - return false; - } - return true; + public static boolean isValidIp6(final String ip) { + if (ip == null) + return false; + + final InetAddressValidator validator = InetAddressValidator.getInstance(); + return validator.isValidInet6Address(ip); } public static boolean isValidIp6Cidr(final String ip6Cidr) { @@ -1410,15 +1283,16 @@ public static boolean isIp6InRange(final String ip6, final String ip6Range) { return false; } + public static boolean isIp6InNetwork(final IPv6Address ip, final IPv6Network network) { + return network.contains(ip); + } + public static boolean isIp6InNetwork(final String ip6, final String ip6Cidr) { - IPv6Network network = null; try { - network = IPv6Network.fromString(ip6Cidr); + return isIp6InNetwork(IPv6Address.fromString(ip6), IPv6Network.fromString(ip6Cidr)); } catch (final IllegalArgumentException ex) { return false; } - final IPv6Address ip = IPv6Address.fromString(ip6); - return network.contains(ip); } public static boolean isIp6RangeOverlap(final String ipRange1, final String ipRange2) { @@ -1580,11 +1454,11 @@ public static String generateMacOnIncrease(final String baseMac, final long l) { return long2Mac(mac); } - public static boolean isIpWithtInCidrRange(final String ipAddress, final String cidr) { - if (!isValidIp(ipAddress)) { + public static boolean isIpWithInCidrRange(final String ipAddress, final String cidr) { + if (!isValidIp4(ipAddress)) { return false; } - if (!isValidCIDR(cidr)) { + if (!isValidIp4Cidr(cidr)) { return false; } @@ -1602,6 +1476,29 @@ public static boolean isIpWithtInCidrRange(final String ipAddress, final String return isInRange; } + public static boolean isIpInCidrList(final InetAddress address, final String[] cidrlist) { + boolean match = false; + + for (String cidr: cidrlist) { + try { + if (address instanceof Inet6Address && isValidIp6Cidr(cidr)) { + if (isIp6InNetwork(IPv6Address.fromInetAddress(address), IPv6Network.fromString(cidr))) { + match = true; + break; + } + } else if (address instanceof Inet4Address && isValidIp4Cidr(cidr)) { + if (NetUtils.isIpWithInCidrRange(address.getHostAddress(), cidr)) { + match = true; + break; + } + } + } catch (IllegalArgumentException e) { + continue; + } + } + return match; + } + public static Boolean IsIpEqualToNetworkOrBroadCastIp(final String requestedIp, final String cidr, final long size) { assert size < MAX_CIDR : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; @@ -1647,7 +1544,7 @@ public static IPv6Address EUI64Address(final String cidr, final String macAddres } public static IPv6Address ipv6LinkLocal(final String macAddress) { - return EUI64Address(IPv6Network.fromString("fe80::/64"), macAddress); + return EUI64Address(IPv6Network.LINK_LOCAL_NETWORK, macAddress); } } diff --git a/utils/src/test/java/com/cloud/utils/net/NetUtilsTest.java b/utils/src/test/java/com/cloud/utils/net/NetUtilsTest.java index eaa9c29088e..bec22098b49 100644 --- a/utils/src/test/java/com/cloud/utils/net/NetUtilsTest.java +++ b/utils/src/test/java/com/cloud/utils/net/NetUtilsTest.java @@ -32,9 +32,12 @@ import static org.junit.Assert.assertTrue; import java.math.BigInteger; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.SortedSet; import java.util.TreeSet; +import com.googlecode.ipv6.IPv6Network; import org.apache.log4j.Logger; import org.junit.Test; @@ -198,10 +201,10 @@ public void testIsUnicastMac() { @Test public void testIsValidIpv6() { - assertTrue(NetUtils.isValidIpv6("fc00::1")); - assertFalse(NetUtils.isValidIpv6("")); - assertFalse(NetUtils.isValidIpv6(null)); - assertFalse(NetUtils.isValidIpv6("1234:5678::1/64")); + assertTrue(NetUtils.isValidIp6("fc00::1")); + assertFalse(NetUtils.isValidIp6("")); + assertFalse(NetUtils.isValidIp6(null)); + assertFalse(NetUtils.isValidIp6("1234:5678::1/64")); } @Test @@ -214,10 +217,10 @@ public void testIsIp6InRange() { @Test public void testIsIp6InNetwork() { - assertFalse(NetUtils.isIp6InNetwork("1234:5678:abcd::1", "1234:5678::/64")); - assertTrue(NetUtils.isIp6InNetwork("1234:5678::1", "1234:5678::/64")); - assertTrue(NetUtils.isIp6InNetwork("1234:5678::ffff:ffff:ffff:ffff", "1234:5678::/64")); - assertTrue(NetUtils.isIp6InNetwork("1234:5678::", "1234:5678::/64")); + assertFalse(NetUtils.isIp6InNetwork(IPv6Address.fromString("1234:5678:abcd::1"), IPv6Network.fromString("1234:5678::/64"))); + assertTrue(NetUtils.isIp6InNetwork(IPv6Address.fromString("1234:5678::1"), IPv6Network.fromString("1234:5678::/64"))); + assertTrue(NetUtils.isIp6InNetwork(IPv6Address.fromString("1234:5678::ffff:ffff:ffff:ffff"), IPv6Network.fromString("1234:5678::/64"))); + assertTrue(NetUtils.isIp6InNetwork(IPv6Address.fromString("1234:5678::"), IPv6Network.fromString("1234:5678::/64"))); } @Test @@ -267,13 +270,9 @@ public void testIsValidCIDR() throws Exception { final String cidrSecond = "10.0.151.0/20"; final String cidrThird = "10.0.144.0/21"; - assertTrue(NetUtils.isValidCIDR(cidrFirst)); - assertTrue(NetUtils.isValidCIDR(cidrSecond)); - assertTrue(NetUtils.isValidCIDR(cidrThird)); - assertTrue(NetUtils.isValidCIDR("2001:db8::/64")); - assertTrue(NetUtils.isValidCIDR("2001:db8::/48")); - assertTrue(NetUtils.isValidCIDR("2001:db8:fff::/56")); - assertFalse(NetUtils.isValidCIDR("2001:db8:gggg::/56")); + assertTrue(NetUtils.isValidIp4Cidr(cidrFirst)); + assertTrue(NetUtils.isValidIp4Cidr(cidrSecond)); + assertTrue(NetUtils.isValidIp4Cidr(cidrThird));; } @Test @@ -285,8 +284,6 @@ public void testIsValidCidrList() throws Exception { assertTrue(NetUtils.isValidCidrList(cidrFirst)); assertTrue(NetUtils.isValidCidrList(cidrSecond)); assertTrue(NetUtils.isValidCidrList(cidrThird)); - assertTrue(NetUtils.isValidCidrList("2001:db8::/64,2001:db8:ffff::/48")); - assertTrue(NetUtils.isValidCidrList("2001:db8::/64,2001:db8:ffff::/48,192.168.0.0/24")); } @Test @@ -386,7 +383,7 @@ public void test31BitPrefixStart() { final String ipAddress = "192.168.0.0"; final String cidr = "192.168.0.0/31"; - final boolean isInRange = NetUtils.isIpWithtInCidrRange(ipAddress, cidr); + final boolean isInRange = NetUtils.isIpWithInCidrRange(ipAddress, cidr); assertTrue("Check if the subnetUtils.setInclusiveHostCount(true) has been called.", isInRange); } @@ -396,7 +393,7 @@ public void test31BitPrefixEnd() { final String ipAddress = "192.168.0.1"; final String cidr = "192.168.0.0/31"; - final boolean isInRange = NetUtils.isIpWithtInCidrRange(ipAddress, cidr); + final boolean isInRange = NetUtils.isIpWithInCidrRange(ipAddress, cidr); assertTrue("Check if the subnetUtils.setInclusiveHostCount(true) has been called.", isInRange); } @@ -406,7 +403,7 @@ public void test31BitPrefixFail() { final String ipAddress = "192.168.0.2"; final String cidr = "192.168.0.0/31"; - final boolean isInRange = NetUtils.isIpWithtInCidrRange(ipAddress, cidr); + final boolean isInRange = NetUtils.isIpWithInCidrRange(ipAddress, cidr); assertFalse("Out of the range. Why did it return true?", isInRange); } @@ -462,21 +459,21 @@ public void testIs31PrefixCidr() { public void testGetCidrNetMask() { final String cidr = "10.10.0.0/16"; String netmask = NetUtils.getCidrNetmask("10.10.10.10/16"); - assertTrue(cidr + " does not generate valid netmask " + netmask,NetUtils.isValidNetmask(netmask)); + assertTrue(cidr + " does not generate valid netmask " + netmask,NetUtils.isValidIp4Netmask(netmask)); } @Test public void testGetCidrSubNet() { final String cidr = "10.10.0.0/16"; String subnet = NetUtils.getCidrSubNet("10.10.10.10/16"); - assertTrue(cidr + " does not contain " + subnet,NetUtils.isIpWithtInCidrRange(subnet, cidr)); + assertTrue(cidr + " does not contain " + subnet,NetUtils.isIpWithInCidrRange(subnet, cidr)); } @Test public void testGetCidrSubNetWithWidth() { final String cidr = "10.10.0.0/16"; String subnet = NetUtils.getCidrSubNet("10.10.10.10", 16); - assertTrue(cidr + " does not contain " + subnet,NetUtils.isIpWithtInCidrRange(subnet, cidr)); + assertTrue(cidr + " does not contain " + subnet,NetUtils.isIpWithInCidrRange(subnet, cidr)); } @Test @@ -610,4 +607,75 @@ public void testIPv6LinkLocal() { assertEquals(IPv6Address.fromString("fe80::42:e0ff:fee8:d6a3"), NetUtils.ipv6LinkLocal("02:42:e0:e8:d6:a3")); assertEquals(IPv6Address.fromString("fe80::47a:88ff:fe00:8b"), NetUtils.ipv6LinkLocal("06:7a:88:00:00:8b")); } + + @Test + public void testIsIpInCidrList() throws UnknownHostException { + String[] cidrs = "0.0.0.0/0,::/0".split(","); + System.out.println(NetUtils.isIpInCidrList(InetAddress.getByName("192.168.1.1"), cidrs)); + assertTrue(NetUtils.isIpInCidrList(InetAddress.getByName("192.168.1.1"), cidrs)); + assertTrue(NetUtils.isIpInCidrList(InetAddress.getByName("172.16.8.9"), cidrs)); + assertTrue(NetUtils.isIpInCidrList(InetAddress.getByName("127.0.0.1"), cidrs)); + assertTrue(NetUtils.isIpInCidrList(InetAddress.getByName("2001:db8:100::1"), cidrs)); + assertTrue(NetUtils.isIpInCidrList(InetAddress.getByName("::1"), cidrs)); + assertTrue(NetUtils.isIpInCidrList(InetAddress.getByName("2a01:4f8:130:2192::2"), cidrs)); + + assertTrue(NetUtils.isIpInCidrList(InetAddress.getByName("127.0.0.1"), "127.0.0.1/8".split(","))); + assertFalse(NetUtils.isIpInCidrList(InetAddress.getByName("192.168.1.1"), "127.0.0.1/8".split(","))); + + assertTrue(NetUtils.isIpInCidrList(InetAddress.getByName("127.0.0.1"), "127.0.0.1/8,::1/128".split(","))); + assertTrue(NetUtils.isIpInCidrList(InetAddress.getByName("::1"), "127.0.0.1/8,::1/128".split(","))); + + assertFalse(NetUtils.isIpInCidrList(InetAddress.getByName("192.168.29.47"), "127.0.0.1/8,::1/128".split(","))); + assertFalse(NetUtils.isIpInCidrList(InetAddress.getByName("2001:db8:1938:3ff1::1"), "127.0.0.1/8,::1/128".split(","))); + + assertTrue(NetUtils.isIpInCidrList(InetAddress.getByName("2a01:4f8:130:2192::2"), "::/0,127.0.0.1".split(","))); + assertTrue(NetUtils.isIpInCidrList(InetAddress.getByName("2001:db8:200:300::1"), "2001:db8:200::/48,127.0.0.1".split(","))); + assertFalse(NetUtils.isIpInCidrList(InetAddress.getByName("2001:db8:200:300::1"), "2001:db8:300::/64,127.0.0.1".split(","))); + assertFalse(NetUtils.isIpInCidrList(InetAddress.getByName("2a01:4f8:130:2192::2"), "2001:db8::/64,127.0.0.1".split(","))); + } + + @Test + public void testIsSiteLocalAddress() { + assertTrue(NetUtils.isSiteLocalAddress("192.168.0.1")); + assertTrue(NetUtils.isSiteLocalAddress("10.0.0.1")); + assertTrue(NetUtils.isSiteLocalAddress("172.16.0.1")); + assertTrue(NetUtils.isSiteLocalAddress("192.168.254.56")); + assertTrue(NetUtils.isSiteLocalAddress("10.254.254.254")); + assertFalse(NetUtils.isSiteLocalAddress("8.8.8.8")); + assertFalse(NetUtils.isSiteLocalAddress("8.8.4.4")); + assertFalse(NetUtils.isSiteLocalAddress("")); + assertFalse(NetUtils.isSiteLocalAddress(null)); + } + + @Test + public void testStaticVariables() { + assertEquals(80, NetUtils.HTTP_PORT); + assertEquals(443, NetUtils.HTTPS_PORT); + assertEquals(500, NetUtils.VPN_PORT); + assertEquals(4500, NetUtils.VPN_NATT_PORT); + assertEquals(1701, NetUtils.VPN_L2TP_PORT); + assertEquals(8081, NetUtils.HAPROXY_STATS_PORT); + + assertEquals("udp", NetUtils.UDP_PROTO); + assertEquals("tcp", NetUtils.TCP_PROTO); + assertEquals("any", NetUtils.ANY_PROTO); + assertEquals("icmp", NetUtils.ICMP_PROTO); + assertEquals("http", NetUtils.HTTP_PROTO); + assertEquals("ssl", NetUtils.SSL_PROTO); + + assertEquals("0.0.0.0/0", NetUtils.ALL_IP4_CIDRS); + assertEquals("::/0", NetUtils.ALL_IP6_CIDRS); + } + + @Test + public void testIsValidPort() { + assertTrue(NetUtils.isValidPort(80)); + assertTrue(NetUtils.isValidPort("80")); + assertTrue(NetUtils.isValidPort(443)); + assertTrue(NetUtils.isValidPort("443")); + assertTrue(NetUtils.isValidPort(0)); + assertTrue(NetUtils.isValidPort(65535)); + assertFalse(NetUtils.isValidPort(-1)); + assertFalse(NetUtils.isValidPort(65536)); + } } diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java index bece91a98f5..f448741fe54 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java @@ -1618,7 +1618,7 @@ public static String resolveHostNameInUrl(DatacenterMO dcMo, String url) { } String host = uri.getHost(); - if (NetUtils.isValidIp(host)) { + if (NetUtils.isValidIp4(host)) { s_logger.info("host name in url is already in IP address, url: " + url); return url; } ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services