/************************************************************************* * Copyright 2009-2014 Eucalyptus Systems, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need * additional information or have any questions. ************************************************************************/ package com.eucalyptus.cloudformation.template.url; import java.net.URL; import java.util.StringTokenizer; import java.util.regex.Pattern; /** * Created by ethomas on 9/18/14. */ public class WhiteListURLMatcher { private static final String[] SUPPORTED_PROTOCOLS = new String[] {"http", "https"}; public static boolean urlIsAllowed(URL url, String whiteList) { if (whiteList == null) return false; boolean unsupportedProtocol = true; for (String protocol: SUPPORTED_PROTOCOLS) { if (protocol.equalsIgnoreCase(url.getProtocol())) { unsupportedProtocol = false; break; } } if (unsupportedProtocol) return false; String[] whiteListPatterns = whiteList.split("\\,"); boolean supportedPattern = false; if (whiteListPatterns != null) { for (String whiteListPattern: whiteListPatterns) { whiteListPattern = whiteListPattern.trim(); // check if the pattern includes a protocol String includedProtocol = null; for (String protocol: SUPPORTED_PROTOCOLS) { if (whiteListPattern.toLowerCase().startsWith(protocol.toLowerCase() + "://")) { includedProtocol = protocol; whiteListPattern = whiteListPattern.substring(protocol.toLowerCase().length() + "://".length()); break; } } if (matchesString(whiteListPattern.toLowerCase(), url.getHost().toLowerCase()) && (includedProtocol == null || includedProtocol.equalsIgnoreCase(url.getProtocol()))) { supportedPattern = true; break; } } } return supportedPattern; } private static boolean matchesString(String pattern, String target) { // We want to check just against ? and * in the pattern, but need to be careful if the string contains other reg-exp characters StringTokenizer stok = new StringTokenizer(pattern, "*?", true); // tokenize on * and ? and leave those tokens in there StringBuilder newPattern = new StringBuilder(); while (stok.hasMoreTokens()) { String currentToken = stok.nextToken(); if ("*".equals(currentToken)) { newPattern.append(".*"); } else if ("?".equals(currentToken)) { newPattern.append(".?"); } else { newPattern.append(Pattern.quote(currentToken)); // literal values for everything else } } return target.matches(newPattern.toString()); } }