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.DNSRequest;
025    import org.apache.james.jspf.core.DNSResponse;
026    import org.apache.james.jspf.core.MacroExpand;
027    import org.apache.james.jspf.core.SPFChecker;
028    import org.apache.james.jspf.core.SPFCheckerDNSResponseListener;
029    import org.apache.james.jspf.core.SPFSession;
030    import org.apache.james.jspf.core.SPFTermsRegexps;
031    import org.apache.james.jspf.core.exceptions.NeutralException;
032    import org.apache.james.jspf.core.exceptions.NoneException;
033    import org.apache.james.jspf.core.exceptions.PermErrorException;
034    import org.apache.james.jspf.core.exceptions.TempErrorException;
035    import org.apache.james.jspf.core.exceptions.TimeoutException;
036    
037    import java.util.List;
038    
039    /**
040     * This class represent the exists mechanism
041     */
042    public class ExistsMechanism extends GenericMechanism implements SPFCheckerDNSResponseListener {
043    
044        private final class ExpandedChecker implements SPFChecker {
045           
046            /*
047             * (non-Javadoc)
048             * @see org.apache.james.jspf.core.SPFChecker#checkSPF(org.apache.james.jspf.core.SPFSession)
049             */
050            public DNSLookupContinuation checkSPF(SPFSession spfData) throws PermErrorException,
051                    TempErrorException, NeutralException, NoneException {
052                String host = expandHost(spfData);
053                return new DNSLookupContinuation(new DNSRequest(host,DNSRequest.A), ExistsMechanism.this);
054            }
055        }
056    
057        /**
058         * ABNF: exists = "exists" ":" domain-spec
059         */
060        public static final String REGEX = "[eE][xX][iI][sS][tT][sS]" + "\\:"
061                + SPFTermsRegexps.DOMAIN_SPEC_REGEX;
062    
063        private SPFChecker expandedChecker = new ExpandedChecker();
064    
065        /**
066         * @see org.apache.james.jspf.core.SPFChecker#checkSPF(org.apache.james.jspf.core.SPFSession)
067         */
068        public DNSLookupContinuation checkSPF(SPFSession spfData) throws PermErrorException,
069                TempErrorException, NeutralException, NoneException {
070            // update currentDepth
071            spfData.increaseCurrentDepth();
072    
073            spfData.pushChecker(expandedChecker);
074            return macroExpand.checkExpand(getDomain(), spfData, MacroExpand.DOMAIN);
075        }
076    
077        /**
078         * @see org.apache.james.jspf.core.SPFCheckerDNSResponseListener#onDNSResponse(org.apache.james.jspf.core.DNSResponse, org.apache.james.jspf.core.SPFSession)
079         */
080        public DNSLookupContinuation onDNSResponse(DNSResponse response, SPFSession spfSession) throws PermErrorException, TempErrorException {
081            List<String> aRecords;
082            
083            try {
084                aRecords = response.getResponse();
085            } catch (TimeoutException e) {
086                spfSession.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.FALSE);
087                return null;
088            }
089            
090            if (aRecords != null && aRecords.size() > 0) {
091                spfSession.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.TRUE);
092                return null;
093            }
094            
095            // No match found
096            spfSession.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.FALSE);
097            return null;
098        }
099    
100        /**
101         * @see java.lang.Object#toString()
102         */
103        public String toString() {
104            return "exists:"+getDomain();
105        }
106    
107    }