You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by no...@apache.org on 2006/08/28 20:24:41 UTC

svn commit: r437772 - in /james/server/trunk/src: conf/ java/org/apache/james/smtpserver/core/filter/fastfail/ java/org/apache/james/transport/mailets/ java/org/apache/james/util/ test/org/apache/james/smtpserver/

Author: norman
Date: Mon Aug 28 11:24:41 2006
New Revision: 437772

URL: http://svn.apache.org/viewvc?rev=437772&view=rev
Log:
First setp for Virtual user handlers. See JAMES-597

Added:
    james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/AbstractVirtualUserTableHandler.java
    james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/XMLVirtualUserTableHandler.java
    james/server/trunk/src/java/org/apache/james/util/VirtualUserTableUtil.java
Modified:
    james/server/trunk/src/conf/james-smtphandlerchain.xml
    james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptHandler.java
    james/server/trunk/src/java/org/apache/james/transport/mailets/AbstractVirtualUserTable.java
    james/server/trunk/src/java/org/apache/james/transport/mailets/XMLVirtualUserTable.java
    james/server/trunk/src/test/org/apache/james/smtpserver/ValidRcptHandlerTest.java

Modified: james/server/trunk/src/conf/james-smtphandlerchain.xml
URL: http://svn.apache.org/viewvc/james/server/trunk/src/conf/james-smtphandlerchain.xml?rev=437772&r1=437771&r2=437772&view=diff
==============================================================================
--- james/server/trunk/src/conf/james-smtphandlerchain.xml (original)
+++ james/server/trunk/src/conf/james-smtphandlerchain.xml Mon Aug 28 11:24:41 2006
@@ -95,17 +95,32 @@
      </handler>
      -->
      
+     <!-- IF you want to use the ValidRcptHandler you can set virtual user which will accepted here.-->
+     <!--
+     <handler class="org.apache.james.smtpserver.core.filter.fastfail.XMLVirtualUserTableHandler" command="RCPT">
+         <!- 1:1 mapping ->
+         <mapping>morgoth@middle-earth=sauron@mordor</mapping>
+         <!- 1:n mapping ->
+         <mapping>istari@middle-earth=saruman@isengard;radigast;gandalf</mapping>
+         <!- regex based mapping ->
+         <mapping>*@osgilliath=regex:(.*)@osgilliath:${1}@minas-tirith</mapping>
+         <!- both standard and regex mapping ->
+         <mapping>ring@*=onering@mordor;regex:ring@(.*):ring@${1}</mapping>
+         <!- conditional regex mapping example ->
+         <mapping>*@listserver=regex:(.*)-on@listserver:${1}-subscribe@listserver;
+                               regex:(.*)-off@listserver:${1}-unsubscribe@listserver
+         </mapping>
+     </handler>
+     -->
+         
      <!-- If activated all email will get rejected which has no valid user -->
      <!-- You need to add the recipient to the validRecipient list if you want -->
      <!-- to accept email for a recipient which not exist on the server -->
-     <!-- If you enable the useVirtualUserTable its possible to use this handler with the JDBCVirtualUserTable mailet -->
      <!-- 
      <handler class="org.apache.james.smtpserver.core.filter.fastfail.ValidRcptHandler" command="MAIL">
          <validRecipients> </validRecipients>
          <validDomains> </validDomains>
          <validRegexPattern> </validRegexPattern>
-         <repositoryPath> db://maildb </repositoryPath>
-         <useVirtualUserTable> false </useVirtualUserTable>       
      </handler>
      -->
             

Added: james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/AbstractVirtualUserTableHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/AbstractVirtualUserTableHandler.java?rev=437772&view=auto
==============================================================================
--- james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/AbstractVirtualUserTableHandler.java (added)
+++ james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/AbstractVirtualUserTableHandler.java Mon Aug 28 11:24:41 2006
@@ -0,0 +1,129 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.smtpserver.core.filter.fastfail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.StringTokenizer;
+
+import javax.mail.internet.ParseException;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.james.smtpserver.CommandHandler;
+import org.apache.james.smtpserver.SMTPSession;
+import org.apache.james.util.VirtualUserTableUtil;
+import org.apache.mailet.MailAddress;
+import org.apache.oro.text.regex.MalformedPatternException;
+
+/**
+ * Provides an abstraction of common functionality needed for implementing
+ * a Virtual User Table. Override the <code>mapRecipients</code> method to
+ * map virtual recipients to real recipients.
+ */
+public abstract class AbstractVirtualUserTableHandler extends AbstractLogEnabled
+    implements CommandHandler {
+    
+    public final static String VALID_USER = "VALID_USER";
+    
+    /**
+     * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
+     */
+    public void onCommand(SMTPSession session) {
+        MailAddress rcpt = (MailAddress) session.getState().get(SMTPSession.CURRENT_RECIPIENT);
+
+        // remove old state
+        session.getState().remove(VALID_USER);
+    
+        String targetString = mapRecipients(rcpt);
+
+        // Only non-null mappings are translated
+        if (targetString != null) {
+            if (targetString.startsWith("error:")) {
+                // No valid mapping
+                return;
+            } else {
+                StringTokenizer tokenizer = new StringTokenizer(targetString,
+                VirtualUserTableUtil.getSeparator(targetString));
+
+                while (tokenizer.hasMoreTokens()) {
+                    String targetAddress = tokenizer.nextToken().trim();
+
+
+                    if (targetAddress.startsWith("regex:")) {   
+                        try {
+                targetAddress = VirtualUserTableUtil.regexMap(rcpt, targetAddress);
+            } catch (MalformedPatternException e) {
+                            getLogger().error("Exception during regexMap processing: ", e);
+            }
+
+
+                        if (targetAddress == null)
+                            continue;
+                        }
+
+                        try {
+                            MailAddress target = (targetAddress.indexOf('@') < 0) ? new MailAddress(targetAddress, "localhost")
+                                : new MailAddress(targetAddress);
+
+                            session.getState().put(VALID_USER, target);
+
+    
+                            StringBuffer buf = new StringBuffer().append(
+                                "Valid virtual user mapping ").append(rcpt)
+                                .append(" to ").append(target);
+                            getLogger().debug(buf.toString());
+    
+
+                        } catch (ParseException pe) {
+                            //Don't map this address... there's an invalid address mapping here
+                            StringBuffer exceptionBuffer = new StringBuffer(128)
+                                .append("There is an invalid map from ")
+                                .append(rcpt).append(" to ").append(
+                                targetAddress);
+                            getLogger().error(exceptionBuffer.toString());
+                            continue;
+                        }
+                   }
+               }
+           }
+      }
+
+    /**
+     * Override to map virtual recipients to real recipients, both local and non-local.
+     * Each key in the provided map corresponds to a potential virtual recipient, stored as
+     * a <code>MailAddress</code> object.
+     * 
+     * Translate virtual recipients to real recipients by mapping a string containing the
+     * address of the real recipient as a value to a key. Leave the value <code>null<code>
+     * if no mapping should be performed. Multiple recipients may be specified by delineating
+     * the mapped string with commas, semi-colons or colons.
+     * 
+     * @param recipientsMap the mapping of virtual to real recipients, as 
+     *    <code>MailAddress</code>es to <code>String</code>s.
+     */
+    protected abstract String mapRecipients(MailAddress recipient);;
+    
+    public Collection getImplCommands() {
+        Collection c = new ArrayList();
+        c.add("RCPT");
+    
+        return c;
+    }
+}

Modified: james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptHandler.java?rev=437772&r1=437771&r2=437772&view=diff
==============================================================================
--- james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptHandler.java (original)
+++ james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptHandler.java Mon Aug 28 11:24:41 2006
@@ -22,28 +22,17 @@
 
 package org.apache.james.smtpserver.core.filter.fastfail;
 
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.StringTokenizer;
 
-import org.apache.avalon.cornerstone.services.datasources.DataSourceSelector;
-import org.apache.avalon.excalibur.datasource.DataSourceComponent;
-import org.apache.avalon.framework.activity.Initializable;
 import org.apache.avalon.framework.configuration.Configurable;
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.avalon.framework.service.ServiceException;
-import org.apache.avalon.framework.service.ServiceManager;
-import org.apache.avalon.framework.service.Serviceable;
 import org.apache.james.smtpserver.CommandHandler;
 import org.apache.james.smtpserver.SMTPSession;
-import org.apache.james.util.JDBCUtil;
 import org.apache.james.util.mail.dsn.DSNStatus;
 import org.apache.mailet.MailAddress;
 import org.apache.oro.text.regex.MalformedPatternException;
@@ -54,18 +43,12 @@
 /**
  * Handler which reject invalid recipients
  */
-public class ValidRcptHandler extends AbstractLogEnabled implements CommandHandler, Configurable,Serviceable,Initializable{
+public class ValidRcptHandler extends AbstractLogEnabled implements CommandHandler, Configurable {
     
     private Collection recipients = new ArrayList();
     private Collection domains = new ArrayList();
     private Collection regex = new ArrayList();
-    private String repositoryPath;
-    private DataSourceComponent dataSource;
-    private DataSourceSelector selector;
-    private boolean useVirtualUserTable = false;
-    private boolean useSql = false;
-    private String query = "select VirtualUserTable.target_address from VirtualUserTable, VirtualUserTable as VUTDomains where (VirtualUserTable.user like ? or VirtualUserTable.user like '\\%') and (VirtualUserTable.domain like ? or (VirtualUserTable.domain like '\\%' and VUTDomains.domain like ?)) order by concat(VirtualUserTable.user,'@',VirtualUserTable.domain) desc limit 1";
-    
+ 
     /**
      * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
      */
@@ -88,23 +71,6 @@
                 throw new ConfigurationException("Malformed pattern: ", mpe);
             }
         }
-    
-        Configuration virtualUserTableConfig = arg0.getChild("useVirtualUserTable", false);
-        if (virtualUserTableConfig != null) {
-            useVirtualUserTable = virtualUserTableConfig.getValueAsBoolean(false);
-        }
-          
-    
-        Configuration configRepositoryPath = arg0.getChild("repositoryPath", false);
-        if (configRepositoryPath != null) {
-            repositoryPath = configRepositoryPath.getValue();
-            useSql = true;
-            
-            Configuration configQuery = arg0.getChild("query", false);
-            if (configQuery != null) {
-                this.query = configQuery.getValue();
-            } 
-        }  
     }
     
     /**
@@ -124,7 +90,7 @@
     }
 
     /**
-     * Set the valid domains. 
+     * Set the domains for which every rcpt will be accepted. 
      * 
      * @param recip The valid domains. Commaseperated list
      */
@@ -158,13 +124,6 @@
 
         }  
     }
-    
-    /**
-     * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
-     */
-    public void service(ServiceManager arg0) throws ServiceException {
-        selector = (DataSourceSelector) arg0.lookup(DataSourceSelector.ROLE);
-    }
 
     /**
      * @see org.apache.james.smtpserver.CommandHandler#getImplCommands()
@@ -183,7 +142,7 @@
         if (!session.isRelayingAllowed() && !(session.isAuthRequired() && session.getUser() != null)) {
             checkValidRcpt(session);
         } else {
-            getLogger().debug("Sender allowed to relay");
+            getLogger().debug("Sender allowed");
         }
     }
     
@@ -201,6 +160,11 @@
         if (session.getConfigurationData().getUsersRepository().contains(rcpt.getUser()) == true || recipients.contains(rcpt.toString().toLowerCase()) || domains.contains(rcpt.getHost().toLowerCase())) {
             invalidUser = false;
         }
+
+        // check if an valid virtual mapping exists
+        if (invalidUser == true  && session.getState().get(AbstractVirtualUserTableHandler.VALID_USER) != null) {
+            invalidUser = false;
+        }
         
         if (invalidUser == true && !regex.isEmpty()) {
             Iterator reg = regex.iterator();
@@ -215,10 +179,6 @@
             }
         }
     
-        if (useSql == true && invalidUser == true) {
-            invalidUser = userExist(rcpt,useVirtualUserTable);
-        }
-    
         if (invalidUser == true) {
             //user not exist
             String responseString = "554 " + DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.ADDRESS_MAILBOX) + " Unknown user: " + rcpt.toString();
@@ -227,86 +187,6 @@
         
             session.writeResponse(responseString);
             session.setStopHandlerProcessing(true);
-        }
-    }
-    
-    /**
-     * Return true if the MailAddress exists in the table
-     * 
-     * @param rcpt The MailAddress to check
-     * @return true if the MailAddress exists in the table. If not false
-     */
-    private boolean userExist(MailAddress rcpt, boolean useVirtualUserTable) {
-        Connection conn = null;
-        PreparedStatement mappingStmt = null;
-        try {
-            conn = dataSource.getConnection();
-            mappingStmt = conn.prepareStatement(query);
-                ResultSet mappingRS = null;
-                try {
-                    if (useVirtualUserTable == true) {
-                        mappingStmt.setString(1, rcpt.getUser());
-                        mappingStmt.setString(2, rcpt.getHost());
-                        mappingStmt.setString(3, rcpt.getHost());
-                    } else {
-                        mappingStmt.setString(1, rcpt.toString());
-                    }
-                    mappingRS = mappingStmt.executeQuery();
-                    
-                    if (mappingRS.next()) {
-                       return true;
-                    }
-                } finally {
-                    theJDBCUtil.closeJDBCResultSet(mappingRS);
-                }
-            
-        } catch (SQLException sqle) {
-            getLogger().error("Error accessing database", sqle);
-            
-            // safety first
-            return true;
-        } finally {
-            theJDBCUtil.closeJDBCStatement(mappingStmt);
-            theJDBCUtil.closeJDBCConnection(conn);
-        }
-        return false;
-    
-    }
-    
-    /**
-     * The JDBCUtil helper class
-     */
-    private final JDBCUtil theJDBCUtil = new JDBCUtil() {
-        protected void delegatedLog(String logString) {
-            getLogger().debug("ValidRcpt: " + logString);
-        }
-    };
- 
-    /**
-     * Return the DataSourceSelector 
-     * 
-     * @param datasources The DataSourceSelector
-     * @param repositoryPath The repositoryPath
-     * @return true or false 
-     * 
-     * @throws ServiceException
-     */
-    private DataSourceComponent getDataSource(DataSourceSelector datasources,String repositoryPath) throws ServiceException {
-
-        int stindex = repositoryPath.indexOf("://") + 3;
-        String datasourceName = repositoryPath.substring(stindex);
-
-        return (DataSourceComponent) datasources.select(datasourceName);
-    }
-
-    /**
-     * @see org.apache.avalon.framework.activity.Initializable#initialize()
-     */
-    public void initialize() throws Exception {
-        if (useSql == true) {
-            // init the datasource 
-            dataSource = getDataSource(selector,repositoryPath);
-            getLogger().debug("SQL is used");
         }
     }
 }

Added: james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/XMLVirtualUserTableHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/XMLVirtualUserTableHandler.java?rev=437772&view=auto
==============================================================================
--- james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/XMLVirtualUserTableHandler.java (added)
+++ james/server/trunk/src/java/org/apache/james/smtpserver/core/filter/fastfail/XMLVirtualUserTableHandler.java Mon Aug 28 11:24:41 2006
@@ -0,0 +1,70 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+
+
+package org.apache.james.smtpserver.core.filter.fastfail;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.james.util.VirtualUserTableUtil;
+import org.apache.mailet.MailAddress;
+
+/**
+ * This handler should be called before ValidRcptHandler if the XMLVirtualUserTable is used.
+ * It only set some state. It not replace the recipient.
+ */
+public class XMLVirtualUserTableHandler extends AbstractVirtualUserTableHandler implements Configurable{
+
+    Map mappings = new HashMap();
+    
+    /**
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
+     */
+    public void configure(Configuration arg0) throws ConfigurationException {
+        Configuration[] mapping = arg0.getChildren("mapping");
+    
+        if (mapping != null) {
+            StringBuffer map = new StringBuffer();
+            
+            for (int i = 0; i < mapping.length; i++) {
+                if (i != 0)  {
+                    map.append(", ");
+                }
+                map.append(mapping[i]);
+            }
+            mappings = VirtualUserTableUtil.getXMLMappings(map.toString());
+        }       
+    }
+    
+    /**
+     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractVirtualUserTableHandler#mapRecipients(MailAddress)
+     */
+    protected String mapRecipients(MailAddress recipient) {
+        String user = recipient.getUser().toLowerCase();
+        String domain = recipient.getHost().toLowerCase();
+  
+        return VirtualUserTableUtil.getTargetString(user, domain, mappings);
+    }
+
+}

Modified: james/server/trunk/src/java/org/apache/james/transport/mailets/AbstractVirtualUserTable.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/transport/mailets/AbstractVirtualUserTable.java?rev=437772&r1=437771&r2=437772&view=diff
==============================================================================
--- james/server/trunk/src/java/org/apache/james/transport/mailets/AbstractVirtualUserTable.java (original)
+++ james/server/trunk/src/java/org/apache/james/transport/mailets/AbstractVirtualUserTable.java Mon Aug 28 11:24:41 2006
@@ -22,14 +22,11 @@
 package org.apache.james.transport.mailets;
 
 import org.apache.james.core.MailImpl;
-import org.apache.james.util.XMLResources;
+import org.apache.james.util.VirtualUserTableUtil;
 import org.apache.mailet.GenericMailet;
 import org.apache.mailet.Mail;
 import org.apache.mailet.MailAddress;
-import org.apache.oro.text.regex.MatchResult;
-import org.apache.oro.text.regex.Pattern;
-import org.apache.oro.text.regex.Perl5Compiler;
-import org.apache.oro.text.regex.Perl5Matcher;
+import org.apache.oro.text.regex.MalformedPatternException;
 
 import javax.mail.MessagingException;
 import javax.mail.internet.ParseException;
@@ -100,7 +97,11 @@
                         // log("Attempting to map from " + source + " to " + targetAddress);
 
                         if (targetAddress.startsWith("regex:")) {
-                            targetAddress = regexMap(mail, source, targetAddress);
+                            try {
+                                targetAddress = VirtualUserTableUtil.regexMap(source, targetAddress);
+                            } catch (MalformedPatternException e) {
+                                log("Exception during regexMap processing: ", e);
+                            }
                             if (targetAddress == null) continue;
                         }
 
@@ -223,49 +224,6 @@
       catch (MessagingException me) {
           log("Cannot send DSN.  Exception during DSN processing: ", me);
       }
-  }
-
-  /**
-   * Processes regex virtual user mapping
-   *
-   * If a mapped target string begins with the prefix regex:, it must be
-   * formatted as regex:<regular-expression>:<parameterized-string>,
-   * e.g., regex:(.*)@(.*):${1}@tld
-   *
-   * @param mail the Mail instance being processed
-   * @param address the MailAddress to be mapped
-   * @param targetString a String specifying the mapping
-   */
-  private String regexMap(Mail mail, MailAddress address, String targetString) {
-      String result = null;
-
-      try {
-          int msgPos = targetString.indexOf(':', "regex:".length() + 1);
-
-          // log("regex: targetString = " + targetString);
-          // log("regex: msgPos = " + msgPos);
-          // log("regex: compile " + targetString.substring("regex:".length(), msgPos));
-          // log("regex: address = " + address.toString());
-          // log("regex: replace = " + targetString.substring(msgPos + 1));
-
-          Pattern pattern = new Perl5Compiler().compile(targetString.substring("regex:".length(), msgPos));
-          Perl5Matcher matcher = new Perl5Matcher();
-
-          if (matcher.matches(address.toString(), pattern)) {
-              MatchResult match = matcher.getMatch();
-              Map parameters = new HashMap(match.groups());
-              for (int i = 1; i < match.groups(); i++) {
-                  parameters.put(Integer.toString(i), match.group(i));
-              }
-              result = XMLResources.replaceParameters(targetString.substring(msgPos + 1), parameters);
-          }
-      }
-      catch (Exception e) {
-          log("Exception during regexMap processing: ", e);
-      }
-
-      // log("regex: result = " + result);
-      return result;
   }
 
   /**

Modified: james/server/trunk/src/java/org/apache/james/transport/mailets/XMLVirtualUserTable.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/transport/mailets/XMLVirtualUserTable.java?rev=437772&r1=437771&r2=437772&view=diff
==============================================================================
--- james/server/trunk/src/java/org/apache/james/transport/mailets/XMLVirtualUserTable.java (original)
+++ james/server/trunk/src/java/org/apache/james/transport/mailets/XMLVirtualUserTable.java Mon Aug 28 11:24:41 2006
@@ -25,10 +25,10 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.StringTokenizer;
 
 import javax.mail.MessagingException;
 
+import org.apache.james.util.VirtualUserTableUtil;
 import org.apache.mailet.MailAddress;
 
 /**
@@ -71,14 +71,7 @@
       String mapping = getInitParameter("mapping");
       
       if(mapping != null) {
-          StringTokenizer tokenizer = new StringTokenizer(mapping, ",");
-          while(tokenizer.hasMoreTokens()) {
-            String mappingItem = tokenizer.nextToken();
-            int index = mappingItem.indexOf('=');
-            String virtual = mappingItem.substring(0, index).trim().toLowerCase();
-            String real = mappingItem.substring(index + 1).trim().toLowerCase();
-            mappings.put(virtual, real);
-          }
+          mappings = VirtualUserTableUtil.getXMLMappings(mapping);
       }
   }
 
@@ -95,7 +88,7 @@
           String user = source.getUser().toLowerCase();
           String domain = source.getHost().toLowerCase();
     
-          String targetString = getTargetString(user, domain);
+          String targetString = VirtualUserTableUtil.getTargetString(user, domain, mappings);
           
           if (targetString != null) {
               recipientsMap.put(source, targetString);
@@ -103,41 +96,6 @@
       }
   }
 
-  /**
-   * Returns the real recipient given a virtual username and domain.
-   * 
-   * @param user the virtual user
-   * @param domain the virtual domain
-   * @return the real recipient address, or <code>null</code> if no mapping exists
-   */
-  private String getTargetString(String user, String domain) {
-      StringBuffer buf;
-      String target;
-      
-      //Look for exact (user@domain) match
-      buf = new StringBuffer().append(user).append("@").append(domain);
-      target = (String)mappings.get(buf.toString());
-      if (target != null) {
-          return target;
-      }
-      
-      //Look for user@* match
-      buf = new StringBuffer().append(user).append("@*");
-      target = (String)mappings.get(buf.toString());
-      if (target != null) {
-          return target;
-      }
-      
-      //Look for *@domain match
-      buf = new StringBuffer().append("*@").append(domain);
-      target = (String)mappings.get(buf.toString());
-      if (target != null) {
-          return target;
-      }
-      
-      return null;
-  }
-  
   public String getMailetInfo() {
       return "XML Virtual User Table mailet";
   }

Added: james/server/trunk/src/java/org/apache/james/util/VirtualUserTableUtil.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/util/VirtualUserTableUtil.java?rev=437772&view=auto
==============================================================================
--- james/server/trunk/src/java/org/apache/james/util/VirtualUserTableUtil.java (added)
+++ james/server/trunk/src/java/org/apache/james/util/VirtualUserTableUtil.java Mon Aug 28 11:24:41 2006
@@ -0,0 +1,145 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+
+
+package org.apache.james.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.mailet.MailAddress;
+import org.apache.oro.text.regex.MalformedPatternException;
+import org.apache.oro.text.regex.MatchResult;
+import org.apache.oro.text.regex.Pattern;
+import org.apache.oro.text.regex.Perl5Compiler;
+import org.apache.oro.text.regex.Perl5Matcher;
+
+/**
+ * This helper class contains methods for the VirtualUserTable implementations
+ */
+public class VirtualUserTableUtil {
+
+    private VirtualUserTableUtil() {}
+    
+    
+    /**
+     * Processes regex virtual user mapping
+     *
+     * If a mapped target string begins with the prefix regex:, it must be
+     * formatted as regex:<regular-expression>:<parameterized-string>,
+     * e.g., regex:(.*)@(.*):${1}@tld
+     *
+     * @param address the MailAddress to be mapped
+     * @param targetString a String specifying the mapping
+     * @throws MalformedPatternException 
+     */
+     public static String regexMap( MailAddress address, String targetString) throws MalformedPatternException {
+        String result = null;
+
+
+        int msgPos = targetString.indexOf(':', "regex:".length() + 1);
+
+        // log("regex: targetString = " + targetString);
+        // log("regex: msgPos = " + msgPos);
+        // log("regex: compile " + targetString.substring("regex:".length(), msgPos));
+        // log("regex: address = " + address.toString());
+        // log("regex: replace = " + targetString.substring(msgPos + 1));
+
+        Pattern pattern = new Perl5Compiler().compile(targetString.substring("regex:".length(), msgPos));
+        Perl5Matcher matcher = new Perl5Matcher();
+
+        if (matcher.matches(address.toString(), pattern)) {
+            MatchResult match = matcher.getMatch();
+            Map parameters = new HashMap(match.groups());
+            for (int i = 1; i < match.groups(); i++) {
+                parameters.put(Integer.toString(i), match.group(i));
+            }
+            result = XMLResources.replaceParameters(targetString.substring(msgPos + 1), parameters);
+        }    
+        return result;
+    }
+     
+     /**
+      * Returns the real recipient given a virtual username and domain.
+      * 
+      * @param user the virtual user
+      * @param domain the virtual domain
+      * @return the real recipient address, or <code>null</code> if no mapping exists
+      */
+     public static String getTargetString(String user, String domain, Map mappings) {
+         StringBuffer buf;
+         String target;
+         
+         //Look for exact (user@domain) match
+         buf = new StringBuffer().append(user).append("@").append(domain);
+         target = (String)mappings.get(buf.toString());
+         if (target != null) {
+             return target;
+         }
+         
+         //Look for user@* match
+         buf = new StringBuffer().append(user).append("@*");
+         target = (String)mappings.get(buf.toString());
+         if (target != null) {
+             return target;
+         }
+         
+         //Look for *@domain match
+         buf = new StringBuffer().append("*@").append(domain);
+         target = (String)mappings.get(buf.toString());
+         if (target != null) {
+             return target;
+         }
+         
+         return null;
+     }
+     
+     /**
+      * Returns the character used to delineate multiple addresses.
+      * 
+      * @param targetString the string to parse
+      * @return the character to tokenize on
+      */
+     public static String getSeparator(String targetString) {
+        return (targetString.indexOf(',') > -1 ? "," : (targetString
+        .indexOf(';') > -1 ? ";"
+        : (targetString.indexOf("regex:") > -1 ? "" : ":")));
+     }
+     
+     /**
+      * Returns a Map which contains the mappings
+      * 
+      * @param mapping A String which contains a list of mappings
+      * @return Map which contains the mappings
+      */
+     public static Map getXMLMappings(String mapping) {
+         Map mappings = new HashMap();
+         StringTokenizer tokenizer = new StringTokenizer(mapping, ",");
+         while(tokenizer.hasMoreTokens()) {
+           String mappingItem = tokenizer.nextToken();
+           int index = mappingItem.indexOf('=');
+           String virtual = mappingItem.substring(0, index).trim().toLowerCase();
+           String real = mappingItem.substring(index + 1).trim().toLowerCase();
+           mappings.put(virtual, real);
+         }
+         return mappings;
+     }
+}

Modified: james/server/trunk/src/test/org/apache/james/smtpserver/ValidRcptHandlerTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/test/org/apache/james/smtpserver/ValidRcptHandlerTest.java?rev=437772&r1=437771&r2=437772&view=diff
==============================================================================
--- james/server/trunk/src/test/org/apache/james/smtpserver/ValidRcptHandlerTest.java (original)
+++ james/server/trunk/src/test/org/apache/james/smtpserver/ValidRcptHandlerTest.java Mon Aug 28 11:24:41 2006
@@ -30,6 +30,7 @@
 import org.apache.avalon.framework.container.ContainerUtil;
 import org.apache.james.services.MailServer;
 import org.apache.james.services.UsersRepository;
+import org.apache.james.smtpserver.core.filter.fastfail.AbstractVirtualUserTableHandler;
 import org.apache.james.smtpserver.core.filter.fastfail.ValidRcptHandler;
 import org.apache.james.test.mock.avalon.MockLogger;
 import org.apache.james.userrepository.MockUsersRepository;
@@ -247,6 +248,20 @@
         }
 
         assertTrue("Invalid Config",exception);
+    }
+    
+    public void testNotRejectValidUserState() throws ParseException {
+        String domain = "domain";
+        String recipient = "recip@" + domain;
+        ValidRcptHandler handler = new ValidRcptHandler();
+        SMTPSession session = setupMockedSMTPSession(setupMockedSMTPConfiguration(),new MailAddress(recipient),false,false,null);
+        ContainerUtil.enableLogging(handler,new MockLogger());
+    
+        session.getState().put(AbstractVirtualUserTableHandler.VALID_USER, recipient);
+        handler.onCommand(session);
+    
+        assertFalse("Not rejected",session.getStopHandlerProcessing());
+        assertNull("Not rejected",response);
     }
     
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


RE: svn commit: r437772 - in /james/server/trunk/src: conf/ java/org/apache/james/smtpserver/core/filter/fastfail/ java/org/apache/james/transport/mailets/ java/org/apache/james/util/ test/org/apache/james/smtpserver/

Posted by "Noel J. Bergman" <no...@devtech.com>.
Not quite ...

> if (targetString.startsWith("error:")) {
>    // No valid mapping
>    return;

If there is an error: it means just that.  There IS a mapping, and it says that this is NOT a valid address.  Do not pass go, do not collect $200, do not allow the RCPT because it is allowed in some forwarding domain, etc.  This is NOT a valid address by explicit declaration.  Please return the error messsage in-protocol.

	--- Noel



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org