2012-10-12 15 views
12

Próbuję połączyć się z serwerem poczty Gmail SMTP i wykonywać zadania zgodnie z podanym przeze mnie kodem szkieletu. Dozwolone jest używanie tylko socket s (a więc nie smtplib). Muszę: wysłać polecenie HELO, MAIL FROM, RCPT TO i DATA.Łączenie się z SMTP (SSL lub TLS) przy użyciu Pythona

Jest wiele przypadków podobnych problemów opublikowanych, ale nie otrzymały one prawidłowej odpowiedzi. Na przykład: Implementing Transport Layer Security in Python - Simple Mail Client

Program jest wymagany do połączenia z smtp.gmail.com przez port 587. Wziąłem dwa różne podejścia:

  1. Korzystanie STARTTLS:

    mailserver = 'smtp.gmail.com' 
    clientSocket = socket(AF_INET, SOCK_STREAM) 
    clientSocket.connect((mailserver, 587)) 
    recv = clientSocket.recv(1024) 
    print recv 
    if recv[:3] != '220': 
        print '220 reply not received from server.' 
    
    #Send HELO command and print server response 
    heloCommand = 'HELO Alice\r\n' 
    clientSocket.send(heloCommand) 
    recv1 = clientSocket.recv(1024) 
    print recv1 
    if recv1[:3] != '250': 
        print '250 reply not received from server.' 
    
    #Send MAIL FROM command and print server response. 
    command = "STARTTLS\r\n" 
    clientSocket.send(command) 
    recvdiscard = clientSocket.recv(1024) 
    print recvdiscard 
    clientSocket.send("MAIL From: email\r\n") 
    recv2 = clientSocket.recv(1024) 
    print recv2 
    if recv2[:3] != '250': 
        print '250 reply not received from server.' 
    
  2. Używanie SSL:

    clientSocketSSL = ssl.wrap_socket(clientSocket) 
    

    Następnie clientSocketSSL zastępuje wszystkie instancje clientSocket. Linie STARTTLS również są usuwane, a do góry dodano import ssl.

Podczas korzystania z pierwszej metody, polecenie MAIL FROM: nie zwraca niczego. Dostaję następujący wynik:

250 mx.google.com at your service 

220 2.0.0 Ready to start TLS 

250 reply not received from server. 

Kiedy przy użyciu protokołu SSL, Dostaję taki sam jak połączonego postu:

ssl.SSLError: [Errno 1] _ssl.c:504: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol 

Am I brakuje czegoś tutaj? Domyślam się, że moim najlepszym rozwiązaniem jest używanie TLS, ale nie mam pojęcia, jak to zrobić ... czy jest coś złego w moim poleceniu MAIL FROM?

+0

Czy próbowałeś tego? [wysyłając e-mail z pytona] [1] [1]: http: // stackoverflow.com/a/399240/986760 – fayyazkl

+0

@fayyazkl jak wspomniałem mogę używać tylko gniazd, nie smtplib – user1287523

+0

Zacznij od ustalenia wcięcia w kodzie. –

Odpowiedz

9

Podczas korzystania z protokołu SSL, należy podłączyć do portu 465 zamiast portu 587. W przypadku korzystania STARTTLS, trzeba jeszcze używać ssl.wrap_socket, po prostu zrobić to później - konkretnie, po otrzymaniu odpowiedzi 220 dowodzić STARTTLS. Po wykonaniu STARTTLS znowu powinieneś zrobić HELO, ponieważ serwer powinien zapomnieć o wszystkim, co wydarzyło się przed STARTTLS.

W obu przypadkach serwery na portach smtp.google.com 465 i 587 nadal nie zwrócą odpowiedzi 250 na polecenie MAIL, ponieważ wymagają uwierzytelnienia przed wysłaniem wiadomości e-mail. Zamiast tego otrzymasz odpowiedź 530. Musisz użyć polecenia AUTH z danymi uwierzytelniającymi gmail.com do uwierzytelnienia, aby móc z powodzeniem używać tych serwerów na MAIL.

Jeśli nie chcesz uwierzytelniać i w zależności od szczegółów, co musisz zrobić, możesz spróbować użyć portu 25 serwera znalezionego w rekordzie MX gmail.com. W tej chwili serwer to gmail-smtp-in.l.google.com i obsługuje STARTTLS.