1 /** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one or more 4 * contributor license agreements. See the NOTICE file distributed with 5 * this work for additional information regarding copyright ownership. 6 * The ASF licenses this file to You under the Apache License, Version 2.0 7 * (the "License"); you may not use this file except in compliance with 8 * the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 package org.apache.openejb.server.auth; 19 20 import java.util.regex.Pattern; 21 import java.util.regex.Matcher; 22 import java.util.StringTokenizer; 23 import java.net.InetAddress; 24 import java.net.Inet4Address; 25 26 /** 27 * @version $Revision$ $Date$ 28 */ 29 public class FactorizedIPAddressPermission implements IPAddressPermission { 30 private static final Pattern MASK_VALIDATOR = Pattern.compile("^((\\d{1,3}){1}(\\.\\d{1,3}){0,2}\\.)?\\{(\\d{1,3}){1}((,\\d{1,3})*)\\}$"); 31 32 public static boolean canSupport(String mask) { 33 Matcher matcher = MASK_VALIDATOR.matcher(mask); 34 return matcher.matches(); 35 } 36 37 private final byte[] prefixBytes; 38 private final byte[] suffixBytes; 39 40 public FactorizedIPAddressPermission(String mask) { 41 Matcher matcher = MASK_VALIDATOR.matcher(mask); 42 if (false == matcher.matches()) { 43 throw new IllegalArgumentException("Mask " + mask + " does not match pattern " + MASK_VALIDATOR.pattern()); 44 } 45 46 // group 1 is the factorized IP part. 47 // e.g. group 1 in "1.2.3.{4,5,6}" is "1.2.3." 48 String prefix = matcher.group(1); 49 StringTokenizer tokenizer = new StringTokenizer(prefix, "."); 50 prefixBytes = new byte[tokenizer.countTokens()]; 51 for (int i = 0; i < prefixBytes.length; i++) { 52 String token = tokenizer.nextToken(); 53 int value = Integer.parseInt(token); 54 if (value < 0 || 255 < value) { 55 throw new IllegalArgumentException("byte #" + i + " is not valid."); 56 } 57 prefixBytes[i] = (byte) value; 58 } 59 60 // group 5 is a comma separated list of optional suffixes. 61 // e.g. group 5 in "1.2.3.{4,5,6}" is ",5,6" 62 String suffix = matcher.group(5); 63 tokenizer = new StringTokenizer(suffix, ","); 64 suffixBytes = new byte[1 + tokenizer.countTokens()]; 65 66 // group 4 is the compulsory and first suffix. 67 // e.g. group 4 in "1.2.3.{4,5,6}" is "4" 68 int value = Integer.parseInt(matcher.group(4)); 69 int i = 0; 70 if (value < 0 || 255 < value) { 71 throw new IllegalArgumentException("suffix " + i + " is not valid."); 72 } 73 suffixBytes[i++] = (byte) value; 74 75 for (; i < suffixBytes.length; i++) { 76 String token = tokenizer.nextToken(); 77 value = Integer.parseInt(token); 78 if (value < 0 || 255 < value) { 79 throw new IllegalArgumentException("byte #" + i + " is not valid."); 80 } 81 suffixBytes[i] = (byte) value; 82 } 83 } 84 85 public boolean implies(InetAddress address) { 86 if (false == address instanceof Inet4Address) { 87 return false; 88 } 89 90 byte[] byteAddress = address.getAddress(); 91 for (int i = 0; i < prefixBytes.length; i++) { 92 if (byteAddress[i] != prefixBytes[i]) { 93 return false; 94 } 95 } 96 byte lastByte = byteAddress[prefixBytes.length]; 97 for (int i = 0; i < suffixBytes.length; i++) { 98 if (lastByte == suffixBytes[i]) { 99 return true; 100 } 101 } 102 return false; 103 } 104 }