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/07/07 19:42:25 UTC

svn commit: r419932 - in /james/server/trunk/src/java/org/apache/james: transport/mailets/SpamAssassin.java util/SpamAssassinInvoker.java

Author: norman
Date: Fri Jul  7 10:42:25 2006
New Revision: 419932

URL: http://svn.apache.org/viewvc?rev=419932&view=rev
Log:
Add spamassassian support based on Josh Parreco's contribution. Moved the core code to util class for easy use it in fastfail and matcher. See JAMES-259

Added:
    james/server/trunk/src/java/org/apache/james/transport/mailets/SpamAssassin.java
    james/server/trunk/src/java/org/apache/james/util/SpamAssassinInvoker.java

Added: james/server/trunk/src/java/org/apache/james/transport/mailets/SpamAssassin.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/transport/mailets/SpamAssassin.java?rev=419932&view=auto
==============================================================================
--- james/server/trunk/src/java/org/apache/james/transport/mailets/SpamAssassin.java (added)
+++ james/server/trunk/src/java/org/apache/james/transport/mailets/SpamAssassin.java Fri Jul  7 10:42:25 2006
@@ -0,0 +1,103 @@
+/***********************************************************************
+ * Copyright (c) 2006 The Apache Software Foundation.                  *
+ * All rights reserved.                                                *
+ * ------------------------------------------------------------------- *
+ * Licensed 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.transport.mailets;
+
+import org.apache.james.util.SpamAssassinInvoker;
+import org.apache.mailet.GenericMailet;
+import org.apache.mailet.Mail;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+/**
+ * Sends the message through daemonized SpamAssassin (spamd), visit <a
+ * href="SpamAssassin.org">SpamAssassin.org</a> for info on configuration. The
+ * header X-Spam-Status is added to every message, this contains the score and
+ * the threshold score for spam (usually 5.0). If the message exceeds the
+ * threshold, the header X-Spam-Flag will be added with the value of YES. The
+ * default host for spamd is localhost and the default port is 783. <br>
+ * <br>
+ * Sample Configuration: <br>
+ * <br>
+ * &lt;mailet match="All" class="SpamAssassin"&gt;
+ * &lt;spamdHost&gt;localhost&lt;/spamdHost&gt;
+ * &lt;spamdPort&gt;783&lt;/spamdPort&gt; <br>
+ */
+public class SpamAssassin extends GenericMailet {
+
+    String spamdHost;
+
+    int spamdPort;
+
+    String subjectPrefix;
+
+    public void init() throws MessagingException {
+        spamdHost = getInitParameter("spamdHost");
+        if (spamdHost == null || spamdHost.equals("")) {
+            spamdHost = "127.0.0.1";
+        }
+
+        String port = getInitParameter("spamdPort");
+        if (port == null || port.equals("")) {
+            spamdPort = 783;
+        } else {
+
+            try {
+                spamdPort = Integer.parseInt(getInitParameter("spamdPort"));
+            } catch (NumberFormatException e) {
+                throw new MessagingException(
+                        "Please configure a valid port. Not valid: "
+                                + spamdPort);
+            }
+        }
+    }
+
+    public void service(Mail mail) {
+        try {
+            MimeMessage message = mail.getMessage();
+
+            // Invoke spamassian connection and scan the message
+            SpamAssassinInvoker sa = new SpamAssassinInvoker(spamdHost,
+                    spamdPort);
+            boolean spam = sa.scanMail(message);
+            String hits = sa.getHits();
+            String required = sa.getRequiredHits();
+
+            // message was spam
+            if (spam) {
+                // add headers
+                message.setHeader("X-Spam-Flag", "YES");
+                message.setHeader("X-Spam-Status", new StringBuffer(
+                        "Yes, hits=").append(hits).append(" required=").append(
+                        required).toString());
+            } else {
+                // add headers
+                message.setHeader("X-Spam-Status",
+                        new StringBuffer("No, hits=").append(hits).append(
+                                " required=").append(required).toString());
+            }
+            message.saveChanges();
+        } catch (MessagingException e) {
+            log(e.getMessage());
+        }
+
+    }
+
+    public String getMailetInfo() {
+        return "Checks message against SpamAssassin";
+    }
+}

Added: james/server/trunk/src/java/org/apache/james/util/SpamAssassinInvoker.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/util/SpamAssassinInvoker.java?rev=419932&view=auto
==============================================================================
--- james/server/trunk/src/java/org/apache/james/util/SpamAssassinInvoker.java (added)
+++ james/server/trunk/src/java/org/apache/james/util/SpamAssassinInvoker.java Fri Jul  7 10:42:25 2006
@@ -0,0 +1,137 @@
+/***********************************************************************
+ * Copyright (c) 1999-2006 The Apache Software Foundation.             *
+ * All rights reserved.                                                *
+ * ------------------------------------------------------------------- *
+ * Licensed 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 javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.StringTokenizer;
+
+/**
+ * Sends the message through daemonized SpamAssassin (spamd), visit <a
+ * href="SpamAssassin.org">SpamAssassin.org</a> for info on configuration.
+ */
+public class SpamAssassinInvoker {
+
+    String spamdHost;
+
+    int spamdPort;
+
+    String subjectPrefix;
+
+    String hits = "?";
+
+    String required = "?";
+
+    public SpamAssassinInvoker(String spamdHost, int spamdPort) {
+        this.spamdHost = spamdHost;
+        this.spamdPort = spamdPort;
+    }
+
+    /**
+     * Scan a MimeMessage for spam by passing it to spamd. 
+     * 
+     * @param message The MimeMessage to scan 
+     * @return true if spam otherwise false
+     * @throws MessagingException if an error on scanning is detected
+     */
+    public boolean scanMail(MimeMessage message) throws MessagingException {
+        Socket socket = null;
+        OutputStream out = null;
+        BufferedReader in = null;
+
+        try {
+            socket = new Socket(spamdHost, spamdPort);
+
+            out = socket.getOutputStream();
+            in = new BufferedReader(new InputStreamReader(socket
+                    .getInputStream()));
+            out.write("CHECK SPAMC/1.2\r\n\r\n".getBytes());
+
+            message.writeTo(out);
+            out.flush();
+            socket.shutdownOutput();
+            String s = null;
+            while ((s = in.readLine()) != null) {
+                if (s.startsWith("Spam:")) {
+                    StringTokenizer t = new StringTokenizer(s, " ");
+                    boolean spam;
+                    try {
+                        t.nextToken();
+                        spam = Boolean.valueOf(t.nextToken()).booleanValue();
+                    } catch (Exception e) {
+                        // On exception return flase
+                        return false;
+                    }
+                    t.nextToken();
+                    hits = t.nextToken();
+                    t.nextToken();
+                    required = t.nextToken();
+
+                    if (spam) {
+                        // spam detected
+                        return true;
+                    } else {
+                        return false;
+                    }
+                }
+            }
+            return false;
+        } catch (UnknownHostException e1) {
+            throw new MessagingException(
+                    "Error communicating with spamd. Unknown host: "
+                            + spamdHost);
+        } catch (IOException e1) {
+            throw new MessagingException("Error communicating with spamd on "
+                    + spamdHost + ":" + spamdPort + "Exception:" + e1);
+        } catch (MessagingException e1) {
+            throw new MessagingException("Error communicating with spamd on "
+                    + spamdHost + ":" + spamdPort + "Exception:" + e1);
+        } finally {
+            try {
+                in.close();
+                out.close();
+                socket.close();
+            } catch (Exception e) {
+            }
+
+        }
+    }
+
+    /**
+     * Return the hits which was returned by spamd
+     * 
+     * @return hits
+     */
+    public String getHits() {
+        return hits;
+    }
+
+    /**
+     * Return the required hits
+     * 
+     * @return required
+     */
+    public String getRequiredHits() {
+        return required;
+    }
+}



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