Skip to content
Permalink
Browse files

[JENKINS-51223] catch more domain suffix based no_proxy matches (add …

…curl-like algorithm to existing regexp)

remove some of the duplicate JnlpAgentEndpointResolver/Util code
  • Loading branch information
gabemontero committed May 17, 2018
1 parent 3cc5305 commit 0272a4302e5eb3d619530fdb3e1ab4f45663a9b3
@@ -30,7 +30,8 @@
*
* @author Kohsuke Kawaguchi
*/
class Util {
@Restricted(NoExternalUse.class)
public class Util {
/**
* Gets the file name portion from a qualified '/'-separate resource path name.
*
@@ -108,7 +109,7 @@ static String indent(String s) {
*
* Warning: this method won't match shortened representation of IPV6 address
*/
static boolean inNoProxyEnvVar(@Nonnull String host) {
public static boolean inNoProxyEnvVar(@Nonnull String host) {
String noProxy = System.getenv("no_proxy");
if (noProxy != null) {
noProxy = noProxy.trim()
@@ -124,6 +125,7 @@ static boolean inNoProxyEnvVar(@Nonnull String host) {
}
else {
int depth = 0;
String originalHost = host;
// Loop while we have a valid domain name: acme.com
// We add a safeguard to avoid a case where the host would always be valid because the regex would
// for example fail to remove subdomains.
@@ -135,8 +137,13 @@ static boolean inNoProxyEnvVar(@Nonnull String host) {
if (noProxy.matches(".*(^|,)\\Q" + host + "\\E($|,).*"))
return true;
// Remove first subdomain: master.jenkins.acme.com -> jenkins.acme.com
else
host = host.replaceFirst("^[a-z0-9]+(-[a-z0-9]+)*\\.", "");
host = host.replaceFirst("^[a-z0-9]+(-[a-z0-9]+)*\\.", "");
}

String[] noProxyArray = noProxy.split(",");
// fix for https://issues.jenkins-ci.org/browse/JENKINS-51223, basic suffix match
if (depth > 0 && suffixMatch(originalHost, noProxyArray)) {
return true;
}
}
}
@@ -145,6 +152,20 @@ static boolean inNoProxyEnvVar(@Nonnull String host) {
return false;
}

// fix for https://issues.jenkins-ci.org/browse/JENKINS-51223
// adds curl-like algorithm for matching to existing regexp used in
// inNoProxyEnvVars
static boolean suffixMatch(String host, String[] noProxyArray) {
for (String proxy : noProxyArray) {
// still needs to capture some form of subdomain, like ".svc"
if (!proxy.contains("."))
continue;
if (host.endsWith(proxy))
return true;
}
return false;
}

/**
* Gets URL connection.
* If http_proxy environment variable exists, the connection uses the proxy.
@@ -24,6 +24,8 @@
package org.jenkinsci.remoting.engine;

import hudson.remoting.Base64;
import hudson.remoting.Util;

import org.jenkinsci.remoting.util.https.NoCheckHostnameVerifier;
import org.jenkinsci.remoting.util.https.NoCheckTrustManager;

@@ -498,58 +500,8 @@ static URLConnection openURLConnection(URL url, String credentials, String proxy
return con;
}

/**
* Check if given URL is in the exclusion list defined by the no_proxy environment variable.
* On most *NIX system wildcards are not supported but if one top domain is added, all related subdomains will also
* be ignored. Both "mit.edu" and ".mit.edu" are valid syntax.
* http://www.gnu.org/software/wget/manual/html_node/Proxies.html
*
* Regexp:
* - \Q and \E: https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
* - To match IPV4/IPV/FQDN: Regular Expressions Cookbook, 2nd Edition (ISBN: 9781449327453)
*
* Warning: this method won't match shortened representation of IPV6 address
*
* FIXME: duplicate of hudson.remoting.Util.inNoProxyEnvVar
*/
static boolean inNoProxyEnvVar(String host) {
String noProxy = System.getenv("no_proxy");
if (noProxy != null) {
noProxy = noProxy.trim()
// Remove spaces
.replaceAll("\\s+", "")
// Convert .foobar.com to foobar.com
.replaceAll("((?<=^|,)\\.)*(([a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,})(?=($|,))", "$2");

if (!noProxy.isEmpty()) {
// IPV4 and IPV6
if (host.matches("^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$") || host
.matches("^(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$")) {
return noProxy.matches(".*(^|,)\\Q" + host + "\\E($|,).*");
} else {
int depth = 0;
// Loop while we have a valid domain name: acme.com
// We add a safeguard to avoid a case where the host would always be valid because the regex would
// for example fail to remove subdomains.
// According to Wikipedia (no RFC defines it), 128 is the max number of subdivision for a valid
// FQDN:
// https://en.wikipedia.org/wiki/Subdomain#Overview
while (host.matches("^([a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,}$") && depth < 128) {
++depth;
// Check if the no_proxy contains the host
if (noProxy.matches(".*(^|,)\\Q" + host + "\\E($|,).*")) {
return true;
}
// Remove first subdomain: master.jenkins.acme.com -> jenkins.acme.com
else {
host = host.replaceFirst("^[a-z0-9]+(-[a-z0-9]+)*\\.", "");
}
}
}
}
}

return false;
return Util.inNoProxyEnvVar(host);
}

@CheckForNull
@@ -121,6 +121,47 @@ public void testSubFQDNWithDot() {

assertEquals(false, Util.inNoProxyEnvVar("foobar.com"));
}

@Test
public void testSubFWDNWithDotMinimalSuffix() {
PowerMockito.when(System.getenv("no_proxy")).thenReturn(".svc");

assertEquals(true, Util.inNoProxyEnvVar("bn-myproj.svc"));
}

@Test
public void testSubFWDNWithDotMinimalSuffixMixedCase() {
PowerMockito.when(System.getenv("no_proxy")).thenReturn(".svc,.default,.local,localhost,.boehringer.com,10.250.0.0/16,10.251.0.0/16,10.183.195.106,10.183.195.107,10.183.195.108,10.183.195.109,10.183.195.11,10.183.195.111,10.183.195.112,10.183.195.113,10.183.195.13,10.250.127.");

assertEquals(true, Util.inNoProxyEnvVar("bn-myproj.svc"));
}

@Test
public void testNoProxyWithInvalidChars() {
PowerMockito.when(System.getenv("no_proxy")).thenReturn("foo+.co=m");

assertEquals(false, Util.inNoProxyEnvVar("foo+.co=m"));
}

@Test
public void testNoProxyWithInvalidChar() {
PowerMockito.when(System.getenv("no_proxy")).thenReturn("foo.co=m");

assertEquals(false, Util.inNoProxyEnvVar("foo.co=m"));
}

@Test
public void testNoProxyWithInvalidCharInMinimalSuffix() {
PowerMockito.when(System.getenv("no_proxy")).thenReturn(".sv=c");

assertEquals(false, Util.inNoProxyEnvVar("foo.sv=c"));
}
@Test
public void testSubFWDNWithoutDotMinimalSuffix() {
PowerMockito.when(System.getenv("no_proxy")).thenReturn("svc");

assertEquals(false, Util.inNoProxyEnvVar("bn-myproj.svc"));
}

@Test
public void testMixed() {

0 comments on commit 0272a43

Please sign in to comment.
You can’t perform that action at this time.