Add active sender validation

This forum contains features that has been archived. This section contains implemented features, duplicate requests, and requests which we have decided not to implement.
Post Reply
mvdlande
New user
New user
Posts: 13
Joined: 2006-02-07 16:20
Location: the Netherlands

Add active sender validation

Post by mvdlande » 2006-07-20 09:09

<updated, I changed some code!>
I have been using the SURBLE script and it filters out a lot of SPAM. I noticed that the SPAM I still receive either has an invalid sender address or an empty sender address. (When I disable "allow empty sender address" some servers who do active sender validation reject my mail.) Therefore I put this check in a script. As for the active sender validation I wrote a program in C# with "Microsoft Visual C# 2005 Express Edition" (free).

The input to the executable is "sTo sFrom sMX sHostname"
sTo = address to validate
sFrom = address to identify yourselve
sMX = a comma seperated list of Mail servers handling sTo
sHostname = the server internet hostname

The output is an integer error code
0 = valid address
anything else, no valid address (see source)

I named the executable ValidateEmail.exe

If you want to use the script, modify the paths in the script to point to a valid location (see script)

I Have my source here:
ftp://vandelande.com/ValidateEmail/

This is the script

Code: Select all


   Sub OnAcceptMessage(oClient, oMessage) 

   ' add strSource = "[YASU]" in the messages rejected by SURBLE script
   strSource = "[none]" 

   ' Insert SURBLE script

   ' End SURBLE script
 
    dim oUtil
    Set oUtil = CreateObject("hMailServer.Utilities")
    'Check for an empty sender address
    If InStr(1 , oMessage.FromAddress , "@" , 1 ) >= 1 Then
        Result.Value = 0   'deliver the message
    Else
        Result.Value = 1   'reject the message
        strSource = "[No sender]" 
    End If


    If Result.Value = 0 Then
        mail = oUtil.GetMailServer(oMessage.FromAddress)
        mail = Replace(mail, " ", "", 1, -1, 1)
        ' sFrom = "ValidateEmail@yourdomain.com"
        sFrom = "" 
        sTo = oMessage.FromAddress
	sMX = mail
        'SLocalHost = "your domain"
	slocalHost = "yourdomain.com"
        'sLogDir is not used yet
	sLogDir = "c:\logs\"
        ValidSender = oShell.Run("E:\hMailServer\Events\ValidateEmail.exe " & sTo & " " & sFrom & " " & sMX & " " & sLocalHost & " " & sLogDir , 0, TRUE) 
        If ValidSender = 0 Then
            strSource = "[valid sender address] " & ValidSender 
        Else
            Result.Value = 1
             strSource = "[no valid sender address] " & ValidSender 
        End If
    End If


    ' Write a log file of the results

    If Result.Value = 1 Then
        SET oFs = CreateObject("Scripting.FileSystemObject") 
        SET oFil = ofs.OpenTextFile("C:\Logs\hMailserver\rejected_" & Date() & ".log", 8, True) 'open for append, create if not exists 
      oFil.WriteLine(Now() & " Mail From : " & "<" & oMessage.FromAddress & "> " & strSource )
      oFil.Close 
      SET oFil = Nothing 
      SET oFs = Nothing 
   Else
      SET oFs = CreateObject("Scripting.FileSystemObject") 
      SET oFil = ofs.OpenTextFile("C:\Logs\hMailserver\accepted_" & Date() & ".log", 8, True) 'open for append, create if not exists 
      oFil.WriteLine(Now() & " Mail From : " & "<" & oMessage.FromAddress & "> " & strSource )
      oFil.Close 
      SET oFil = Nothing 
      SET oFs = Nothing 
   End If



   End Sub 
This is my test script

Code: Select all


   Set oMessage = CreateObject("hMailServer.Utilities")
   Set oShell = CreateObject("WScript.Shell") 


'   sTo = "busscranford@legislator.com"
    sTo = "aideblast@columnist.com"
    sTo = "alginateboogie@catlover.com"
    sTo = "cliqueambulatory@scientist.com"

   sFrom = "" ' add your email address


   mail = oMessage.GetMailServer(sTo)
   mail = Replace(mail, " ", "", 1, -1, 1)
   sMX = mail
   sLocalhost = "yourhost" ' add your hostname
   sLogDir = "E:\C#\ValidateEmail\ValidateEmail\bin\Release\"
   intRetVal = oShell.Run("ValidateEmail.exe " & sTo & " " & sFrom & " " & sMX & " " & sLocalhost & " " & sLogDir, 0, TRUE) 
   WScript.Echo intRetVal  
This is my ValidateEmail C# source code

Code: Select all


#define TRACE_ON
using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.Net.NetworkInformation;
using System.IO;
using System.Threading;
using System.Diagnostics;


namespace ConsoleApplication1
{
     class Program
    {
        private enum SMTPResponse : int
        {
            CONNECT_SUCCESS = 220,
            GENERIC_SUCCESS = 250,
            DATA_SUCCESS = 354,
            QUIT_SUCCESS = 221
        }
        static bool timeout;

        //[Conditional("TRACE_ON")]
        static int Main(string[] args)
        {
            string today = DateTime.Today.ToShortDateString().Replace('/', '-');
            string now = DateTime.Now.ToLongTimeString(); 
            string To = "<" + args[0] + ">";
            string From = "<" + args[1] + ">";
            string MX = args[2];

            string localhost = args[3];
            //string LogDir = args[4];
            MX = MX.Trim(',');
            //String FileName = LogDir + "debug-" + today + ".log";
            
            // check for a "no-reply" user
            string[] users = To.Split('@');
            string user = users[0];
            user = user.ToLower();
            if ((user == "no-reply") || (user == "noreply"))
                return 0;
            // turn the MX host IP's into an array
            string[] hosts = MX.Split(',');
            string host;
            int i = 0;
            // try a maximum of 3 MX servers (when available)
            while (i < 3)
            {
                try
                {
                    host = hosts[i];
                    try
                    {
                        IPEndPoint endPt = new IPEndPoint(IPAddress.Parse(host), 25);
                        Socket tcpSocket = new Socket(endPt.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                        // SMTP time-out discussion (use 5 minuts)
                        // http://www.freesoft.org/CIE/RFC/1123/109.htm
                        // Set the timeout for synchronous receive methods to 
                        // 1 second (1000 milliseconds.)
                        tcpSocket.ReceiveTimeout = 300000;
                        // Set the timeout for synchronous send methods
                        // to 1 second (1000 milliseconds.)            
                        tcpSocket.SendTimeout = 300000;
                        // Set the Time to live, TTL
                        // to 64 hops.
                        tcpSocket.Ttl = 128;
                        // Set receive buffer size 
                        // to 1023 bytes.
                        //tcpSocket.ReceiveBufferSize = 1023;
                        tcpSocket.Connect(endPt);


                        //Attempting to connect
                        if (!Check_Response(tcpSocket, SMTPResponse.CONNECT_SUCCESS))
                        {
                            if (timeout)
                            {
                                tcpSocket.Close();
                            }
                            else
                            {
                                tcpSocket.Close();
                                return 2;
                            }
                        }

                        //HELO server
                        //Senddata(s, string.Format("HELO {0}\r\n", Dns.GetHostName()));
                        Senddata(tcpSocket, string.Format("HELO {0}\r\n", localhost));
                        if (!Check_Response(tcpSocket, SMTPResponse.GENERIC_SUCCESS))
                        {
                            if (timeout)
                            {
                                tcpSocket.Close();
                            }
                            else
                            {
                                tcpSocket.Close();
                                return 3;

                            }
                        }
                        //Identify yourself
                        //Servers may resolve your domain and check whether 
                        //you are listed in BlackLists etc.
                        Senddata(tcpSocket, string.Format("MAIL From: {0}\r\n", From));
                        if (!Check_Response(tcpSocket, SMTPResponse.GENERIC_SUCCESS))
                        {
                            //Senddata(tcpSocket, "QUIT\r\n", sw);
                            //Check_Response(tcpSocket, SMTPResponse.QUIT_SUCCESS, sw);
                            if (timeout)
                            {
                                tcpSocket.Close();
                            }
                            else
                            {
                                tcpSocket.Close();
                                return 4;
                            }
                        }
                        Senddata(tcpSocket, string.Format("RCPT TO: {0}\r\n", To));
                        if (!Check_Response(tcpSocket, SMTPResponse.GENERIC_SUCCESS))
                        {
                            //Senddata(tcpSocket, "QUIT\r\n");
                            if (timeout)
                            {
                                tcpSocket.Close();
                            }
                            else
                            {
                                tcpSocket.Close();
                                return 5;
                            }
                        }
                        Senddata(tcpSocket, "QUIT\r\n");
                        if (!timeout)
                        {
                            Check_Response(tcpSocket, SMTPResponse.QUIT_SUCCESS);

                            tcpSocket.Close();
                            return 0;
                        }
                    }
                    catch
                    {
                    }
                }
                catch
                {
                }
                i++;
            }
            return 100 + i;
        }


        private static void Senddata(Socket tcpSocket, string msg)
        {
            byte[] _msg = Encoding.ASCII.GetBytes(msg);
            tcpSocket.Send(_msg, 0, _msg.Length, SocketFlags.None);
        }

        private static bool Check_Response(Socket tcpSocket, SMTPResponse response_expected)
        {
            string sResponse;
            int response;
            int count = 0;
            byte[] bytes = new byte[1024];
            timeout = false;
            // wait a maximum of 5 miniuts
            while ((tcpSocket.Available == 0) && (count < 3000))
            {
                System.Threading.Thread.Sleep(100);
                count++;
            }
            tcpSocket.Receive(bytes, 0, tcpSocket.Available, SocketFlags.None);
            sResponse = Encoding.ASCII.GetString(bytes);
            response = Convert.ToInt32(sResponse.Substring(0, 3));

            if (response != (int)response_expected)
                return false;
            return true;
        }
    }
}
Old code for testing

Code: Select all



using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.Net.NetworkInformation;
using System.IO;
using System.Threading;
namespace ConsoleApplication1
{
    class Program
    {
        private enum SMTPResponse : int
        {
            CONNECT_SUCCESS = 220,
            GENERIC_SUCCESS = 250,
            DATA_SUCCESS = 354,
            QUIT_SUCCESS = 221
        }
        static bool timeout;
        static bool debug = true;
        static int Main(string[] args)
        {
            string today = DateTime.Today.ToShortDateString().Replace('/', '-');
            string now = DateTime.Now.ToLongTimeString(); 
            string To = "<" + args[0] + ">";
            string From = "<" + args[1] + ">";
            string MX = args[2];
            string localhost = args[3];
            //string LogDir = args[4];
            MX = MX.Trim(',');
            //String FileName = LogDir + "debug-" + today + ".log";
            String FileName = "debug.log";
            StreamWriter sw = new StreamWriter(FileName, true); // append
            if (debug) sw.Write("Start : {0} : {1} {2}" + "\r\n", now, today, To);
            
            // check for a "no-reply" user
            string[] users = To.Split('@');
            string user = users[0];
            user = user.ToLower();
            if ((user == "no-reply") || (user == "noreply"))
                return 0;
            // turn the MX host IP's into an array
            string[] hosts = MX.Split(',');
            string host;
            int i = 0;
            // try a maximum of 3 MX servers (when available)
            while (i < 3)
            {
                try
                {
                    if (debug) sw.Write("  i = {0}, ", i);
                    host = hosts[i];
                    if (debug) sw.Write("  host = {0} \r\n", host);
                    try
                    {
                        IPEndPoint endPt = new IPEndPoint(IPAddress.Parse(host), 25);
                        Socket tcpSocket = new Socket(endPt.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                        // SMTP time-out discussion (use 5 minuts)
                        // http://www.freesoft.org/CIE/RFC/1123/109.htm
                        // Set the timeout for synchronous receive methods to 
                        // 1 second (1000 milliseconds.)
                        tcpSocket.ReceiveTimeout = 300000;
                        // Set the timeout for synchronous send methods
                        // to 1 second (1000 milliseconds.)            
                        tcpSocket.SendTimeout = 300000;
                        // Set the Time to live, TTL
                        // to 64 hops.
                        tcpSocket.Ttl = 128;
                        // Set receive buffer size 
                        // to 1023 bytes.
                        //tcpSocket.ReceiveBufferSize = 1023;
                        tcpSocket.Connect(endPt);

                        if (debug) sw.Write("    Open connection {0} \r\n", host);

                        //Attempting to connect
                        if (!Check_Response(tcpSocket, SMTPResponse.CONNECT_SUCCESS, sw))
                        {
                            if (timeout)
                            {
                                if (debug) sw.Write("    Close connection {0} \r\n", host);
                                tcpSocket.Close();
                            }
                            else
                            {
                                if (debug) sw.Write("    Close connection {0} \r\n", host);
                                tcpSocket.Close();
                                if (debug) sw.Close();
                                return 2;
                            }
                        }

                        //HELO server
                        //Senddata(s, string.Format("HELO {0}\r\n", Dns.GetHostName()));
                        Senddata(tcpSocket, string.Format("HELO {0}\r\n", localhost), sw);
                        if (!Check_Response(tcpSocket, SMTPResponse.GENERIC_SUCCESS, sw))
                        {
                            if (timeout)
                            {
                                if (debug) sw.Write("    Close connection {0} \r\n", host);
                                tcpSocket.Close();
                            }
                            else
                            {
                                if (debug) sw.Write("    Close connection {0} \r\n", host);
                                tcpSocket.Close();
                                if (debug) sw.Close();
                                return 3;

                            }
                        }
                        //Identify yourself
                        //Servers may resolve your domain and check whether 
                        //you are listed in BlackLists etc.
                        Senddata(tcpSocket, string.Format("MAIL From: {0}\r\n", From), sw);
                        if (!Check_Response(tcpSocket, SMTPResponse.GENERIC_SUCCESS, sw))
                        {
                            //Senddata(tcpSocket, "QUIT\r\n", sw);
                            //Check_Response(tcpSocket, SMTPResponse.QUIT_SUCCESS, sw);
                            if (timeout)
                            {
                                if (debug) sw.Write("    Close connection {0} \r\n", host);
                                tcpSocket.Close();
                            }
                            else
                            {
                                if (debug) sw.Write("    Close connection {0} \r\n", host);
                                tcpSocket.Close();
                                if (debug) sw.Close();
                                return 4;
                            }
                        }
                        Senddata(tcpSocket, string.Format("RCPT TO: {0}\r\n", To), sw);
                        if (!Check_Response(tcpSocket, SMTPResponse.GENERIC_SUCCESS, sw))
                        {
                            //Senddata(tcpSocket, "QUIT\r\n", sw);
                            //Check_Response(tcpSocket, SMTPResponse.QUIT_SUCCESS, sw);
                            if (timeout)
                            {
                                if (debug) sw.Write("    Close connection {0} \r\n", host);
                                tcpSocket.Close();
                            }
                            else
                            {
                                if (debug) sw.Write("    Close connection {0} \r\n", host);
                                tcpSocket.Close();
                                if (debug) sw.Close();
                                return 5;
                            }
                        }
                        Senddata(tcpSocket, "QUIT\r\n", sw);
                        if (!timeout)
                        {
                            Check_Response(tcpSocket, SMTPResponse.QUIT_SUCCESS, sw);

                            if (debug) sw.Write("    Close connection {0} \r\n", host);
                            tcpSocket.Close();
                            if (debug) sw.Close();
                            return 0;
                        }
                    }
                    catch
                    {
                    }
                }
                catch
                {
                }
                i++;
            }
            if (debug) sw.Write("End \r\n");
            if (debug) sw.Close();
            return 100 + i;
        }


        private static void Senddata(Socket tcpSocket, string msg, StreamWriter sw)
        {
            byte[] _msg = Encoding.ASCII.GetBytes(msg);
            sw.Write("    msg = {0}" + "\r\n", msg);
            tcpSocket.Send(_msg, 0, _msg.Length, SocketFlags.None);
        }

        private static bool Check_Response(Socket tcpSocket, SMTPResponse response_expected, StreamWriter sw)
        {
            string sResponse;
            int response;
            int count = 0;
            byte[] bytes = new byte[1024];
            timeout = false;
            // wait a maximum of 5 miniuts
            while ((tcpSocket.Available == 0) && (count < 3000))
            {
                System.Threading.Thread.Sleep(100);
                count++;
            }
            /*if (tcpSocket.Available == 0)
            {
                if (debug) sw.Write("    timeout = {0} \r\n", count);
                timeout = true;
                return false;
            }
             */
            tcpSocket.Receive(bytes, 0, tcpSocket.Available, SocketFlags.None);
            sResponse = Encoding.ASCII.GetString(bytes);
            response = Convert.ToInt32(sResponse.Substring(0, 3));
            if (debug) sw.Write("    response = {0} \r\n", response);

            if (response != (int)response_expected)
                return false;
            return true;
        }
    }
}


westdam
Senior user
Senior user
Posts: 728
Joined: 2006-08-01 21:24
Location: Padova, Italy
Contact:

Post by westdam » 2006-08-18 13:08

hi, i'm coming from argosoft and this function was yet used as "aggressive verification" . It was very useful and stop a lot of spam.. Hmail dont have that function so i missed it.. Hehe thanks for the code. Hope martin put it as normal function . I'll ask on request forum.. Byez marco

Hotlanta
Normal user
Normal user
Posts: 46
Joined: 2006-12-04 20:46

Post by Hotlanta » 2006-12-07 01:10

Is this functionality built into hMailserver now? If not, is there a downside to aggressively validating email addresses?

Regards,

John

Thomas Parvais
Normal user
Normal user
Posts: 111
Joined: 2004-12-17 12:21
Contact:

Post by Thomas Parvais » 2007-09-18 14:27

Martin,

I was searching this function from a lont time ago. You've almost all function blocks in Hmailserver. Can you please implement them via COM interface.

Thank you

Thomas

User avatar
Asynchronous
New user
New user
Posts: 12
Joined: 2007-05-18 12:07
Location: France
Contact:

Post by Asynchronous » 2007-09-22 18:38

Sorry, i have a Script Error with required object "oShell"...

Post Reply