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.Inet6Address; 25 26 /** 27 * @version $Revision$ $Date$ 28 */ 29 public class NetmaskIPv6AddressPermission implements IPAddressPermission { 30 private static final Pattern MASK_VALIDATOR = Pattern.compile("^(([a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4})/((\\d{1,3})|(([a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}))$"); 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[] networkAddressBytes; 38 private final byte[] netmaskBytes; 39 40 public NetmaskIPv6AddressPermission(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 networkAddressBytes = new byte[16]; 47 int pos = 0; 48 StringTokenizer tokenizer = new StringTokenizer(matcher.group(1), ":"); 49 while (tokenizer.hasMoreTokens()) { 50 String token = tokenizer.nextToken(); 51 int value = Integer.parseInt(token, 16); 52 networkAddressBytes[pos++] = (byte) ((value & 0xff00) >> 8); 53 networkAddressBytes[pos++] = (byte) value; 54 } 55 56 netmaskBytes = new byte[16]; 57 String netmask = matcher.group(4); 58 if (null != netmask) { 59 int value = Integer.parseInt(netmask); 60 pos = value / 8; 61 int shift = 8 - value % 8; 62 for (int i = 0; i < pos; i++) { 63 netmaskBytes[i] = (byte) 0xff; 64 } 65 netmaskBytes[pos] = (byte) (0xff << shift); 66 } else { 67 pos = 0; 68 tokenizer = new StringTokenizer(matcher.group(5), ":"); 69 while (tokenizer.hasMoreTokens()) { 70 String token = tokenizer.nextToken(); 71 int value = Integer.parseInt(token, 16); 72 netmaskBytes[pos++] = (byte) ((value & 0xff00) >> 8); 73 netmaskBytes[pos++] = (byte) value; 74 } 75 } 76 } 77 78 public boolean implies(InetAddress address) { 79 if (false == address instanceof Inet6Address) { 80 return false; 81 } 82 83 byte[] byteAddress = address.getAddress(); 84 for (int i = 0; i < 16; i++) { 85 if ((netmaskBytes[i] & byteAddress[i]) != networkAddressBytes[i]) { 86 return false; 87 } 88 } 89 return true; 90 } 91 }