You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2024/06/14 06:49:36 UTC

(james-project) branch master updated: JAMES-3946 WhiteList manager removals (#2299)

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


The following commit(s) were added to refs/heads/master by this push:
     new 2af30eeb26 JAMES-3946 WhiteList manager removals (#2299)
2af30eeb26 is described below

commit 2af30eeb26d65cb63ba12a9b96ac782f05068c96
Author: Maksim <85...@users.noreply.github.com>
AuthorDate: Fri Jun 14 09:49:29 2024 +0300

    JAMES-3946 WhiteList manager removals (#2299)
---
 .../spring-app/src/main/resources/sqlResources.xml | 113 ---
 .../james/transport/mailets/WhiteListManager.java  | 793 ---------------------
 .../matchers/AbstractSQLWhitelistMatcher.java      | 255 -------
 .../james/transport/matchers/IsInWhiteList.java    | 190 -----
 .../transport/matchers/NetworkIsInWhitelist.java   | 139 ----
 upgrade-instructions.md                            |  12 +
 6 files changed, 12 insertions(+), 1490 deletions(-)

diff --git a/server/apps/spring-app/src/main/resources/sqlResources.xml b/server/apps/spring-app/src/main/resources/sqlResources.xml
index 07f7c7b7a2..787890f8b8 100644
--- a/server/apps/spring-app/src/main/resources/sqlResources.xml
+++ b/server/apps/spring-app/src/main/resources/sqlResources.xml
@@ -335,119 +335,6 @@
         </sql>
     </sqlDefs>
 
-<!-- SQL statements to support the WhiteListManager mailet and the IsInWhiteList matcher -->
-<!-- -->
-    <sqlDefs name="WhiteList">
-
-        <sql name="whiteListTableName">whitelist</sql>
-
-        <!-- Statements used to retrieve a single entry. -->
-        <sql name="selectByPK">SELECT localUser, localHost FROM whitelist where (localUser=? AND localHost=? AND remoteUser=? AND remoteHost=?)</sql>
-
-        <!-- Statements used to all entries by sender address. -->
-        <sql name="selectBySender">SELECT remoteUser, remoteHost FROM whitelist where (localUser=? AND localHost=?) ORDER BY remoteUser, remoteHost</sql>
-
-        <!-- Statements used to insert an entry. -->
-        <sql name="insert">INSERT INTO whitelist (localUser, localHost, remoteUser, remoteHost) VALUES (?,?,?,?)</sql>
-
-        <!-- Statements used to delete an entry. -->
-        <sql name="deleteByPK">DELETE FROM whitelist where (localUser=? AND localHost=? AND remoteUser=? AND remoteHost=?)</sql>
-
-        <!-- Statements used to create the "whitelist" table. -->
-        <sql name="createWhiteListTable" db="hypersonic">
-            CREATE TABLE whitelist (
-            localUser varchar (64) NOT NULL,
-            localHost varchar (255) NOT NULL,
-            remoteUser varchar (64) NOT NULL,
-            remoteHost varchar (255) NOT NULL,
-            PRIMARY KEY (localUser, localHost, remoteUser, remoteHost)
-            )
-        </sql>
-        <sql name="createWhiteListTable" db="hsqldb">
-            CREATE CACHED TABLE ${table} (
-            CREATE TABLE whitelist (
-            localUser varchar (64) NOT NULL,
-            localHost varchar (255) NOT NULL,
-            remoteUser varchar (64) NOT NULL,
-            remoteHost varchar (255) NOT NULL,
-            PRIMARY KEY (localUser, localHost, remoteUser, remoteHost)
-            )
-        </sql>
-        <sql name="createWhiteListTable" db="mysql">
-            CREATE TABLE whitelist (
-            localUser varchar (64) NOT NULL,
-            localHost varchar (255) character set latin1 NOT NULL,
-            remoteUser varchar (64) NOT NULL,
-            remoteHost varchar (255) character set latin1 NOT NULL,
-            PRIMARY KEY (localUser, localHost, remoteUser, remoteHost)
-            ) TYPE=InnoDB
-        </sql>
-        <sql name="createWhiteListTable" db="mssql">
-            CREATE TABLE [whitelist] (
-            [localUser] [varchar] (64) NOT NULL,
-            [localHost] [varchar] (255) NOT NULL,
-            [remoteUser] [varchar] (64) NOT NULL,
-            [remoteHost] [varchar] (255) NOT NULL,
-            PRIMARY KEY (localUser, localHost, remoteUser, remoteHost)
-            )
-        </sql>
-        <sql name="createWhiteListTable" db="oracle">
-            CREATE TABLE whitelist (
-            localUser varchar (64) NOT NULL,
-            localHost varchar (255) NOT NULL,
-            remoteUser varchar (64) NOT NULL,
-            remoteHost varchar (255) NOT NULL,
-            PRIMARY KEY (localUser, localHost, remoteUser, remoteHost)
-            )
-        </sql>
-        <sql name="createWhiteListTable" db="postgresql">
-            CREATE TABLE whitelist (
-            localUser varchar (64) NOT NULL,
-            localHost varchar (255) NOT NULL,
-            remoteUser varchar (64) NOT NULL,
-            remoteHost varchar (255) NOT NULL,
-            PRIMARY KEY (localUser, localHost, remoteUser, remoteHost)
-            )
-        </sql>
-        <sql name="createWhiteListTable" db="sapdb">
-            CREATE TABLE whitelist (
-            localUser varchar (64) NOT NULL,
-            localHost varchar (255) NOT NULL,
-            remoteUser varchar (64) NOT NULL,
-            remoteHost varchar (255) NOT NULL,
-            PRIMARY KEY (localUser, localHost, remoteUser, remoteHost)
-            )
-        </sql>
-        <sql name="createWhiteListTable" db="db2">
-            CREATE TABLE whitelist (
-            localUser varchar (64) NOT NULL,
-            localHost varchar (255) NOT NULL,
-            remoteUser varchar (64) NOT NULL,
-            remoteHost varchar (255) NOT NULL,
-            PRIMARY KEY (localUser, localHost, remoteUser, remoteHost)
-            )
-        </sql>
-        <sql name="createWhiteListTable" db="ingres">
-            CREATE TABLE whitelist (
-            localUser varchar (64) NOT NULL,
-            localHost varchar (255) NOT NULL,
-            remoteUser varchar (64) NOT NULL,
-            remoteHost varchar (255) NOT NULL,
-            PRIMARY KEY (localUser, localHost, remoteUser, remoteHost)
-            )
-        </sql>
-        <sql name="createWhiteListTable" db="derby">
-            CREATE TABLE whitelist (
-            localUser varchar (64) NOT NULL,
-            localHost varchar (255) NOT NULL,
-            remoteUser varchar (64) NOT NULL,
-            remoteHost varchar (255) NOT NULL,
-            PRIMARY KEY (localUser, localHost, remoteUser, remoteHost)
-            )
-        </sql>
-
-    </sqlDefs>
-
     <sqlDefs name="NetworkWhiteList">
 
         <sql name="networkWhiteListTableName">networkWhitelist</sql>
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/WhiteListManager.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/WhiteListManager.java
deleted file mode 100644
index ca7f65dfd1..0000000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/WhiteListManager.java
+++ /dev/null
@@ -1,793 +0,0 @@
-/****************************************************************
- * 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.transport.mailets;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.time.ZonedDateTime;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import javax.sql.DataSource;
-
-import jakarta.inject.Inject;
-import jakarta.mail.Address;
-import jakarta.mail.Message;
-import jakarta.mail.MessagingException;
-import jakarta.mail.Session;
-import jakarta.mail.internet.InternetAddress;
-import jakarta.mail.internet.MimeBodyPart;
-import jakarta.mail.internet.MimeMessage;
-import jakarta.mail.internet.MimeMultipart;
-
-import org.apache.james.core.Domain;
-import org.apache.james.core.MailAddress;
-import org.apache.james.user.api.UsersRepository;
-import org.apache.james.util.sql.JDBCUtil;
-import org.apache.james.util.sql.SqlResources;
-import org.apache.mailet.Experimental;
-import org.apache.mailet.Mail;
-import org.apache.mailet.MailetException;
-import org.apache.mailet.base.DateFormats;
-import org.apache.mailet.base.GenericMailet;
-import org.apache.mailet.base.RFC2822Headers;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.github.fge.lambdas.Throwing;
-import com.google.common.collect.ImmutableList;
-
-/**
- * <p>
- * Manages for each local user a "white list" of remote addresses whose messages
- * should never be blocked as spam.
- * </p>
- * <p>
- * The normal behaviour is to check, for a local sender, if a remote recipient
- * is already in the list: if not, it will be automatically inserted. This is
- * under the interpretation that if a local sender <i>X</i> sends a message to a
- * remote recipient <i>Y</i>, then later on if a message is sent by <i>Y</i> to
- * <i>X</i> it should be considered always valid and never blocked; hence
- * <i>Y</i> should be in the white list of <i>X</i>.
- * </p>
- * <p>
- * Another mode of operations is when a local sender sends a message to
- * <i>whitelistManagerAddress</i> with one of three specific values in the
- * subject, to (i) send back a message displaying a list of the addresses in his
- * own list; (ii) insert some new addresses in his own list; (iii) remove some
- * addresses from his own list. In all this cases the message will be ghosted
- * and the postmaster will reply to the sender.
- * </p>
- * <p>
- * The sender name is always converted to its primary name (handling aliases).
- * </p>
- * <p>
- * Sample configuration:
- * </p>
- * 
- * <pre>
- * <code>
- * &lt;mailet match="SMTPAuthSuccessful" class="WhiteListManager"&gt;
- *   &lt;repositoryPath&gt; db://maildb &lt;/repositoryPath&gt;
- *   &lt;!--
- *     If true automatically inserts the local sender to remote recipients entries in the whitelist (default is false).
- *   --&gt;
- *   &lt;automaticInsert&gt;true&lt;/automaticInsert&gt;
- *   &lt;!--
- *     Set this to an email address of the "whitelist manager" to send commands to (default is null).
- *   --&gt;
- *   &lt;whitelistManagerAddress&gt;whitelist.manager@xxx.yyy&lt;/whitelistManagerAddress&gt;
- *   &lt;!--
- *     Set this to a unique text that you can use (by sending a message to the "whitelist manager" above)
- *     to tell the mailet to send back the contents of the white list (default is null).
- *   --&gt;
- *   &lt;displayFlag&gt;display whitelist&lt;/displayFlag&gt;
- *   &lt;!--
- *     Set this to a unique text that you can use (by sending a message to the "whitelist manager" above)
- *     to tell the mailet to insert some new remote recipients to the white list (default is null).
- *   --&gt;
- *   &lt;insertFlag&gt;insert whitelist&lt;/insertFlag&gt;
- *   &lt;!--
- *     Set this to a unique text that you can use (by sending a message to the "whitelist manager" above)
- *     to tell the mailet to remove some remote recipients from the white list (default is null).
- *   --&gt;
- *   &lt;removeFlag&gt;remove whitelist&lt;/removeFlag&gt;
- * &lt;/mailet&gt;
- * </code>
- * </pre>
- * 
- * @see org.apache.james.transport.matchers.IsInWhiteList
- * @since 2.3.0
- */
-@Experimental
-@SuppressWarnings("deprecation")
-public class WhiteListManager extends GenericMailet {
-    private static final Logger LOGGER = LoggerFactory.getLogger(WhiteListManager.class);
-
-    private boolean automaticInsert;
-    private String displayFlag;
-    private String insertFlag;
-    private String removeFlag;
-    private MailAddress whitelistManagerAddress;
-
-    private String selectByPK;
-    private String selectBySender;
-    private String insert;
-    private String deleteByPK;
-
-    private DataSource datasource;
-
-    /**
-     * The user repository for this mail server. Contains all the users with
-     * inboxes on this server.
-     */
-    private UsersRepository localusers;
-
-    /**
-     * The JDBCUtil helper class
-     */
-    private final JDBCUtil theJDBCUtil = new JDBCUtil();
-
-    /**
-     * Contains all of the sql strings for this component.
-     */
-    private final SqlResources sqlQueries = new SqlResources();
-
-    /** Holds value of property sqlParameters. */
-    private final Map<String, String> sqlParameters = new HashMap<>();
-
-    @Inject
-    public void setDataSource(DataSource datasource) {
-        this.datasource = datasource;
-    }
-
-    @Inject
-    public void setUsersRepository(UsersRepository localusers) {
-        this.localusers = localusers;
-    }
-
-    /**
-     * Getter for property sqlParameters.
-     * 
-     * @return Value of property sqlParameters.
-     */
-    private Map<String, String> getSqlParameters() {
-
-        return this.sqlParameters;
-    }
-
-    @Override
-    public void init() throws MessagingException {
-        automaticInsert = Boolean.parseBoolean(getInitParameter("automaticInsert"));
-        LOGGER.debug("automaticInsert: {}", automaticInsert);
-
-        displayFlag = getInitParameter("displayFlag");
-        insertFlag = getInitParameter("insertFlag");
-        removeFlag = getInitParameter("removeFlag");
-
-        String whitelistManagerAddressString = getInitParameter("whitelistManagerAddress");
-        if (whitelistManagerAddressString != null) {
-            whitelistManagerAddressString = whitelistManagerAddressString.trim();
-            LOGGER.debug("whitelistManagerAddress: {}", whitelistManagerAddressString);
-            try {
-                whitelistManagerAddress = new MailAddress(whitelistManagerAddressString);
-            } catch (jakarta.mail.internet.ParseException pe) {
-                throw new MessagingException("Bad whitelistManagerAddress", pe);
-            }
-
-            if (displayFlag != null) {
-                displayFlag = displayFlag.trim();
-                LOGGER.debug("displayFlag: {}", displayFlag);
-            } else {
-                LOGGER.debug("displayFlag is null");
-            }
-            if (insertFlag != null) {
-                insertFlag = insertFlag.trim();
-                LOGGER.debug("insertFlag: {}", insertFlag);
-            } else {
-                LOGGER.debug("insertFlag is null");
-            }
-            if (removeFlag != null) {
-                removeFlag = removeFlag.trim();
-                LOGGER.debug("removeFlag: {}", removeFlag);
-            } else {
-                LOGGER.debug("removeFlag is null");
-            }
-        } else {
-            LOGGER.debug("whitelistManagerAddress is null; will ignore commands");
-        }
-
-        String repositoryPath = getInitParameter("repositoryPath");
-        if (repositoryPath != null) {
-            LOGGER.debug("repositoryPath: {}", repositoryPath);
-        } else {
-            throw new MessagingException("repositoryPath is null");
-        }
-
-        try {
-            initSqlQueries(datasource.getConnection(), getMailetContext());
-        } catch (Exception e) {
-            throw new MessagingException("Exception initializing queries", e);
-        }
-
-        selectByPK = sqlQueries.getSqlString("selectByPK", true);
-        selectBySender = sqlQueries.getSqlString("selectBySender", true);
-        insert = sqlQueries.getSqlString("insert", true);
-        deleteByPK = sqlQueries.getSqlString("deleteByPK", true);
-    }
-
-    @Override
-    public void service(Mail mail) throws MessagingException {
-
-        // check if it's a local sender
-        if (!mail.hasSender()) {
-            return;
-        }
-        MailAddress senderMailAddress = mail.getMaybeSender().get();
-        if (!getMailetContext().isLocalEmail(senderMailAddress)) {
-            // not a local sender, so return
-            return;
-        }
-
-        Collection<MailAddress> recipients = mail.getRecipients();
-
-        if (recipients.size() == 1 && whitelistManagerAddress != null && whitelistManagerAddress.equals(recipients.toArray()[0])) {
-
-            mail.setState(Mail.GHOST);
-
-            String subject = mail.getMessage().getSubject();
-            if (displayFlag != null && displayFlag.equals(subject)) {
-                manageDisplayRequest(mail);
-            } else if (insertFlag != null && insertFlag.equals(subject)) {
-                manageInsertRequest(mail);
-            } else if (removeFlag != null && removeFlag.equals(subject)) {
-                manageRemoveRequest(mail);
-            } else {
-                StringWriter sout = new StringWriter();
-                PrintWriter out = new PrintWriter(sout, true);
-                out.println("Answering on behalf of: " + whitelistManagerAddress);
-                out.println("ERROR: Unknown command in the subject line: " + subject);
-                sendReplyFromPostmaster(mail, sout.toString());
-            }
-            return;
-        }
-
-        if (automaticInsert) {
-            checkAndInsert(senderMailAddress, recipients);
-        }
-
-    }
-
-    @Override
-    public String getMailetInfo() {
-        return "White List Manager mailet";
-    }
-
-    /**
-     * Loops through each address in the recipient list, checks if in the
-     * senders list and inserts in it otherwise.
-     */
-    private void checkAndInsert(MailAddress senderMailAddress, Collection<MailAddress> recipients) throws MessagingException {
-        String senderUser = senderMailAddress.getLocalPart().toLowerCase(Locale.US);
-        Domain senderHost = senderMailAddress.getDomain();
-
-        Connection conn = null;
-        PreparedStatement selectStmt = null;
-        PreparedStatement insertStmt = null;
-        boolean dbUpdated = false;
-
-        try {
-
-            for (MailAddress recipient : recipients) {
-                ResultSet selectRS = null;
-                try {
-                    String recipientUser = recipient.getLocalPart().toLowerCase(Locale.US);
-                    Domain recipientHost = recipient.getDomain();
-
-                    if (getMailetContext().isLocalServer(recipientHost)) {
-                        // not a remote recipient, so skip
-                        continue;
-                    }
-
-                    if (conn == null) {
-                        conn = datasource.getConnection();
-                    }
-
-                    if (selectStmt == null) {
-                        selectStmt = conn.prepareStatement(selectByPK);
-                    }
-                    selectStmt.setString(1, senderUser);
-                    selectStmt.setString(2, senderHost.asString());
-                    selectStmt.setString(3, recipientUser);
-                    selectStmt.setString(4, recipientHost.asString());
-                    selectRS = selectStmt.executeQuery();
-                    if (selectRS.next()) {
-                        // This address was already in the list
-                        continue;
-                    }
-
-                    if (insertStmt == null) {
-                        insertStmt = conn.prepareStatement(insert);
-                    }
-                    insertStmt.setString(1, senderUser);
-                    insertStmt.setString(2, senderHost.asString());
-                    insertStmt.setString(3, recipientUser);
-                    insertStmt.setString(4, recipientHost.asString());
-                    insertStmt.executeUpdate();
-                    dbUpdated = true;
-
-                } finally {
-                    theJDBCUtil.closeJDBCResultSet(selectRS);
-                }
-
-                // Commit our changes if necessary.
-                if (conn != null && dbUpdated && !conn.getAutoCommit()) {
-                    conn.commit();
-                    dbUpdated = false;
-                }
-            }
-        } catch (SQLException sqle) {
-            LOGGER.error("Error accessing database", sqle);
-            throw new MessagingException("Exception thrown", sqle);
-        } finally {
-            theJDBCUtil.closeJDBCStatement(selectStmt);
-            theJDBCUtil.closeJDBCStatement(insertStmt);
-            // Rollback our changes if necessary.
-            try {
-                if (conn != null && dbUpdated && !conn.getAutoCommit()) {
-                    conn.rollback();
-                    dbUpdated = false;
-                }
-            } catch (Exception e) {
-                LOGGER.error("Ignored exception upon rollback", e);
-            }
-            theJDBCUtil.closeJDBCConnection(conn);
-        }
-    }
-
-    /**
-     * Manages a display request.
-     */
-    private void manageDisplayRequest(Mail mail) throws MessagingException {
-        MailAddress senderMailAddress = mail.getMaybeSender().get();
-        String senderUser = senderMailAddress.getLocalPart().toLowerCase(Locale.US);
-        Domain senderHost = senderMailAddress.getDomain();
-
-        Connection conn = null;
-        PreparedStatement selectStmt = null;
-        ResultSet selectRS = null;
-
-        StringWriter sout = new StringWriter();
-        PrintWriter out = new PrintWriter(sout, true);
-
-        try {
-            out.println("Answering on behalf of: " + whitelistManagerAddress);
-            out.println("Displaying white list of " + (new MailAddress(senderUser, senderHost)) + ":");
-            out.println();
-
-            conn = datasource.getConnection();
-            selectStmt = conn.prepareStatement(selectBySender);
-            selectStmt.setString(1, senderUser);
-            selectStmt.setString(2, senderHost.asString());
-            selectRS = selectStmt.executeQuery();
-            while (selectRS.next()) {
-                MailAddress mailAddress = new MailAddress(selectRS.getString(1), selectRS.getString(2));
-                out.println(mailAddress.toString());
-            }
-
-            out.println();
-            out.println("Finished");
-
-            sendReplyFromPostmaster(mail, sout.toString());
-
-        } catch (SQLException sqle) {
-            out.println("Error accessing the database");
-            sendReplyFromPostmaster(mail, sout.toString());
-            throw new MessagingException("Error accessing database", sqle);
-        } finally {
-            theJDBCUtil.closeJDBCResultSet(selectRS);
-            theJDBCUtil.closeJDBCStatement(selectStmt);
-            theJDBCUtil.closeJDBCConnection(conn);
-        }
-    }
-
-    /**
-     * Manages an insert request.
-     */
-    private void manageInsertRequest(Mail mail) throws MessagingException {
-        MailAddress senderMailAddress = mail.getMaybeSender().get();
-        String senderUser = senderMailAddress.getLocalPart().toLowerCase(Locale.US);
-        Domain senderHost = senderMailAddress.getDomain();
-
-        Connection conn = null;
-        PreparedStatement selectStmt = null;
-        PreparedStatement insertStmt = null;
-        boolean dbUpdated = false;
-
-        StringWriter sout = new StringWriter();
-        PrintWriter out = new PrintWriter(sout, true);
-
-        try {
-            out.println("Answering on behalf of: " + whitelistManagerAddress);
-            out.println("Inserting in the white list of " + (new MailAddress(senderUser, senderHost)) + " ...");
-            out.println();
-
-            MimeMessage message = mail.getMessage();
-
-            Object content = message.getContent();
-
-            if (message.getContentType().startsWith("text/plain") && content instanceof String) {
-                StringTokenizer st = new StringTokenizer((String) content, " \t\n\r\f,;:<>");
-                while (st.hasMoreTokens()) {
-                    ResultSet selectRS = null;
-                    try {
-                        MailAddress recipientMailAddress;
-                        try {
-                            recipientMailAddress = new MailAddress(st.nextToken());
-                        } catch (jakarta.mail.internet.ParseException pe) {
-                            continue;
-                        }
-                        String recipientUser = recipientMailAddress.getLocalPart().toLowerCase(Locale.US);
-                        Domain recipientHost = recipientMailAddress.getDomain();
-
-                        if (getMailetContext().isLocalServer(recipientHost)) {
-                            // not a remote recipient, so skip
-                            continue;
-                        }
-
-                        if (conn == null) {
-                            conn = datasource.getConnection();
-                        }
-
-                        if (selectStmt == null) {
-                            selectStmt = conn.prepareStatement(selectByPK);
-                        }
-                        selectStmt.setString(1, senderUser);
-                        selectStmt.setString(2, senderHost.asString());
-                        selectStmt.setString(3, recipientUser);
-                        selectStmt.setString(4, recipientHost.asString());
-                        selectRS = selectStmt.executeQuery();
-                        if (selectRS.next()) {
-                            // This address was already in the list
-                            out.println("Skipped:  " + recipientMailAddress);
-                            continue;
-                        }
-
-                        if (insertStmt == null) {
-                            insertStmt = conn.prepareStatement(insert);
-                        }
-                        insertStmt.setString(1, senderUser);
-                        insertStmt.setString(2, senderHost.asString());
-                        insertStmt.setString(3, recipientUser);
-                        insertStmt.setString(4, recipientHost.asString());
-                        insertStmt.executeUpdate();
-                        dbUpdated = true;
-                        out.println("Inserted: " + recipientMailAddress);
-
-                    } finally {
-                        theJDBCUtil.closeJDBCResultSet(selectRS);
-                    }
-                }
-
-                if (dbUpdated) {
-                    LOGGER.debug("Insertion request issued by {}", senderMailAddress);
-                }
-                // Commit our changes if necessary.
-                if (conn != null && dbUpdated && !conn.getAutoCommit()) {
-                    conn.commit();
-                    dbUpdated = false;
-                }
-            } else {
-                out.println("The message must be plain - no action");
-            }
-
-            out.println();
-            out.println("Finished");
-
-            sendReplyFromPostmaster(mail, sout.toString());
-
-        } catch (SQLException sqle) {
-            out.println("Error accessing the database");
-            sendReplyFromPostmaster(mail, sout.toString());
-            throw new MessagingException("Error accessing the database", sqle);
-        } catch (IOException ioe) {
-            out.println("Error getting message content");
-            sendReplyFromPostmaster(mail, sout.toString());
-            throw new MessagingException("Error getting message content", ioe);
-        } finally {
-            theJDBCUtil.closeJDBCStatement(selectStmt);
-            theJDBCUtil.closeJDBCStatement(insertStmt);
-            // Rollback our changes if necessary.
-            try {
-                if (conn != null && dbUpdated && !conn.getAutoCommit()) {
-                    conn.rollback();
-                    dbUpdated = false;
-                }
-            } catch (Exception e) {
-                LOGGER.error("Ignored exception upon rollback", e);
-            }
-            theJDBCUtil.closeJDBCConnection(conn);
-        }
-    }
-
-    /**
-     * Manages a remove request.
-     */
-    private void manageRemoveRequest(Mail mail) throws MessagingException {
-        MailAddress senderMailAddress = mail.getMaybeSender().get();
-        String senderUser = senderMailAddress.getLocalPart().toLowerCase(Locale.US);
-        Domain senderHost = senderMailAddress.getDomain();
-
-        Connection conn = null;
-        PreparedStatement selectStmt = null;
-        PreparedStatement deleteStmt = null;
-        boolean dbUpdated = false;
-
-        StringWriter sout = new StringWriter();
-        PrintWriter out = new PrintWriter(sout, true);
-
-        try {
-            out.println("Answering on behalf of: " + whitelistManagerAddress);
-            out.println("Removing from the white list of " + (new MailAddress(senderUser, senderHost)) + " ...");
-            out.println();
-
-            MimeMessage message = mail.getMessage();
-
-            Object content = message.getContent();
-
-            if (message.getContentType().startsWith("text/plain") && content instanceof String) {
-                StringTokenizer st = new StringTokenizer((String) content, " \t\n\r\f,;:<>");
-                while (st.hasMoreTokens()) {
-                    ResultSet selectRS = null;
-                    try {
-                        MailAddress recipientMailAddress;
-                        try {
-                            recipientMailAddress = new MailAddress(st.nextToken());
-                        } catch (jakarta.mail.internet.ParseException pe) {
-                            continue;
-                        }
-                        String recipientUser = recipientMailAddress.getLocalPart().toLowerCase(Locale.US);
-                        Domain recipientHost = recipientMailAddress.getDomain();
-
-                        if (getMailetContext().isLocalServer(recipientHost)) {
-                            // not a remote recipient, so skip
-                            continue;
-                        }
-
-                        if (conn == null) {
-                            conn = datasource.getConnection();
-                        }
-
-                        if (selectStmt == null) {
-                            selectStmt = conn.prepareStatement(selectByPK);
-                        }
-                        selectStmt.setString(1, senderUser);
-                        selectStmt.setString(2, senderHost.asString());
-                        selectStmt.setString(3, recipientUser);
-                        selectStmt.setString(4, recipientHost.asString());
-                        selectRS = selectStmt.executeQuery();
-                        if (!selectRS.next()) {
-                            // This address was not in the list
-                            out.println("Skipped: " + recipientMailAddress);
-                            continue;
-                        }
-
-                        if (deleteStmt == null) {
-                            deleteStmt = conn.prepareStatement(deleteByPK);
-                        }
-                        deleteStmt.setString(1, senderUser);
-                        deleteStmt.setString(2, senderHost.asString());
-                        deleteStmt.setString(3, recipientUser);
-                        deleteStmt.setString(4, recipientHost.asString());
-                        deleteStmt.executeUpdate();
-                        dbUpdated = true;
-                        out.println("Removed: " + recipientMailAddress);
-
-                    } finally {
-                        theJDBCUtil.closeJDBCResultSet(selectRS);
-                    }
-                }
-
-                if (dbUpdated) {
-                    LOGGER.debug("Removal request issued by {}", senderMailAddress);
-                }
-                // Commit our changes if necessary.
-                if (conn != null && dbUpdated && !conn.getAutoCommit()) {
-                    conn.commit();
-                    dbUpdated = false;
-                }
-            } else {
-                out.println("The message must be plain - no action");
-            }
-
-            out.println();
-            out.println("Finished");
-
-            sendReplyFromPostmaster(mail, sout.toString());
-
-        } catch (SQLException sqle) {
-            out.println("Error accessing the database");
-            sendReplyFromPostmaster(mail, sout.toString());
-            throw new MessagingException("Error accessing the database", sqle);
-        } catch (IOException ioe) {
-            out.println("Error getting message content");
-            sendReplyFromPostmaster(mail, sout.toString());
-            throw new MessagingException("Error getting message content", ioe);
-        } finally {
-            theJDBCUtil.closeJDBCStatement(selectStmt);
-            theJDBCUtil.closeJDBCStatement(deleteStmt);
-            // Rollback our changes if necessary.
-            try {
-                if (conn != null && dbUpdated && !conn.getAutoCommit()) {
-                    conn.rollback();
-                    dbUpdated = false;
-                }
-            } catch (Exception e) {
-                LOGGER.error("Ignored exception upon rollback", e);
-            }
-            theJDBCUtil.closeJDBCConnection(conn);
-        }
-    }
-
-    private void sendReplyFromPostmaster(Mail mail, String stringContent) {
-        try {
-            MailAddress notifier = getMailetContext().getPostmaster();
-
-            MailAddress senderMailAddress = mail.getMaybeSender().get();
-
-            MimeMessage message = mail.getMessage();
-            // Create the reply message
-            MimeMessage reply = new MimeMessage(Session.getDefaultInstance(System.getProperties(), null));
-
-            // Create the list of recipients in the Address[] format
-            reply.setRecipients(Message.RecipientType.TO, senderMailAddress.toInternetAddress().stream()
-                .collect(ImmutableList.toImmutableList())
-                .toArray(new InternetAddress[0]));
-
-            // Set the sender...
-            notifier.toInternetAddress()
-                .ifPresent(Throwing.<Address>consumer(reply::setFrom).sneakyThrow());
-
-            // Create the message body
-            MimeMultipart multipart = new MimeMultipart();
-            // Add message as the first mime body part
-            MimeBodyPart part = new MimeBodyPart();
-            part.setContent(stringContent, "text/plain");
-            part.setHeader(RFC2822Headers.CONTENT_TYPE, "text/plain");
-            multipart.addBodyPart(part);
-
-            reply.setContent(multipart);
-            reply.setHeader(RFC2822Headers.CONTENT_TYPE, multipart.getContentType());
-
-            // Create the list of recipients in our MailAddress format
-            Set<MailAddress> recipients = new HashSet<>();
-            recipients.add(senderMailAddress);
-
-            // Set additional headers
-            if (reply.getHeader(RFC2822Headers.DATE) == null) {
-                reply.setHeader(RFC2822Headers.DATE, DateFormats.RFC822_DATE_FORMAT.format(ZonedDateTime.now()));
-            }
-            String subject = message.getSubject();
-            if (subject == null) {
-                subject = "";
-            }
-            if (subject.indexOf("Re:") == 0) {
-                reply.setSubject(subject);
-            } else {
-                reply.setSubject("Re:" + subject);
-            }
-            reply.setHeader(RFC2822Headers.IN_REPLY_TO, message.getMessageID());
-
-            // Send it off...
-            getMailetContext().sendMail(notifier, recipients, reply);
-        } catch (Exception e) {
-            LOGGER.error("Exception found sending reply", e);
-        }
-    }
-
-    /**
-     * Initializes the sql query environment from the SqlResources file. Will
-     * look for conf/sqlResources.xml.
-     * 
-     * @param conn
-     *            The connection for accessing the database
-     * @param mailetContext
-     *            The current mailet context, for finding the
-     *            conf/sqlResources.xml file
-     * @throws Exception
-     *             If any error occurs
-     */
-    private void initSqlQueries(Connection conn, org.apache.mailet.MailetContext mailetContext) throws Exception {
-        try {
-            if (conn.getAutoCommit()) {
-                conn.setAutoCommit(false);
-            }
-
-            /*
-                Holds value of property sqlFile.
-            */
-            String confDir = getInitParameterAsOptional("confDir")
-                .orElseThrow(() -> new MailetException("WhiteListManager has no 'confDir' configured"));
-
-            File sqlFile = new File(confDir, "sqlResources.xml").getCanonicalFile();
-            sqlQueries.init(sqlFile, "WhiteList", conn, getSqlParameters());
-
-            checkTables(conn);
-        } finally {
-            theJDBCUtil.closeJDBCConnection(conn);
-        }
-    }
-
-    private void checkTables(Connection conn) throws SQLException {
-
-        // Need to ask in the case that identifiers are stored, ask the
-        // DatabaseMetaInfo.
-        // Try UPPER, lower, and MixedCase, to see if the table is there.
-
-        boolean dbUpdated;
-
-        dbUpdated = createTable(conn, "whiteListTableName", "createWhiteListTable");
-
-        // Commit our changes if necessary.
-        if (conn != null && dbUpdated && !conn.getAutoCommit()) {
-            conn.commit();
-            dbUpdated = false;
-        }
-
-    }
-
-    private boolean createTable(Connection conn, String tableNameSqlStringName, String createSqlStringName) throws SQLException {
-        String tableName = sqlQueries.getSqlString(tableNameSqlStringName, true);
-
-        DatabaseMetaData dbMetaData = conn.getMetaData();
-
-        // Try UPPER, lower, and MixedCase, to see if the table is there.
-        if (theJDBCUtil.tableExists(dbMetaData, tableName)) {
-            return false;
-        }
-
-        PreparedStatement createStatement = null;
-
-        try {
-            createStatement = conn.prepareStatement(sqlQueries.getSqlString(createSqlStringName, true));
-            createStatement.execute();
-
-            LOGGER.info("Created table '{}' using sqlResources string '{}'.", tableName, createSqlStringName);
-
-        } finally {
-            theJDBCUtil.closeJDBCStatement(createStatement);
-        }
-
-        return true;
-    }
-
-}
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/AbstractSQLWhitelistMatcher.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/AbstractSQLWhitelistMatcher.java
deleted file mode 100644
index bb95782805..0000000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/AbstractSQLWhitelistMatcher.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/****************************************************************
- * 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.transport.matchers;
-
-import java.io.File;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import javax.sql.DataSource;
-
-import jakarta.inject.Inject;
-import jakarta.mail.MessagingException;
-
-import org.apache.james.core.Domain;
-import org.apache.james.core.MailAddress;
-import org.apache.james.filesystem.api.FileSystem;
-import org.apache.james.transport.mailets.WhiteListManager;
-import org.apache.james.user.api.UsersRepository;
-import org.apache.james.util.sql.JDBCUtil;
-import org.apache.james.util.sql.SqlResources;
-import org.apache.mailet.Experimental;
-import org.apache.mailet.Mail;
-import org.apache.mailet.base.GenericMatcher;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * No documentation is available for this deprecated, experimental matcher.
- */
-@SuppressWarnings("deprecation")
-@Experimental
-public abstract class AbstractSQLWhitelistMatcher extends GenericMatcher {
-    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSQLWhitelistMatcher.class);
-
-    /**
-     * The user repository for this mail server. Contains all the users with
-     * inboxes on this server.
-     */
-    private UsersRepository localusers;
-
-    protected DataSource datasource;
-    protected JDBCUtil jdbcUtil;
-
-    /** Holds value of property sqlParameters. */
-    private final Map<String, String> sqlParameters = new HashMap<>();
-
-
-    @Inject
-    public void setDataSource(DataSource datasource) {
-        this.datasource = datasource;
-    }
-
-    @Inject
-    public void setUsersRepository(UsersRepository localusers) {
-        this.localusers = localusers;
-    }
-    
-    @Inject
-    public void setJdbcUtil(JDBCUtil jdbcUtil) {
-        this.jdbcUtil = jdbcUtil;
-    }
-
-    /**
-     * Getter for property sqlParameters.
-     * 
-     * @return Value of property sqlParameters.
-     */
-    private Map<String, String> getSqlParameters() {
-        return this.sqlParameters;
-    }
-
-    /**
-     * The JDBCUtil helper class
-     */
-    protected final JDBCUtil theJDBCUtil = new JDBCUtil();
-
-    /**
-     * Contains all of the sql strings for this component.
-     */
-    protected final SqlResources sqlQueries = new SqlResources();
-
-    private FileSystem fs;
-
-    @Inject
-    public void setFilesystem(FileSystem fs) {
-        this.fs = fs;
-    }
-
-    @Override
-    public void init() throws MessagingException {
-        String repositoryPath = null;
-        StringTokenizer st = new StringTokenizer(getCondition(), ", \t", false);
-        if (st.hasMoreTokens()) {
-            repositoryPath = st.nextToken().trim();
-        }
-        if (repositoryPath != null) {
-            LOGGER.info("repositoryPath: {}", repositoryPath);
-        } else {
-            throw new MessagingException("repositoryPath is null");
-        }
-
-        try {
-            initSqlQueries(datasource.getConnection(), getMailetContext());
-        } catch (Exception e) {
-            throw new MessagingException("Exception initializing queries", e);
-        }
-
-        super.init();
-    }
-
-    @Override
-    public Collection<MailAddress> match(Mail mail) throws MessagingException {
-        // check if it's a local sender
-        if (!mail.hasSender()) {
-            return null;
-        }
-        MailAddress senderMailAddress = mail.getMaybeSender().get();
-        if (getMailetContext().isLocalEmail(senderMailAddress)) {
-            // is a local sender, so return
-            return null;
-        }
-
-        String senderUser = senderMailAddress.getLocalPart();
-
-        senderUser = senderUser.toLowerCase(Locale.US);
-
-        Collection<MailAddress> recipients = mail.getRecipients();
-
-        Collection<MailAddress> inWhiteList = new java.util.HashSet<>();
-
-        for (MailAddress recipientMailAddress : recipients) {
-            String recipientUser = recipientMailAddress.getLocalPart().toLowerCase(Locale.US);
-            Domain recipientHost = recipientMailAddress.getDomain();
-
-            if (!getMailetContext().isLocalServer(recipientHost)) {
-                // not a local recipient, so skip
-                continue;
-            }
-
-            if (matchedWhitelist(recipientMailAddress, mail)) {
-                // This address was already in the list
-                inWhiteList.add(recipientMailAddress);
-            }
-
-        }
-
-        return inWhiteList;
-
-    }
-
-    protected abstract boolean matchedWhitelist(MailAddress recipient, Mail mail) throws MessagingException;
-
-    /**
-     * Initializes the sql query environment from the SqlResources file.<br>
-     * Will look for conf/sqlResources.xml.<br>
-     * Will <strong>not</<strong> create the database resources, if missing<br>
-     * (this task is done, if needed, in the {@link WhiteListManager}
-     * initialization routine).
-     * 
-     * @param conn
-     *            The connection for accessing the database
-     * @param mailetContext
-     *            The current mailet context, for finding the
-     *            conf/sqlResources.xml file
-     * @throws Exception
-     *             If any error occurs
-     */
-    protected void initSqlQueries(Connection conn, org.apache.mailet.MailetContext mailetContext) throws Exception {
-        try {
-            if (conn.getAutoCommit()) {
-                conn.setAutoCommit(false);
-            }
-
-            /* Holds value of property sqlFile. */
-            File sqlFile = fs.getFile("classpath:sqlResources.xml");
-            sqlQueries.init(sqlFile, getSQLSectionName(), conn, getSqlParameters());
-            checkTables(conn);
-        } finally {
-            theJDBCUtil.closeJDBCConnection(conn);
-        }
-    }
-
-    protected abstract String getTableName();
-
-    protected abstract String getTableCreateQueryName();
-
-    private void checkTables(Connection conn) throws SQLException {
-
-        // Need to ask in the case that identifiers are stored, ask the
-        // DatabaseMetaInfo.
-        // Try UPPER, lower, and MixedCase, to see if the table is there.
-
-        boolean dbUpdated;
-
-        dbUpdated = createTable(conn, getTableName(), getTableCreateQueryName());
-
-        // Commit our changes if necessary.
-        if (conn != null && dbUpdated && !conn.getAutoCommit()) {
-            conn.commit();
-            dbUpdated = false;
-        }
-
-    }
-
-    private boolean createTable(Connection conn, String tableNameSqlStringName, String createSqlStringName) throws SQLException {
-        String tableName = sqlQueries.getSqlString(tableNameSqlStringName, true);
-
-        DatabaseMetaData dbMetaData = conn.getMetaData();
-
-        // Try UPPER, lower, and MixedCase, to see if the table is there.
-        if (theJDBCUtil.tableExists(dbMetaData, tableName)) {
-            return false;
-        }
-
-        PreparedStatement createStatement = null;
-
-        try {
-            createStatement = conn.prepareStatement(sqlQueries.getSqlString(createSqlStringName, true));
-            createStatement.execute();
-
-            LOGGER.info("Created table '{}' using sqlResources string '{}'.", tableName, createSqlStringName);
-
-        } finally {
-            theJDBCUtil.closeJDBCStatement(createStatement);
-        }
-
-        return true;
-    }
-
-    protected abstract String getSQLSectionName();
-}
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/IsInWhiteList.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/IsInWhiteList.java
deleted file mode 100644
index 04eee01e13..0000000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/IsInWhiteList.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/****************************************************************
- * 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.transport.matchers;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Locale;
-
-import jakarta.mail.MessagingException;
-
-import org.apache.james.core.Domain;
-import org.apache.james.core.MailAddress;
-import org.apache.mailet.Experimental;
-import org.apache.mailet.Mail;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * <p>
- * Matches recipients having the mail sender in the recipient's private
- * whitelist .
- * </p>
- * <p>
- * The recipient name is always converted to its primary name (handling
- * aliases).
- * </p>
- * <p>
- * Configuration string: The database name containing the white list table.
- * </p>
- * <p>
- * Example:
- * 
- * <pre>
- *  &lt;mailet match=&quot;IsInWhiteList=db://maildb&quot; class=&quot;ToProcessor&quot;&gt;
- *     &lt;processor&gt; transport &lt;/processor&gt;
- *  &lt;/mailet&gt;
- * </pre>
- * 
- * </p>
- * 
- * @see org.apache.james.transport.mailets.WhiteListManager
- * @since 2.3.0
- */
-@Experimental
-public class IsInWhiteList extends AbstractSQLWhitelistMatcher {
-    private static final Logger LOGGER = LoggerFactory.getLogger(IsInWhiteList.class);
-
-    private String selectByPK;
-
-    @Override
-    public void init() throws MessagingException {
-        super.init();
-        selectByPK = sqlQueries.getSqlString("selectByPK", true);
-    }
-
-    @Override
-    protected String getSQLSectionName() {
-        return "WhiteList";
-    }
-
-    @Override
-    protected boolean matchedWhitelist(MailAddress recipientMailAddress, Mail mail) throws MessagingException {
-        if (!mail.hasSender()) {
-            return true;
-        }
-        MailAddress senderMailAddress = mail.getMaybeSender().get();
-        String senderUser = senderMailAddress.getLocalPart().toLowerCase(Locale.US);
-        Domain senderHost = senderMailAddress.getDomain();
-
-        Connection conn = null;
-        PreparedStatement selectStmt = null;
-        ResultSet selectRS = null;
-        try {
-            String recipientUser = recipientMailAddress.getLocalPart().toLowerCase(Locale.US);
-            Domain recipientHost = recipientMailAddress.getDomain();
-
-            if (conn == null) {
-                conn = datasource.getConnection();
-            }
-
-            try {
-                if (selectStmt == null) {
-                    selectStmt = conn.prepareStatement(selectByPK);
-                }
-                selectStmt.setString(1, recipientUser);
-                selectStmt.setString(2, recipientHost.asString());
-                selectStmt.setString(3, senderUser);
-                selectStmt.setString(4, senderHost.asString());
-                selectRS = selectStmt.executeQuery();
-                if (selectRS.next()) {
-                    // This address was already in the list
-                    return true;
-                }
-            } finally {
-                jdbcUtil.closeJDBCResultSet(selectRS);
-                jdbcUtil.closeJDBCStatement(selectStmt);
-            }
-            
-            try {
-                // check for wildcard domain entries
-                selectStmt = conn.prepareStatement(selectByPK);
-    
-                selectStmt.setString(1, recipientUser);
-                selectStmt.setString(2, recipientHost.asString());
-                selectStmt.setString(3, "*");
-                selectStmt.setString(4, senderHost.asString());
-                selectRS = selectStmt.executeQuery();
-                if (selectRS.next()) {
-                    // This address was already in the list
-                    return true;
-                }
-            } finally {
-                jdbcUtil.closeJDBCResultSet(selectRS);
-                jdbcUtil.closeJDBCStatement(selectStmt);
-            }
-
-            try {
-                // check for wildcard recipient domain entries
-                selectStmt = conn.prepareStatement(selectByPK);
-    
-                selectStmt.setString(1, "*");
-                selectStmt.setString(2, recipientHost.asString());
-                selectStmt.setString(3, senderUser);
-                selectStmt.setString(4, senderHost.asString());
-                selectRS = selectStmt.executeQuery();
-                if (selectRS.next()) {
-                    // This address was already in the list
-                    return true;
-                }
-            } finally {
-                jdbcUtil.closeJDBCResultSet(selectRS);
-                jdbcUtil.closeJDBCStatement(selectStmt);
-            }
-
-            try {
-                // check for wildcard domain entries on both
-                selectStmt = conn.prepareStatement(selectByPK);
-    
-                selectStmt.setString(1, "*");
-                selectStmt.setString(2, recipientHost.asString());
-                selectStmt.setString(3, "*");
-                selectStmt.setString(4, senderHost.asString());
-                selectRS = selectStmt.executeQuery();
-                if (selectRS.next()) {
-                    // This address was already in the list
-                    return true;
-                }
-            } finally {
-                jdbcUtil.closeJDBCResultSet(selectRS);
-                jdbcUtil.closeJDBCStatement(selectStmt);
-            }
-        } catch (SQLException sqle) {
-            LOGGER.error("Error accessing database", sqle);
-            throw new MessagingException("Exception thrown", sqle);
-        } finally {
-            theJDBCUtil.closeJDBCConnection(conn);
-        }
-        return false;
-    }
-
-    @Override
-    protected String getTableCreateQueryName() {
-        return "createWhiteListTable";
-    }
-
-    @Override
-    protected String getTableName() {
-        return "whiteListTableName";
-    }
-
-}
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/NetworkIsInWhitelist.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/NetworkIsInWhitelist.java
deleted file mode 100644
index 53998809af..0000000000
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/matchers/NetworkIsInWhitelist.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************
- * 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.transport.matchers;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
-import jakarta.inject.Inject;
-import jakarta.mail.MessagingException;
-
-import org.apache.james.core.MailAddress;
-import org.apache.james.dnsservice.api.DNSService;
-import org.apache.james.dnsservice.library.netmatcher.NetMatcher;
-import org.apache.mailet.Experimental;
-import org.apache.mailet.Mail;
-
-/**
- * <p>
- * Matcher which lookup whitelisted networks in a database. The networks can be
- * specified via netmask.
- * </p>
- * <p>
- * For example: <code>192.168.0.0/24</code>
- * </p>
- * <p>
- * Th whitelisting is done per recipient
- * </p>
- */
-@Experimental
-public class NetworkIsInWhitelist extends AbstractSQLWhitelistMatcher {
-    private DNSService dns;
-    private String selectNetworks;
-
-    /**
-     * Injection setter for the DNSService.
-     * 
-     * @param dns
-     */
-    @Inject
-    public void setDNSService(DNSService dns) {
-        this.dns = dns;
-    }
-
-    @Override
-    protected String getSQLSectionName() {
-        return "NetworkWhiteList";
-    }
-
-    @Override
-    public void init() throws MessagingException {
-        super.init();
-        selectNetworks = sqlQueries.getSqlString("selectNetwork", true);
-
-    }
-
-    @Override
-    protected boolean matchedWhitelist(MailAddress recipientMailAddress, Mail mail) throws MessagingException {
-        Connection conn = null;
-        PreparedStatement selectStmt = null;
-        ResultSet selectRS = null;
-        try {
-            String recipientUser = recipientMailAddress.getLocalPart().toLowerCase(Locale.US);
-            String recipientHost = recipientMailAddress.getDomain().asString();
-
-            conn = datasource.getConnection();
-
-            List<String> nets = new ArrayList<>();
-            try {
-                selectStmt = conn.prepareStatement(selectNetworks);
-                selectStmt.setString(1, recipientUser);
-                selectStmt.setString(2, recipientHost);
-                selectRS = selectStmt.executeQuery();
-                while (selectRS.next()) {
-                    nets.add(selectRS.getString(1));
-                }
-            } finally {
-                jdbcUtil.closeJDBCResultSet(selectRS);
-                jdbcUtil.closeJDBCStatement(selectStmt);
-            }
-            NetMatcher matcher = new NetMatcher(nets, dns);
-            boolean matched = matcher.matchInetNetwork(mail.getRemoteAddr());
-
-            if (!matched) {
-                try {
-                    selectStmt = conn.prepareStatement(selectNetworks);
-                    selectStmt.setString(1, "*");
-                    selectStmt.setString(2, recipientHost);
-                    selectRS = selectStmt.executeQuery();
-                    nets = new ArrayList<>();
-                    while (selectRS.next()) {
-                        nets.add(selectRS.getString(1));
-                    }
-                } finally {
-                    jdbcUtil.closeJDBCResultSet(selectRS);
-                    jdbcUtil.closeJDBCStatement(selectStmt);
-                }
-                matcher = new NetMatcher(nets, dns);
-                matched = matcher.matchInetNetwork(mail.getRemoteAddr());
-            }
-            return matched;
-        } catch (SQLException sqle) {
-            throw new MessagingException("Error accessing database", sqle);
-        } finally {
-            theJDBCUtil.closeJDBCConnection(conn);
-        }
-    }
-
-    @Override
-    protected String getTableCreateQueryName() {
-        return "createNetworkWhiteListTable";
-    }
-
-    @Override
-    protected String getTableName() {
-        return "networkWhiteListTableName";
-    }
-
-}
diff --git a/upgrade-instructions.md b/upgrade-instructions.md
index bbfb543f4b..183c5f7d6b 100644
--- a/upgrade-instructions.md
+++ b/upgrade-instructions.md
@@ -31,6 +31,18 @@ Change list:
  - [javax -> jakarta](#javax---jakarta)
  - [Make all queues on RabbitMQ quorum queue when `quorum.queues.enable=true`](#make-all-queues-on-rabbitmq-quorum-queue-when-quorumqueuesenabletrue)
  - [Migrate RabbitMQ classic queues to version 2](#migrate-rabbitmq-classic-queues-to-version-2)
+ - [JAMES-3946 removals](#james-3946-white-list-removals)
+
+#### JAMES-3946 White list removals
+
+Date: 14/06/2024
+
+JIRA: https://issues.apache.org/jira/browse/JAMES-3946
+
+The experimental classes pertaining to "white list" management have been removed.
+
+This includes:
+- AbstractSQLWhitelistMatcher, IsInWhiteList, WhiteListManager, NetworkIsInWhitelist. Please use IsInDropList matcher instead.
 
 ### Migrate RabbitMQ classic queues to version 2
 


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