require 'net/smtp' # # The open SMTP-relay test. # # This object is instantiated if the parser sees a line such as: # ### ### mail.bytemark.co.uk must not run smtprelay otherwise 'smtp fail'. ### # # The specification of the port is optional and defaults to 25 # module Custodian module ProtocolTest class SMTPRelayTest < TestFactory # # Save away state from the configuration line. # def initialize( line ) @line = line @host = line.split( /\s+/)[0] # # Save the port # if ( line =~ /on\s+([0-9]+)/ ) @port = $1.dup else @port = 25 end # # Is this test inverted? # if ( line =~ /must\s+not\s+run\s+/ ) @inverted = true else @inverted = false end end # # Allow this test to be serialized. # def to_s @line end # # Read the hostname for usage in the SMTP-transaction. # def get_hostname hostname = "localhost.localdomain" if ( File.exists?( "/etc/hostname" ) ) File.readlines("/etc/hostname" ).each do |line| hostname = line if ( !line.nil? ) hostname.chomp! end end hostname end # # run the test for open relays of SMTP protocol - return true on success. # false on fail. # def run_test # for if we've run the test before @error = nil message = "Subject: SMTP Relay check\nThis is a test for OPEN SMTP relays." begin Net::SMTP.start(@host,@port, get_hostname() ) do |smtp| sent = smtp.send_message message, "noreply@bytemark.co.uk", "noreply@bytemark.co.uk" @status = sent.status.to_s if @status === "250" @error = "NOT OK: message sent on #{@host} with status #{@status}" else @error = "OK: message not sent on #{@host} with status #{@status}" end # # give the parser an appropriate response depending on the smtp code # and whether or not we're inverting the test. (eg, 'must not') # return @inverted if @status == "250" and @inverted return !@inverted if @status == "250" and !@inverted return @inverted if @status != "250" and !@inverted return !@inverted if @status != "250" and @inverted end # Net SMTP rescue Exception => ex # # for if we fail to send a message; this is a good thing # @error = "OK: Timed out or connection refused on #{@host} with status #{@status}" return !@inverted if @inverted return @inverted if !@inverted end end # # If the test failed here we will return a suitable error message. # def error @error end # register ourselves with the class-factory register_test_type "smtprelay" end end end