001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.shiro.web.filter.authz; 020 021import org.apache.shiro.lang.util.StringUtils; 022 023import javax.servlet.ServletRequest; 024import javax.servlet.ServletResponse; 025import java.util.regex.Pattern; 026import java.util.Map; 027 028/** 029 * A Filter that can allow or deny access based on the host that sent the request. 030 * 031 * <b>WARNING:</b> NOT YET FULLY IMPLEMENTED!!! Work in progress. 032 * 033 * @since 1.0 034 */ 035@SuppressWarnings("checkstyle:JavadocVariable") 036public class HostFilter extends AuthorizationFilter { 037 038 /** 039 * IPV4 quad regex. 040 */ 041 public static final String IPV4_QUAD_REGEX = "(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2(?:[0-4][0-9]|5[0-5]))"; 042 043 /** 044 * IPV4 regex. 045 */ 046 public static final String IPV4_REGEX = "(?:" + IPV4_QUAD_REGEX + "\\.){3}" + IPV4_QUAD_REGEX + "$"; 047 048 /** 049 * IPV4 pattern. 050 */ 051 public static final Pattern IPV4_PATTERN = Pattern.compile(IPV4_REGEX); 052 053 public static final String PRIVATE_CLASS_B_SUBSET = "(?:1[6-9]|2[0-9]|3[0-1])"; 054 055 public static final String PRIVATE_CLASS_A_REGEX = "10\\.(?:" + IPV4_QUAD_REGEX + "\\.){2}" + IPV4_QUAD_REGEX + "$"; 056 057 public static final String PRIVATE_CLASS_B_REGEX = 058 "172\\." + PRIVATE_CLASS_B_SUBSET + "\\." + IPV4_QUAD_REGEX + "\\." + IPV4_QUAD_REGEX + "$"; 059 060 public static final String PRIVATE_CLASS_C_REGEX = "192\\.168\\." + IPV4_QUAD_REGEX + "\\." + IPV4_QUAD_REGEX + "$"; 061 062 //user-configured IP (which can be wildcarded) to constructed regex mapping 063 Map<String, String> authorizedIps; 064 Map<String, String> deniedIps; 065 Map<String, String> authorizedHostnames; 066 Map<String, String> deniedHostnames; 067 068 069 public void setAuthorizedHosts(String authorizedHosts) { 070 if (!StringUtils.hasText(authorizedHosts)) { 071 throw new IllegalArgumentException("authorizedHosts argument cannot be null or empty."); 072 } 073 String[] hosts = StringUtils.tokenizeToStringArray(authorizedHosts, ", \t"); 074 075 for (String host : hosts) { 076 //replace any periods with \\. to ensure the regex works: 077 String periodsReplaced = host.replace(".", "\\."); 078 //check for IPv4: 079 String wildcardsReplaced = periodsReplaced.replace("*", IPV4_QUAD_REGEX); 080 081 if (IPV4_PATTERN.matcher(wildcardsReplaced).matches()) { 082 authorizedIps.put(host, wildcardsReplaced); 083 } 084 } 085 086 } 087 088 public void setDeniedHosts(String deniedHosts) { 089 if (!StringUtils.hasText(deniedHosts)) { 090 throw new IllegalArgumentException("deniedHosts argument cannot be null or empty."); 091 } 092 } 093 094 protected boolean isIpv4Candidate(String host) { 095 String[] quads = StringUtils.tokenizeToStringArray(host, "."); 096 if (quads == null || quads.length != 4) { 097 return false; 098 } 099 for (String quad : quads) { 100 if (!quad.equals("*")) { 101 try { 102 Integer.parseInt(quad); 103 } catch (NumberFormatException nfe) { 104 return false; 105 } 106 } 107 } 108 return true; 109 } 110 111 protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception { 112 throw new UnsupportedOperationException("Not yet fully implemented!!!"); 113 } 114}