Sign in to follow this  
Followers 0
boomingranny

SMTP Server Tester

3 posts in this topic

#1 ·  Posted (edited)

Hi,

i am a computer technician who is a fan of autoit for making my life easier.

below is a script that i knocked up that will first lookup the MX record for a server you are attempting to email,

it will then do everything up to sending an email to that server, and report on it.

Usefull for testing and troubleshooting email server problems and more common now days - mail being rejected because your server is being misidentified as a spammer...

Enjoy :)

global $ErrorText = ""
ConsoleWrite("--------------------------------------------------------"&@CRLF)
ConsoleWrite("Advanced Email Server Tester"&@CRLF)
ConsoleWrite("by Daniel Barnes - djbarnes@orcon.net.nz"&@CRLF&@CRLF)
ConsoleWrite("Simulates What your Email Server does to send email"&@CRLF)
ConsoleWrite("--------------------------------------------------------"&@CRLF)

#include "array.au3"
$Email = inputbox("Email Server Tester Tool","Please enter the email address to test sending mail to:")
if @error > 0 then Exit
$Email = StringReplace($Email," ", "")
if StringInStr ($Email,"@") > 0 Then
    local $EmailDomain= StringTrimLeft($Email,stringinstr($Email,"@"))
Else
    msgbox (0, "Invalid Email address!","Invalid Email Address!")
    exit
endif

$from = Iniread("smtptest.ini","email","FromAddress","")
$from = inputbox("Email Server Tester Tool","Please enter your email address:",$from)
if @error > 0 then Exit
$from = StringReplace($from," ", "")
if StringInStr ($from,"@") > 0 Then
    local $FromDomain= StringTrimLeft($from,stringinstr($from,"@"))
else
    msgbox (0, "Invalid Email address!","Invalid Email Address!")
endif

$DNSserver = IniRead ("smtptest.ini","email","DefaultDNSServer","")
$DNSserver = inputbox ("Email Server Tester Tool", "Enter the DNS server to use: [blank = default]")
if @error > 0 then Exit
$DNSserver = StringReplace($DNSserver," ", "")

$mxRecords = nslookup_MX($EmailDomain,$DNSserver)
ConsoleWrite ("Looking up MX records for: "& $EmailDomain&@CRLF)
ConsoleWrite ("Asking DNS Server:        "& $DNSserver&@CRLF)
ConsoleWrite("--------------------------------------------------------"&@CRLF)
ConsoleWrite("MX Records:"&@CRLF)
ConsoleWrite("--------------------------------------------------------"&@CRLF)
if $mxRecords[0] = 0 then 
    ConsoleWrite ("ERROR: No MX Records found for "&$EmailDomain&@CRLF)
    $ErrorText = "ERROR: No MX Records found for "&$EmailDomain&@CRLF
endif
for $i = 1 to $mxRecords[0]
    ConsoleWrite($i &" " &$mxRecords[$i]&@CRLF)
next
ConsoleWrite("--------------------------------------------------------"&@CRLF)
ConsoleWrite("Attempting to send email via SMTP:"&@CRLF)
ConsoleWrite("--------------------------------------------------------"&@CRLF)
for $iMX = 1 to $mxRecords[0]
    ConsoleWrite("Asking "&$DNSserver &" for IP of "&$mxRecords[$iMX]&"..."&@CRLF)
    $ErrorText &= $mxRecords[$imx]&"..."
    $ip = nslookup_IP($mxRecords[$iMX],$DNSserver)
    ConsoleWrite($ip&@CRLF)
    ConsoleWrite ("Attempting To Test Email Sending (SMTP) to "&$ip &":25.")
    ConsoleWrite (smtp($ip,$from,$email) &@CRLF)
    ConsoleWrite(@CRLF)
    ConsoleWrite("--------------------------------------------------------"&@CRLF)
next
ConsoleWrite("Summary:"&@CRLF)
ConsoleWrite("From: " &$from & @CRLF)
ConsoleWrite("To:   " &$Email & @CRLF)
ConsoleWrite ($ErrorText)
ConsoleWrite("--------------------------------------------------------"&@CRLF)

IniWrite("smtptest.ini","email","FromAddress",$from)
IniWrite ("smtptest.ini","email","DefaultDNSServer",$DNSserver)
ConsoleWrite("press [esc] to close")

HotKeySet ("{ESC}","exiter")
while 1
    sleep (10000)
WEnd

func exiter()
    exit
EndFunc

;input the domain, returns an array of MX servers (in pref order hopefully!)
Func nslookup_MX($EmailDomain, byref $DNSserver)
    local $data
    local $pref
    local $MXRecordCount
    local $MXpref[99]
    local $MXName[99]
    $command = Run(@comspec & " /C nslookup -querytype=mx " & $EmailDomain&" " &$DNSserver, @SystemDir, @SW_HIDE,  2) 
    
    While 1
        $data &= StdoutRead($command)
        If @error Then ExitLoop
    Wend
    
;split into lines
    $data = StringReplace($data, @LF,"");remove line feeds
    $data = StringSplit ($data, @CR)
    for $i = 1 to $data[0]
        select
        case stringinstr ($data[$i], "Server:")
    ;remove the word Server: from the start
            $DNSserver = StringReplace ($data[$i], "Server:","")
    ;remove any spaces...
            $DNSserver = StringReplace ($DNSserver, " ","")
        case stringinstr ($data[$i], "mail exchanger = ")
            $MXRecordCount += 1
    ;captures the pref
            $MXpref[$MXRecordCount] = number(stringmid ($data[$i], stringinstr($data[$i],"MX preference =")+16,2))
    ;captures the name...
            $MXname[$MXRecordCount] = StringTrimLeft ($data[$i],stringinstr($data[$i],"mail exchanger =")+16)
        case Else
        endSelect
    next
    $MXName[0] = $MXRecordCount 
    $mxNamecopy = $mxName
    $mxprefSorted = $MXpref
    _arraysort ($mxprefSorted,0,1,$MXRecordCount)
    for $iMXRecord = 1 to $MXRecordCount
        for $isearch = 1 to $MXRecordCount
    ;if we have found the match then...
            if $mxpref[$iMXRecord] = $mxprefSorted[$isearch] Then
                $mxName[$iSearch] =  $mxNameCopy[$iMXRecord];resorting the mx Names...
                $mxprefSorted[$isearch] = -2;don't match this one again!
                $mxpref[$iMXRecord] = -1;don't match this one again!
            endif
        next
    next    
    return $mxName
EndFunc

;input the domainname, returns an IP
Func nslookup_IP($Domain,byref $DNSserver)
    local $data
    local $pref
    local $ip
    $command = Run(@comspec & " /C nslookup -querytype=A " & $Domain&" " &$DNSserver, @SystemDir, @SW_HIDE,  2) 
    
    While 1
    $data &= StdoutRead($command)
    If @error Then ExitLoop
    Wend

;split into lines
    $data = StringReplace($data, @LF,"");remove line feeds
    $data = StringSplit ($data, @CR)
    
    for $i = 1 to $data[0]
;if this line contains the domain then...
        if stringinstr ($data[$i], $Domain) then
            $ip = $data[$i+1]
    ;drop the word address (using the next line down from the one that contains the domain name)
            $ip = StringReplace ($ip ,"Address:","")
            $ip = StringReplace ($ip,"Addresses:","")
    ;drop the spaces
            $ip = StringReplace ($ip," ","")
            if StringInStr ($ip, ",") Then
                $ip = Stringleft($ip,stringinstr($ip,",")-1)
            endif
            return $ip
        endif
    next
EndFunc

func SMTP ($ip,$from,$to)
    $timer = TimerInit ()
    $FromDomain= StringTrimLeft($from,stringinstr($from,"@"))
    TCPStartup ( )
    
    $socket = TCPConnect( $IP, 25 )
    If $socket = -1 Then 
        ConsoleWrite ("Couldn't Connect"&@CRLF)
        $error = "Couldn't Connect"
        $ErrorText &= $error &@CRLF
        return "ERROR - " &$error
    endif

;1 recieve status of server...
    ConsoleWrite(".")
    $i = 0
    $recv = ""
    do
        $i += 1
        $recv &= TCPRecv( $socket, 2048 )
        sleep(10)
    until StringInStr ($recv,@CR) or StringInStr ($recv,@LF) or StringInStr ($recv,"250") or $i = 10000
    
    $recvCode = stringleft ($recv,3)
    if $recvcode < 200 or $recvcode > 299 Then
        ConsoleWrite ("Error - "&$recv&@CRLF)
        $error = $recv
        $ErrorText &= $recv &@CRLF
        TCPShutdown () 
        return "ERROR - " &$error
    endif
    if $recvcode = "" Then
        $error = "No Responce or Disconnected when attempting Connect"
        $ErrorText &= $error &@CRLF
        TCPShutdown () 
        return "ERROR - "&$error
    endif
    
;2 say helo
    ConsoleWrite(".")
    TCPSend($socket,"HELO "&$FromDomain&@CRLF)
    $i = 0
    $recv = ""
    do
        $i += 1
        $recv &= TCPRecv( $socket, 2048 )
        sleep(10)
    until StringInStr ($recv,@CR) or StringInStr ($recv,@LF) or StringInStr ($recv,"250") or $i = 10000
    
    $recvCode = stringleft ($recv,3)
    if $recvcode < 200 or $recvcode > 299 Then
        $error = $recv
        $ErrorText &= $recv &@CRLF
        TCPShutdown () 
        return "ERROR - " &$error
    endif
    if $recvcode = "" Then
        $error = "No Responce or Disconnected when attempting HELO"
        $ErrorText &= $error &@CRLF
        TCPShutdown () 
        return "ERROR - "&$error
    endif
    
;3 mail from
    ConsoleWrite(".")
    TCPSend($socket,"mail from: <"&$from&">"&@CRLF)
    $i = 0
    $recv = ""
    do
        $i += 1
        $recv &= TCPRecv( $socket, 2048 )
        sleep(10)
    until StringInStr ($recv,@CR) or StringInStr ($recv,@LF) or StringInStr ($recv,"250") or $i = 10000
    
    $recvCode = stringleft ($recv,3)
    if $recvcode < 200 or $recvcode > 299 Then
        ConsoleWrite ("Error - "&$recv&@CRLF)
        $error = $recv
        $ErrorText &= $recv &@CRLF
        TCPShutdown () 
        return "ERROR - " &$error
    endif
    if $recvcode = "" Then
        $error = "No Responce or Disconnected when attempting MAIL FROM"
        $ErrorText &= $error &@CRLF
        TCPShutdown () 
        return "ERROR - "&$error
    endif
    
;4 rcpt to
    ConsoleWrite(".")
    TCPSend($socket,"rcpt to: <"&$to&">"&@CRLF)
    $i = 0
    $recv = ""
    do
        $i += 1
        $recv &= TCPRecv( $socket, 2048 )
        sleep(10)
    until StringInStr ($recv,@CR) or StringInStr ($recv,@LF) or StringInStr ($recv,"250") or $i = 10000
    
    $recvCode = stringleft ($recv,3)
    if $recvcode < 200 or $recvcode > 299 Then
        $error = $recv
        $ErrorText &= $recv &@CRLF
        TCPShutdown () 
        return "ERROR - " &$error
    endif
    if $recvcode = "" Then
        $error = "No Responce or Disconnected when attempting RCPT TO"
        $ErrorText &= $error &@CRLF
        TCPShutdown () 
        return "ERROR - "&$error
    endif
    ConsoleWrite(".")
    TCPSend($socket,"QUIT"&@CRLF)
    TCPShutdown () 
    $timetaken = round (TimerDiff($timer ),0)
    $resulttext = "Passed ("&$timetaken&"ms)!"
    $ErrorText &=  $resulttext&@CRLF
    return $resulttext
EndFunc

could probally use some more testing ^_^

Edited by boomingranny

Share this post


Link to post
Share on other sites



HI Boomingranny,

i'm going to test it on monday..

Thnx

Sounds really useful

Emiel


Best regards,Emiel Wieldraaijer

Share this post


Link to post
Share on other sites

SMTP Server Audit, contains a part of your code.

http://www.autoitscript.com/forum/index.php?showtopic=119933&st=0&p=833298&hl=SMTP%20Server%20Audit&fromsearch=1&#entry833298

Hope you find this useful.

Regards

Deltarocked.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0