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 ****************************************************************/
019
020
021 package org.apache.james.jspf.terms;
022
023 import org.apache.james.jspf.core.DNSLookupContinuation;
024 import org.apache.james.jspf.core.IPAddr;
025 import org.apache.james.jspf.core.Inet6Util;
026 import org.apache.james.jspf.core.SPFSession;
027 import org.apache.james.jspf.core.exceptions.PermErrorException;
028
029 /**
030 * This class represent the ip4 mechanism
031 *
032 */
033 public class IP4Mechanism extends GenericMechanism {
034
035 /**
036 * ABNF: IP4 = "ip4" ":" ip4-network [ ip4-cidr-length ]
037 */
038 public static final String REGEX = "[iI][pP][4]" + "\\:" + "([0-9.]+)"
039 + "(?:" + IP4_CIDR_LENGTH_REGEX + ")?";
040
041 private IPAddr ip = null;
042
043 /**
044 * @see org.apache.james.jspf.core.SPFChecker#checkSPF(org.apache.james.jspf.core.SPFSession)
045 */
046 public DNSLookupContinuation checkSPF(SPFSession spfData) throws PermErrorException {
047 IPAddr originalIP;
048
049 originalIP = IPAddr.getAddress(spfData.getIpAddress(), getIp()
050 .getMaskLength());
051
052 spfData.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.valueOf(getIp().getMaskedIPAddress().equals(originalIP.getMaskedIPAddress())));
053
054 return null;
055 }
056
057 /**
058 * @see org.apache.james.jspf.terms.GenericMechanism#config(org.apache.james.jspf.terms.Configuration)
059 */
060 public synchronized void config(Configuration params) throws PermErrorException {
061 if (params.groupCount() == 0) {
062 throw new PermErrorException("Missing ip");
063 }
064 String ipString = params.group(1);
065 if (!isValidAddress(ipString)) {
066 throw new PermErrorException("Invalid Address: " + ipString);
067 }
068 int maskLength = getMaxCidr();
069 if (params.groupCount() >= 2 && params.group(2) != null) {
070 String maskLengthString = params.group(2);
071 maskLength = Integer.parseInt(maskLengthString);
072
073 if (maskLength > getMaxCidr() || (maskLengthString.length() > 1 && maskLengthString.startsWith("0"))) {
074 throw new PermErrorException("Invalid CIDR: " + maskLengthString);
075 }
076 }
077 ip = IPAddr.getAddress(ipString, maskLength);
078 }
079
080 /**
081 * @see org.apache.james.jspf.core.Inet6Util#isValidIPV4Address(String)
082 */
083 protected boolean isValidAddress(String ipString) {
084 return Inet6Util.isValidIPV4Address(ipString);
085 }
086
087 /**
088 * Returns the max cidr for ip4
089 *
090 * @return maxCidr The max cidr
091 */
092 protected int getMaxCidr() {
093 return 32;
094 }
095
096 /**
097 * @return Returns the ip.
098 */
099 protected synchronized IPAddr getIp() {
100 return ip;
101 }
102
103 /**
104 * @see java.lang.Object#toString()
105 */
106 public String toString() {
107 if (getIp().getMaskLength() == getMaxCidr()) {
108 return "ip4:"+getIp().getIPAddress();
109 } else {
110 return "ip4:"+getIp().getIPAddress()+"/"+getIp().getMaskLength();
111 }
112 }
113
114 }