On 09/14/2012 02:32 PM, Tomas Lestach wrote: [...] > > Hi Johannes, > > the patch look good. > > However looking at [1] I see the code is licensed under the Apache License, > Version 2.0. I'm afraid this version isn't compatible with the Spacewalk's > GPLv2. > Or is it? Cliff?
I reworked the code again and also simplified the regex, so I guess it could be fine now? Attached is another version of the patch. Regards, Johannes -- SUSE LINUX Products GmbH, HRB 16746 (AG Nürnberg) GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer
>From ebd7f06c7332a44974b95f51146e59a527356f29 Mon Sep 17 00:00:00 2001 From: Johannes Renner <jren...@suse.de> Date: Tue, 18 Sep 2012 14:17:11 +0200 Subject: [PATCH] Validate proxy format on general config page --- .../rhn/common/validator/HostPortValidator.java | 134 ++++++++++++++++++++ .../validator/test/HostPortValidatorTest.java | 63 +++++++++ .../action/satellite/GeneralConfigAction.java | 12 +- .../frontend/strings/java/StringResource_en_US.xml | 8 ++ 4 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 java/code/src/com/redhat/rhn/common/validator/HostPortValidator.java create mode 100644 java/code/src/com/redhat/rhn/common/validator/test/HostPortValidatorTest.java diff --git a/java/code/src/com/redhat/rhn/common/validator/HostPortValidator.java b/java/code/src/com/redhat/rhn/common/validator/HostPortValidator.java new file mode 100644 index 0000000..cff8ad7 --- /dev/null +++ b/java/code/src/com/redhat/rhn/common/validator/HostPortValidator.java @@ -0,0 +1,134 @@ +/** + * Copyright (c) 2012 Novell + * + * This software is licensed to you under the GNU General Public License, + * version 2 (GPLv2). There is NO WARRANTY for this software, express or + * implied, including the implied warranties of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 + * along with this software; if not, see + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * Red Hat trademarks are not licensed under GPLv2. No permission is + * granted to use or replicate Red Hat trademarks that are incorporated + * in this software or its documentation. + */ +package com.redhat.rhn.common.validator; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Input validation for host[:port], where the host part can be either an IP address + * (IPv4 or IPv6) or a hostname. + */ +public class HostPortValidator { + + // Singleton instance + private static HostPortValidator instance; + + // Pattern to match IPv6 address in bracket notation + private static final Pattern IPV6_BRACKETS = Pattern.compile("^\\[(.*)\\](:(\\d*))?$"); + + // Private constructor + private HostPortValidator() { + } + + /** + * Return the singleton instance of {@link HostPortValidator}. + * @return {@link HostPortValidator} instance + */ + public static HostPortValidator getInstance() { + if (instance == null) { + instance = new HostPortValidator(); + } + return instance; + } + + /** + * Return true if the given string is a valid host[:port] representation. + * @param hostPort + * @return true if hostPort represents a valid host and port, else false. + */ + public boolean isValid(String hostPort) { + if (hostPort == null || hostPort.isEmpty()) { + return false; + } + String host; + String port; + + if (hostPort.startsWith("[")) { + // Parse an IPv6 address in bracket notation + Matcher matcher = IPV6_BRACKETS.matcher(hostPort); + if (!matcher.matches()) { + return false; + } + host = matcher.group(1); + port = matcher.group(3); + } + else { + int colonIndex = hostPort.indexOf(':'); + if (colonIndex != -1 && colonIndex == hostPort.lastIndexOf(':')) { + // Split into host:port + host = hostPort.substring(0, colonIndex); + port = hostPort.substring(colonIndex + 1); + } + else { + host = hostPort; + port = null; + } + } + + // Validate host and port separately + boolean isValidHost = true; + // Validate IP addresses externally (v4 and v6) + if (host.replaceAll("[\\d\\.]", "").isEmpty() || host.contains(":")) { + isValidHost = isValidIP(host); + } + boolean isValidPort = true; + if (port != null) { + isValidPort = isValidPort(port); + } + + return isValidHost && isValidPort; + } + + /** + * Validate IP address format for a given string. + * @param ipString + * @return true if the given string is a valid IP, else false. + */ + private boolean isValidIP(String ipString) { + boolean ret = false; + if (ipString != null && !ipString.isEmpty()) { + try { + InetAddress.getByName(ipString); + ret = true; + } + catch (UnknownHostException e) { + // Stay silent + } + } + return ret; + } + + /** + * Parse a port number from a given string and validate it. + * @param portString + * @return true if the given string is a valid port, else false. + */ + private boolean isValidPort(String portString) { + boolean ret = false; + if (portString != null && !portString.isEmpty()) { + try { + int port = Integer.parseInt(portString); + ret = port >= 0 && port < 65535; + } + catch (NumberFormatException e) { + // Stay silent + } + } + return ret; + } +} diff --git a/java/code/src/com/redhat/rhn/common/validator/test/HostPortValidatorTest.java b/java/code/src/com/redhat/rhn/common/validator/test/HostPortValidatorTest.java new file mode 100644 index 0000000..e96bd91 --- /dev/null +++ b/java/code/src/com/redhat/rhn/common/validator/test/HostPortValidatorTest.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2012 Novell + * + * This software is licensed to you under the GNU General Public License, + * version 2 (GPLv2). There is NO WARRANTY for this software, express or + * implied, including the implied warranties of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 + * along with this software; if not, see + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * Red Hat trademarks are not licensed under GPLv2. No permission is + * granted to use or replicate Red Hat trademarks that are incorporated + * in this software or its documentation. + */ +package com.redhat.rhn.common.validator.test; + +import com.redhat.rhn.common.validator.HostPortValidator; + +import junit.framework.TestCase; + +/** + * Test class for the {@link HostPortValidator}. + */ +public class HostPortValidatorTest extends TestCase { + + public void testIPv4() { + assertTrue(HostPortValidator.getInstance().isValid("192.168.1.2")); + assertTrue(HostPortValidator.getInstance().isValid("192.168.1.2:8888")); + assertTrue(HostPortValidator.getInstance().isValid("192.168.1")); + + assertFalse(HostPortValidator.getInstance().isValid("192.168.1.2:")); + assertFalse(HostPortValidator.getInstance().isValid("192.168.1.2.3")); + assertFalse(HostPortValidator.getInstance().isValid("1200.5.4.3")); + assertFalse(HostPortValidator.getInstance().isValid("192.168.2.1:888888")); + assertFalse(HostPortValidator.getInstance().isValid("http://192.168.2.1:8888")); + } + + public void testIPv6() { + assertTrue(HostPortValidator.getInstance().isValid("2001:0db8:85a3:08d3:1319:8a2e:0370:7344")); + assertTrue(HostPortValidator.getInstance().isValid("[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]")); + assertTrue(HostPortValidator.getInstance().isValid("[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:8888")); + assertTrue(HostPortValidator.getInstance().isValid("[2607:f0d0:1002:51::4]:8888")); + assertTrue(HostPortValidator.getInstance().isValid("[::1]")); + assertTrue(HostPortValidator.getInstance().isValid("[::1]:8888")); + + assertFalse(HostPortValidator.getInstance().isValid("2001:0db8:85a3:08d3:1319:8a2e:0370:7344:8888")); + assertFalse(HostPortValidator.getInstance().isValid("[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]]:8888")); + assertFalse(HostPortValidator.getInstance().isValid("[2001:0db8:85a3:08d3:1319:8a2e:0370:7344:8888")); + assertFalse(HostPortValidator.getInstance().isValid("2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:8888")); + assertFalse(HostPortValidator.getInstance().isValid("[::1]:")); + assertFalse(HostPortValidator.getInstance().isValid("[]")); + } + + public void testHostnames() { + assertTrue(HostPortValidator.getInstance().isValid("myproxy")); + assertTrue(HostPortValidator.getInstance().isValid("myproxy:8888")); + assertTrue(HostPortValidator.getInstance().isValid("proxy.example.com")); + assertTrue(HostPortValidator.getInstance().isValid("proxy.example.com:8888")); + + assertFalse(HostPortValidator.getInstance().isValid("http://proxy.example.com")); + assertFalse(HostPortValidator.getInstance().isValid("http://proxy.example.com:8888")); + } +} diff --git a/java/code/src/com/redhat/rhn/frontend/action/satellite/GeneralConfigAction.java b/java/code/src/com/redhat/rhn/frontend/action/satellite/GeneralConfigAction.java index 257d296..5514537 100644 --- a/java/code/src/com/redhat/rhn/frontend/action/satellite/GeneralConfigAction.java +++ b/java/code/src/com/redhat/rhn/frontend/action/satellite/GeneralConfigAction.java @@ -16,6 +16,7 @@ package com.redhat.rhn.frontend.action.satellite; import com.redhat.rhn.common.conf.Config; import com.redhat.rhn.common.conf.ConfigDefaults; +import com.redhat.rhn.common.validator.HostPortValidator; import com.redhat.rhn.common.validator.ValidatorError; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.frontend.struts.RequestContext; @@ -212,7 +213,16 @@ public class GeneralConfigAction extends BaseConfigAction { */ private ActionErrors validateForm(DynaActionForm form) { ActionErrors errors = new ActionErrors(); - String email = (String) form.get(translateFormPropertyName("traceback_mail")); + + // Check if proxy is given as host:port + String proxy = (String) form.get( + translateFormPropertyName("server.satellite.http_proxy")); + HostPortValidator validator = HostPortValidator.getInstance(); + if (!(proxy.equals("") || validator.isValid(proxy))) { + errors.add(ActionMessages.GLOBAL_MESSAGE, + new ActionMessage("error.proxy_invalid")); + } + String password = (String) form.get( translateFormPropertyName("server.satellite.http_proxy_password")); String confirmationPassword = (String) form.get( diff --git a/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml b/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml index 86e3bd7..507e32d 100644 --- a/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml +++ b/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml @@ -1179,6 +1179,14 @@ http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd" <context context-type="sourcefile">com.redhat.rhn.frontend.action.monitoring.notification.AbstractFilterEditAction</context> </context-group> </trans-unit> + + <trans-unit id="error.proxy_invalid"> +<source>HTTP proxy needs to be specified as host:port.</source> + <context-group name="ctx"> + <context context-type="sourcefile">/rhn/admin/config/GeneralConfig</context> + </context-group> + </trans-unit> + <trans-unit id="/rhn/"> <source>That username is already taken; please choose another.</source> <context-group name="ctx"> -- 1.7.10.4
_______________________________________________ Spacewalk-devel mailing list Spacewalk-devel@redhat.com https://www.redhat.com/mailman/listinfo/spacewalk-devel