2010-11-30 5 views
5

he enviado con éxito de correo electrónico a un servidor remoto a través del puerto de su puerto 25 (no vigilado) con este script:Rubí Mail, la forma de lograr correo electrónico SSL

require 'rubygems' 
require 'mail' 

options = { :address    => "mail.domain.com", 
      :port     => 25, 
      :domain    => 'mail.domain.com', 
      :user_name   => '[email protected]', 
      :password    => 'topsecret', 
      :authentication  => 'login', 
      :enable_starttls_auto => true } 
Mail.defaults do 
    delivery_method :smtp, options 
end 

mail = Mail.new do 
     from '[email protected]' 
     to '[email protected]' 
    subject 'This is a test email' 
     body File.read('body.txt') 
end 

puts mail.to_s 
mail.deliver! 

Lo que hay que hacer ahora es utilizar su puerto SSL 466. Cuando lo intento, me da la salida normal que detalla el mensaje, entonces se hace una pausa durante unos 2 minutos y tose esto:

/usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/timeout.rb:60:in `rbuf_fill': execution expired (Timeout::Error) 
     from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/protocol.rb:134:in `rbuf_fill' 
     from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/protocol.rb:116:in `readuntil' 
     from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/protocol.rb:126:in `readline' 
     from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/smtp.rb:911:in `recv_response' 
     from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/smtp.rb:554:in `do_start' 
     from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/smtp.rb:921:in `critical' 
     from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/smtp.rb:554:in `do_start' 
     from /usr/local/rvm/rubies/ruby-1.8.7-p249/lib/ruby/1.8/net/smtp.rb:525:in `start' 
     from /usr/local/rvm/gems/ruby-1.8.7-p249/gems/mail-2.2.10/lib/mail/network/delivery_methods/smtp.rb:127:in `deliver!' 
     from /usr/local/rvm/gems/ruby-1.8.7-p249/gems/mail-2.2.10/lib/mail/message.rb:243:in `deliver!' 
     from testmail.rb:30 

Creo que esto se debe a que no puede ni siquiera comenzar el proceso de autenticación SSL . ¿Cómo lo hago?

Respuesta

4

Hmm leyendo la red/delivery_methods/smtp.rb, no parece que sea compatible con Direct SSL. TLS no es lo mismo, ya que la conexión comienza con texto plano y luego cambia a SSL en el comando starttls. ¿Puedes usar starttls en el puerto 587?

tirando de mi comentario.

ver

How to send mail with ruby over smtp with ssl (not with rails, no TLS for gmail)

lo que sugiere que puede neto parche mono :: SMTP para hacerlo ..

Ok conocer un poco el tema y puede parchear su alrededor, pero hasta ahora esta solución es asqueroso .. pero funciona :)

#!/usr/bin/env ruby 

require 'rubygems' 
require "openssl" 
require "net/smtp" 
require "mail" 

Net::SMTP.class_eval do 

    def self.start(address, port = nil, 
        helo = 'localhost.localdomain', 
        user = nil, secret = nil, authtype = nil, use_tls = false, 
        use_ssl = true, &block) # :yield: smtp 
    new(address, port).start(helo, user, secret, authtype, use_tls, use_ssl, &block) 
    end 

    def start(helo = 'localhost.localdomain', 
      user = nil, secret = nil, authtype = nil, use_tls = false, use_ssl = true) # :yield: smtp 
    start_method = use_tls ? :do_tls_start : use_ssl ? :do_ssl_start : :do_start 
    if block_given? 
     begin 
     send start_method, helo, user, secret, authtype 
     return yield(self) 
     ensure 
     do_finish 
     end 
    else 
     send start_method, helo, user, secret, authtype 
     return self 
    end 
    end 

    private 

    def do_tls_start(helodomain, user, secret, authtype) 
    raise IOError, 'SMTP session already started' if @started 

    check_auth_args user, secret 

    sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) } 
    @socket = Net::InternetMessageIO.new(sock) 
    @socket.read_timeout = 60 #@read_timeout 
    @socket.debug_output = STDERR #@debug_output 

    check_response(critical { recv_response() }) 
    do_helo(helodomain) 

    raise 'openssl library not installed' unless defined?(OpenSSL) 
    starttls 
    ssl = OpenSSL::SSL::SSLSocket.new(sock) 
    ssl.sync_close = true 
    ssl.connect 
    @socket = Net::InternetMessageIO.new(ssl) 
    @socket.read_timeout = 60 #@read_timeout 
    @socket.debug_output = STDERR #@debug_output 
    do_helo(helodomain) 

    authenticate user, secret, authtype if user 
    @started = true 
    ensure 
    unless @started 
     # authentication failed, cancel connection. 
     @socket.close if not @started and @socket and not @socket.closed? 
     @socket = nil 
    end 
    end 

    def do_ssl_start(helodomain, user, secret, authtype) 
    raise IOError, 'SMTP session already started' if @started 

    check_auth_args user, secret 

    sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) } 
    raise 'openssl library not installed' unless defined?(OpenSSL) 
    ssl = OpenSSL::SSL::SSLSocket.new(sock) 
    ssl.sync_close = true 
    ssl.connect 
    @socket = Net::InternetMessageIO.new(ssl) 
    @socket.read_timeout = 60 #@read_timeout 
    @socket.debug_output = STDERR #@debug_output 

    check_response(critical { recv_response() }) 
    do_helo(helodomain) 

    do_helo(helodomain) 

    authenticate user, secret, authtype if user 
    @started = true 
    ensure 
    unless @started 
     # authentication failed, cancel connection. 
     @socket.close if not @started and @socket and not @socket.closed? 
     @socket = nil 
    end 
    end 

    def do_helo(helodomain) 
    begin 
     if @esmtp 
     ehlo helodomain 
     else 
     helo helodomain 
     end 
    rescue Net::ProtocolError 
     if @esmtp 
     @esmtp = false 
     @error_occured = false 
     retry 
     end 
     raise 
    end 
    end 

    def starttls 
    getok('STARTTLS') 
    end 

    def quit 
    begin 
     getok('QUIT') 
    rescue EOFError, OpenSSL::SSL::SSLError 
    end 
    end 
end 

options = { 
    :address    => "mail.domain.net", 
    :port     => 466, 
    :domain    => 'mail.domain.net', 
    :user_name   => '[email protected]', 
    :password    => 'Secret!', 
    :authentication  => 'login', 
    :use_ssl => true } 

Mail.defaults do 
    delivery_method :smtp, options 
end 

mail = Mail.new do 
    from '[email protected]' 
    to '[email protected]' 
    subject 'This is a test email' 
    body File.read('body.txt') 
end 

puts mail.to_s 
mail.deliver! 

por alguna razón el use_ssl en el parche orig mono no lo hace, y la pareja que con VE RSION está indefinido en Net :: SMTP. Así que lo cambié y forcé use_ssl para ser verdadero, y pude enviar un correo electrónico ...

+0

No tenemos ningún control sobre la asignación de puerto 466 y el puerto 587 no está disponible –

+0

Hmm no parece que Net :: SMTP sea compatible con SSL de fábrica, el correo utilizado. Echa un vistazo aquí. http://stackoverflow.com/questions/708858/how-to-send-mail-with-ruby-over-smtp-with-ssl-not-with-rails-no-tls-for-gmail parece que puedes mono parche Net :: SMTP para trabajar ... – Doon

+0

Lo intenté, y produce exactamente el mismo resultado desafortunadamente. –

0

¿Quería usar port 465? Ese es el puerto de respaldo estándar, no el 466. Probablemente esté agotando el tiempo de conexión al puerto incorrecto.

+0

No, el puerto fue asignado por nuestro proveedor de servicios. Alguien más también sugirió eso, así que también lo intentamos, pero fue en vano. –

+0

¿Qué sucede cuando "telnet mail.myserver.com 466"? ¿Tienes una conexión? –

+0

no. Intentó 465 también. Solo dice "Conectando a mail.safetysend.com ..." –

Cuestiones relacionadas