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
022
023 package org.apache.james.protocols.smtp.core.fastfail;
024
025 import org.apache.james.protocols.smtp.SMTPRetCode;
026 import org.apache.james.protocols.smtp.SMTPSession;
027 import org.apache.james.protocols.smtp.dsn.DSNStatus;
028 import org.apache.james.protocols.smtp.hook.HookResult;
029 import org.apache.james.protocols.smtp.hook.HookReturnCode;
030 import org.apache.james.protocols.smtp.hook.RcptHook;
031 import org.apache.mailet.MailAddress;
032
033
034 /**
035 * Handler which want todo an recipient check should extend this
036 *
037 */
038 public abstract class AbstractValidRcptHandler implements RcptHook {
039
040
041 /**
042 * @see org.apache.james.protocols.smtp.hook.RcptHook#doRcpt(org.apache.james.protocols.smtp.SMTPSession, org.apache.mailet.MailAddress, org.apache.mailet.MailAddress)
043 */
044 public HookResult doRcpt(SMTPSession session, MailAddress sender, MailAddress rcpt) {
045 boolean reject = false;
046
047 if (session.isRelayingAllowed()) {
048 // check if the domain is local, if so we still want to check if the recipient is valid or not as we want to fail fast in such cases
049 if (isLocalDomain(session, rcpt.getDomain())) {
050 if (isValidRecipient(session, rcpt) == false) {
051 reject = true;
052 }
053 }
054 } else {
055 if (isLocalDomain(session, rcpt.getDomain()) == false) {
056 session.getLogger().debug("Unknown domain " + rcpt.getDomain() + " so reject it");
057
058 } else {
059 if (isValidRecipient(session, rcpt) == false) {
060 reject= true;
061 }
062 }
063 }
064
065 if (reject) {
066 //user not exist
067 session.getLogger().info("Rejected message. Unknown user: " + rcpt.toString());
068 return new HookResult(HookReturnCode.DENY,SMTPRetCode.MAILBOX_PERM_UNAVAILABLE, DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.ADDRESS_MAILBOX) + " Unknown user: " + rcpt.toString());
069 } else {
070 return new HookResult(HookReturnCode.DECLINED);
071 }
072 }
073
074
075 /**
076 * Return true if email for the given recipient should get accepted
077 *
078 * @param recipient
079 * @return isValid
080 */
081 protected abstract boolean isValidRecipient(SMTPSession session, MailAddress recipient);
082
083 /**
084 * Return true if the domain is local
085 *
086 * @param session
087 * @param domain
088 * @return local
089 */
090 protected abstract boolean isLocalDomain(SMTPSession session, String domain);
091 }