2012-09-26 19 views
7

El siguiente es mi código actual para conectar al servidor smtp de gmail en el puerto 587. Después de emitir el comando STARTTLS, ¿cómo terminaría de negociar la sesión TLS y comenzar a emitir comandos como AUTH LOGIN y MAIL FROM? He omitido mi nombre de usuario de gmail codificado en Base64 y lo he reemplazado por xxxxxxxx cerca de la parte inferior de mi código.¿Cómo iniciar TLS en una conexión activa en python?

Mi salida de este programa, ya que es, es:

220 mx.google.com ESMTP y10sm3296641yhd.6

250-mx.google.com a su servicio, [75.66.47.144 ]

250-TAMAÑO 35882577

250-8BITMIME

250-STARTTLS

250 ENHANCEDSTATUSCODES

220 2.0.0 Listo para empezar a TLS

from socket import * 
import ssl 
msg = "\r\n smtp.." 
endmsg = "\r\n.\r\n" 

# Mailserver hostname and port to be used. 
mailserver = ("smtp.gmail.com", 587) 


# Create a socket and create an active TCP connection with the mailserver 
clientSocket = socket(AF_INET, SOCK_STREAM); 
clientSocket.connect(mailserver) 

# Read server response 
recv = clientSocket.recv(1024) 
print recv 
if recv[:3] != '220': 
    print '220 reply not received from server.' 

# Send EHLO command and print server response. 
ehloCommand = 'EHLO smtp.google.com\r\n' 
clientSocket.send(ehloCommand) 

recv1 = clientSocket.recv(1024) 
print recv1 
if recv1[:3] != '250': 
    print '250 reply not received from server.' 

# Send STARTTLS command to server and print server response 
command = "STARTTLS\r\n" 
clientSocket.send(command) 

recv1 = clientSocket.recv(1024) 
print recv1 
if recv[:3] != '220': 
    print '220 reply not received from server.' 

# SEND AUTH LOGIN command and Base64 encoded username 
command = "AUTH LOGIN xxxxxxxxxxxxx\r\n" 
clientSocket.send(command) 

recv1 = clientSocket.recv(1024) 
print recv1 
+0

¿por qué no usar http://docs.python.org/library/smtplib.html? –

+1

@MK. Quiero hacer esto manualmente como ejercicio. – ripit

+0

Me lo imaginaba. Si no se usa el módulo ssl escrito en C, hay un módulo python ssl puro en alguna parte. quizás comience desde ssl.wrap_socket (self.sock, keyfile, certfile) – swang

Respuesta

10

Puede ssl envolver un conector conectado. Esto le dará la idea:

import ssl 
import base64 
from socket import * 


cc = socket(AF_INET, SOCK_STREAM) 
cc.connect(("smtp.gmail.com", 587)) 
# cc.read(..) 

cc.send('helo tester.com\r\n') 
cc.send('starttls\r\n') 
# cc.read(..) If the server responds ok to starttls 
#    tls negotiation needs to happen and all 
#    communication is then over the SSL socket 

scc = ssl.wrap_socket(cc, ssl_version=ssl.PROTOCOL_SSLv23) 
scc.send('auth login\r\n') 
# scc.read(..) 

scc.send(base64.b64encode('username')+'\r\n') 
scc.send(base64.b64encode('password')+'\r\n') 

# css.send(
# mail from: 
# rcpt to: 
# data 
# etc 

vistazo a la sección AUTH de esta página de información sobre el nombre de usuario/contraseña de codificación: http://www.samlogic.net/articles/smtp-commands-reference-auth.htm

Después de que el comando AUTH LOGIN ha sido enviada a la servidor, el servidor solicita un nombre de usuario y una contraseña al enviar texto codificado en BASE64 (preguntas) al cliente. "VXNlcm5hbWU6" es el texto codificado en BASE64 para la palabra "Nombre de usuario" y "UGFzc3dvcmQ6" es el texto codificado en BASE64 para la palabra "Contraseña" en el ejemplo anterior. El cliente envía nombre de usuario y contraseña también usando la codificación BASE64. "adlxdkej", en el ejemplo anterior , es un nombre de usuario codificado en BASE64 y "lkujsefxlj" es una contraseña codificada en BASE64.

+0

Quiero agregar que si no hace 'cc.read (...)' después de 'cc.send ('starttls \ r \ n') ', el contenedor SSL se confundirá con el mensaje" listo para iniciar TLS "del servidor y dará un error de" protocolo desconocido ". – wecsam

Cuestiones relacionadas