001: /*
002: *
003: * Jsmtpd, Java SMTP daemon
004: * Copyright (C) 2005 Jean-Francois POUX, jf.poux@laposte.net
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: */
021: package org.jsmtpd.plugins.filters.builtin;
022:
023: import java.util.HashMap;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.Vector;
028:
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031: import org.jsmtpd.core.common.PluginInitException;
032: import org.jsmtpd.core.common.PluginStore;
033: import org.jsmtpd.core.common.acl.IACL;
034: import org.jsmtpd.core.common.filter.FilterTreeFailureException;
035: import org.jsmtpd.core.common.filter.FilterTreeSuccesException;
036: import org.jsmtpd.core.common.filter.IFilter;
037: import org.jsmtpd.core.mail.Email;
038: import org.jsmtpd.core.mail.EmailAddress;
039: import org.jsmtpd.core.mail.Rcpt;
040:
041: /**
042: * @author Jean-Francois POUX
043: */
044: public class RcptRewrite implements IFilter {
045:
046: private Map<EmailAddress, EmailAddress> rewriteMap = new HashMap<EmailAddress, EmailAddress>();
047: private Map<EmailAddress, EmailAddress> catchAllMap = new HashMap<EmailAddress, EmailAddress>();
048: private IACL acl = null;
049:
050: private Log log = LogFactory.getLog(RcptRewrite.class);
051:
052: public boolean doFilter(Email input)
053: throws FilterTreeFailureException,
054: FilterTreeSuccesException {
055: List<Rcpt> rcpts = input.getRcpt();
056: Vector<Rcpt> pendingRemove = new Vector<Rcpt>();
057:
058: for (Iterator iter = rcpts.iterator(); iter.hasNext();) {
059: Rcpt element = (Rcpt) iter.next();
060: EmailAddress rcpt = element.getEmailAddress();
061:
062: // Check if rcpt is in rw map, then apply rw
063: if (rewriteMap.containsKey(rcpt)) {
064: EmailAddress newRcpt = (EmailAddress) rewriteMap
065: .get(rcpt);
066: if (newRcpt != null) {
067: log.info("rcpt " + rcpt.toString() + " is now "
068: + newRcpt + " in mail "
069: + input.getDiskName());
070: element.setEmailAddress(newRcpt);
071: } else {
072: log.info("Removed rcpt " + rcpt.toString()
073: + " in mail " + input.getDiskName());
074: pendingRemove.add(element);
075: }
076:
077: } else //might be a catchall
078: {
079: // Apply catch all if the catchall is defined AND if the user is not excplicitly defined
080: if (catchAllMap.keySet().contains(rcpt)
081: && !acl.isValidAddressStandardUser(rcpt)) {
082: EmailAddress newRcpt = (EmailAddress) catchAllMap
083: .get(rcpt);
084: if (newRcpt != null) {
085: log.info("rcpt " + rcpt.toString()
086: + " is now at catch all " + newRcpt
087: + " in mail " + input.getDiskName());
088: element.setEmailAddress(newRcpt);
089: } else {
090: log.info("Removed rcpt by catchall "
091: + rcpt.toString() + " in mail "
092: + input.getDiskName());
093: pendingRemove.add(element);
094: }
095: }//else leave alone
096: }
097: }//end for loop over rcpt
098:
099: // Apply pendings
100: for (Iterator iter = pendingRemove.iterator(); iter.hasNext();) {
101: Rcpt element = (Rcpt) iter.next();
102: rcpts.remove(element);
103: }
104:
105: return true;
106: }
107:
108: public String getPluginName() {
109: return "Recipient Rewriter for Jsmtpd";
110: }
111:
112: public void initPlugin() throws PluginInitException {
113: acl = PluginStore.getInstance().getAcl();
114: if (acl == null)
115: throw new PluginInitException();
116: }
117:
118: public void shutdownPlugin() {
119:
120: }
121:
122: public void setRewrite(String in) throws Exception {
123: if (!in.contains(","))
124: throw new Exception(
125: "Property set must be user@domain,user2@domain2");
126: String[] args = in.split(",");
127:
128: EmailAddress from = EmailAddress.parseAddress(args[0]);
129: EmailAddress to;
130: if (args[1].equals("remove"))
131: to = null;
132: else
133: to = EmailAddress.parseAddress(args[1]);
134:
135: if (rewriteMap.containsKey(from))
136: throw new Exception("Alias already defined");
137:
138: rewriteMap.put(from, to);
139: }
140:
141: public void setCatchAll(String in) throws Exception {
142: if (!in.contains(","))
143: throw new Exception(
144: "Property set must be *@domain,user2@domain2");
145: String[] args = in.split(",");
146:
147: if (!args[0].contains("*"))
148: throw new Exception(
149: "Property set must be *@domain,user2@domain2");
150: if (args[1].contains("*"))
151: throw new Exception(
152: "Property set must be *@domain,user2@domain2");
153:
154: EmailAddress to;
155: EmailAddress from = EmailAddress.parseAddress(args[0]);
156:
157: if (args[1].equals("remove"))
158: to = null;
159: else
160: to = EmailAddress.parseAddress(args[1]);
161:
162: if (catchAllMap.containsKey(from))
163: throw new Exception("Catch All already defined");
164:
165: catchAllMap.put(from, to);
166: }
167: }
|