Enviar correo SMTP por telnet

Nada nuevo, esto está por todo internet explicado en muchas formas, tamaños y colores. Pero sucede que lo utilizo mucho y lo que siempre hago es entrar a mi blog y hacer una búsqueda por el término «telnet» y ahi me doy cuenta que tengo todas las formas de telnet para correo, menos la común y corriente. Eso motiva este artículo.

Como enviar un correo electrónico al puerto 25 por telnet:

# telnet localhost 25
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 mail.mydomain.com ESMTP

HELO yourdomain.com
250 mail.mydomain.com

MAIL FROM: you@server.com
250 2.1.0 Ok

RCPT TO: rpilas@mydomain.com
250 2.1.5 Ok

DATA
354 End data with <CR><LF>.<CR><LF>
From: "Some One" <you@server.com>
To: "Rodolfo Pilas" <rpilas@mydomain.com>
Subject: Testing
MIME-Version: 1.0
Content-Type: multipart/alternative;
        boundary="boundary-type-1234567892-alt"
--boundary-type-1234567890
--boundary-type-1234567892-alt
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable


Testing the text to see if it works!

--boundary-type-1234567892-alt
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable


<html>Does this actually work?</html>

--boundary-type-1234567892-alt--
--boundary-type-1234567890
Content-Transfer-Encoding: base64
Content-Type: text/plain;name="Here2.txt"
Content-Disposition: attachment;filename="Here2.txt"

KiAxMyBGRVRDSCAoQk9EWVtURVhUXSB7NjU5fQ0KLS1fZjZiM2I1ZWUtMjA3YS00ZDdiLTg0NTgtNDY5YmVlNDkxOGRhXw0KQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSJpc28tODg1OS0xIg0KQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogcXVvdGVkLXByaW50YWJsZQ0KDQoNCkp1c3Qgc2VlaW5nIHdoYXQgdGhpcyBhY3R1
YWxseSBjb250YWlucyEgCQkgCSAgIAkJICA9DQoNCi0tX2Y2YjNiNWVlLTIwN2EtNGQ3Yi04NDU4LTQ2OWJlZTQ5MThkYV8NCkNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PSJpc28tODg1OS0xIg0KQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogcXVvdGVkLXByaW50YWJsZQ0KDQo8aHRtbD4NCjxoZWFkPg0KPHN0eWxlPjwhLS0N
Ci5obW1lc3NhZ2UgUA0Kew0KbWFyZ2luOjBweD0zQg0KcGFkZGluZzowcHgNCn0NCmJvZHkuaG1tZXNzYWdlDQp7DQpmb250LXNpemU6IDEwcHQ9M0INCmZvbnQtZmFtaWx5OlRhaG9tYQ0KfQ0KLS0+PC9zdHlsZT48L2hlYWQ+DQo8Ym9keSBjbGFzcz0zRCdobW1lc3NhZ2UnPjxkaXYgZGlyPTNEJ2x0cic+DQpKdXN0IHNlZWluZyB3aGF0IHRo
aXMgYWN0dWFsbHkgY29udGFpbnMhIAkJIAkgICAJCSAgPC9kaXY+PC9ib2R5Pg0KPC9odG1sPj0NCg0KLS1fZjZiM2I1ZWUtMjA3YS00ZDdiLTg0NTgtNDY5YmVlNDkxOGRhXy0tDQopDQpmbHlubmNvbXB1dGVyIE9LIEZFVENIIGNvbXBsZXRlZA


--boundary-type-1234567890--


.
QUIT
250 2.0.0 Ok: queued as 1EDE71400DE

221 2.0.0 Bye
Connection closed by foreign host.

(esto lo he extraido de internet)

Enviar correo SMTP+SSL por telnet

No es precisamente telnet ya que telnet no implementa SSL, pero me parece un buen título para explicar a que se refiere este artículo.

Siguiendo con el artículo de «Correo POP3+SSL por telnet», ahora explico cómo hacer telnet (a Gmail) para enviar correo.

Obtener usuario/clave

El usuario y clave son pasados codificados en base64, por lo que antes de empezar conviene tener el string de validación, con alguno de estos dos comandos:

$ perl -MMIME::Base64 -e 'print encode_base64("\000pilasguru\@gmail.com\000password")'
AHBpbGFzZ3VydUBnbWFpbC5jb20AcGFzc3dvcmQ=
$ printf "\0pilasguru@gmail.com\0password" | openssl enc -a
AHBpbGFzZ3VydUBnbWFpbC5jb20AcGFzc3dvcmQ=

como se aprecia, ambos devuelven el mismo string.

Conexión

El comando openssl con la opción s_client será el encargado de establecer la conexión:

s_client This implements a generic SSL/TLS client which can establish a transparent connection to a remote server speaking SSL/TLS. It’s intended for testing purposes only and provides only rudimentary interface functionality but internally uses mostly all functionality of the OpenSSL ssl library.

de la siguiente forma:

$ openssl s_client -host smtp.gmail.com -port 587 -starttls smtp -crlf

CONNECTED(00000003)
depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=smtp.gmail.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority G2
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEdjCCA16gAwIBAgIIOuQOXm7sFPMwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
cm5ldCBBdXRob3JpdHkgRzIwHhcNMTMwOTEwMDc1NDQ3WhcNMTQwOTEwMDc1NDQ3
WjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UEAwwOc210
cC5nbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpMKDa
E9bW18yuVMulny5K5YLwf7ebEpINUVPZXvp7cO6vNjl+MCHjhbB2Rkg7QVJE8eNS
V0Hpq3vOuz+RQ2rPKfaeM3MFBZJ+tKscC39XmlVtmyBW5AVWy5dlO7718MQCN/L5
kpYSY6RinFrf5pIlf5XSGRCo3WYndguPP1A+X4gsDKjMaWhCP5KfczLHGTY+4T+d
31lDSah8CbFeMvKav0SFnyRYM36YAvAk2HH1/64Tolbx9tMAW6e6q8dU1U6W5u6+
Bt7WjW1iYwwfML+ZorKR9p+V070nDDN42ZE8HVZw+hOl9eMl48L/eX0eKbSGZ
....
J/3lYLI71meuut7O7G+BcFlXVphs5XSy65LkziTXikR+MRERjCKhv3AwP0oGB2+q
APMUqxtH6K6hmFE5ELtYjS4rKLbH08s8gy65y/EiaBaWKBlKG6s+r22uyxu2xmgo
LFf94N1gVJXuaZXlCgVwThCtbekh8wxjHtcVw2HCZfzQemEr7oshVOX2
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=smtp.gmail.com
issuer=/C=US/O=Google Inc/CN=Google Internet Authority G2
---
No client certificate CA names sent
---
SSL handshake has read 3474 bytes and written 470 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-SHA
    Session-ID: 65AAADD952AE24108001D17D0FF6C5403E5CE85040F61346A1C80C8E753E394F
    Session-ID-ctx:
    Master-Key: F8B3C5E3C2C0435ED53542A36CBB8ECA635255FBAEF73F1ADDB7BC512657E9C9A9B7E7EB567227856648A4D54C63CCA7
    Key-Arg   : None
    Start Time: 1400863594
    Timeout   : 300 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
---
250 CHUNKING

A partir de aquí podemos establecer el diálogo SMTP con el servidor de gmail enviando el comando ehlo:

ehlo
250-mx.google.com at your service, [64.90.52.109]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH XOAUTH2 PLAIN-CLIENTTOKEN
250-ENHANCEDSTATUSCODES
250-PIPELINING
250 CHUNKING

Luego validando nuestro usuario con el string que otuvimos previamente:

AUTH PLAIN AHBpbGFzZ3VydUBnbWFpbC5jb20AcGFzc3dvcmQ=
235 2.7.0 Accepted

A partir de aqui, se pueden enviar los comandos SMTP estandar: MAIL FROM, MAIL TO, DATA y punto para terminar el mensaje.

Correo POP3+SSL por telnet

Siguiendo con el reciente artículo sobre Correo POP3 por telnet, debo tener en cuenta que mis servidores suelen tener el correo con SSL, para lograr la capa de validación y cifrado para la trasmisión de los datos, por este motivo, el telnet no sirve para hacer conexiones.

Entonces cuando el servidor POP3 tiene SSL (sPOP3) la solución es usar openssl, asi:

$ openssl s_client -connect servidor.correo.com:995
CONNECTED(00000005)
-> Aqui se muestra la validación y
-> el contenido del certificado digital
-> … en varios renglones
->
+OK POP3 Ready

A partir de aquí, funcionan perfectamente todos los comandos de POP3, indicados en el artículo anterior, exactamente como si estuvieramos por telnet normal.

Correo POP3 por telnet

Esto no es nada nuevo ni «rocket science«, solo es un apunte personal, ya que esto lo requiero de vez en cuando y al final termino buscando entre documentos y documentos hasta que veo lo que quiero.

Es simplemente cómo hacer telnet al servidor de correo (POP3) y ver los mensajes.

Iniciar sesión en el servidor

$ telnet servidor.correo.com 110

Cuando conecte con el servidor, aparece como lo siguiente:

+OK POP3 Ready

El protocolo POP3 es muy sencillo. Cuando hacemos algo bien el servidor nos contesta con «+OK» y cuando lo hacemos mal nos devuelve un «-ERR». En ambos casos se añadirá un texto descriptivo.

Ahora el servidor espera nuestra validación:

USER usuario@correo.com

El servidor le responderá con el mensaje de OK:

+OK USER

Significa que ha aceptado el nombre de usuario y que esta esperando por su contraseña. Escriba:

PASS contraseña

empleando la contraseña de su buzón de correo. Si todo ha ido bien el servidor nos responde con lo siguiente

+OK Logged in.

Comandos al servidor

Una vez conectados disponemos de varios comandos que podemos utilizar:

STAT (status) solicita el estado de tu buzón de correos. El servidor responderá informando de cuantos mensajes hay a la espera, en el siguiente formato: +OK mm bb, donde mm es el numero de mensajes, y bb el numero de bytes del total.

LIST te lista todos los mensajes. El primer número es el identificador del mensaje (que se requiere para otros comandos y el segundo número es el tamaño.

LIST
+OK 2 messages (320 octets)
1 120
2 200
.

LIST 2
+OK 2 200

LIST 3
-ERR no such message, only 2 messages in maildrop

TOP nn nl para ver las cabeceras y primeras lineas del mensaje (nn sería el numero del mensaje que quieras ver, nl el numero de lineas de la cabecera, p ej: TOP 1 ALL)

RETR # para ver un mensaje, debe especificarse su numero identificados del mensaje.

+OK XXXX octets follow.
Cabecera del mensaje
Cuerpo del mensaje
.

Donde XXXX es el tamaño del mensaje en bytes. Seguido de esta linea se mostrará la cabecera del mensaje y el cuerpo del mismo. Si el mensaje está codificado en HTML o tiene datos adjuntos es más que probable que entienda poco del mismo.

DELE # borra el mensaje elegido. El borrado no es al enviar el comando, sino al terminar la sesión (se debe desconectar con QUIT o los mensajes no serán borrados)

RSET recupera los mensajes marcados para borrado

NOOP (No Operation) instruye al servidor para que no ejecute ninguna acción, salvo responder con un mensaje de confirmación (+OK).

UIDL (Unique Identifier List) sirve para asignar un identificador unico a todos los mensajes o a uno especifico.

APOP (Authenticate Post Office Protocol) Este comando puede ser usado como sustituto del binomio USER – PASS para identificar y validar un usuario. Su utilidad es evitar que el password del usuario viaje por la red de forma no encriptada. La sintaxis es: APOP (nombre) (codigo).

Desconectar y cerrar sesión

Para desconectar correctamente del servidor escriba:

QUIT

El servidor nos responde con:

+OK Logging out.

Y se cierra el telnet: Connection closed by foreign host.

Fuentes: