# $Id: smtp.rb,v 1.2 2006/10/05 01:36:52 koheik Exp $ require 'socket' $:.unshift(File.dirname(__FILE__) + '/../lib') require 'net/ntlm' $user = nil $passwd = nil $host = "localhost" $port = 25 $debug = true def readline(f) (l = f.gets).chomp! puts "srv> " + l if $debug l end def writeline(f, str) puts "cli> " + str if $debug f.print str + "\r\n" end def main s = TCPSocket.new($host, $port) # greetings readline s writeline s, "EHLO #{$host}" while(line = readline(s)) login = true if /^250-AUTH=LOGIN/ =~ line ntlm = true if /^250-AUTH.+NTLM.*/ =~ line break if /^250 OK/ =~ line end unless ntlm and login raise RuntimeError, "it looks like the server doesn't support NTLM Login" end # send Type1 Message t1 = Net::NTLM::Message::Type1.new() writeline s, "AUTH NTLM " + t1.encode64 # receive Type2 Message, i hope line = readline s unless /334 (.+)/ =~ line raise RuntimeError, "i don't recognize this: #{line}" end t2 = Net::NTLM::Message.decode64($1) unless $user and $passwd target = t2.target_name target = Net::NTLM::decode_utf16le(target) if t2.has_flag?(:UNICODE) puts "Target: #{target}" print "User name: " ($user = $stdin.readline).chomp! print "Password: " ($passwd = $stdin.readline).chomp! end # send Type3 Message t3 = t2.response({:user => $user, :password => $passwd}, {:ntlmv2 => true}) writeline s, t3.encode64 # and result is... line = readline s unless /^235(.+)Authentication successful./i =~ line raise RuntimeError, "sorry, authentication failed." end # do real job here like... # from = $user # to = "billg" # writeline s, "MAIL FROM: #{from}" # readline s # writeline s, "RCPT TO: #{to}" # readline s # writeline s, "DATA" # readline s # writeline s, "From: #{from}" # writeline s, "To: #{to}" # writeline s, "blab blab blab..." # writeline s, "#{from}" # writeline s, "." # readline s # say bye writeline s, "QUIT" s.close end main