Wednesday 15 May 2019

sockets - How to start TLS on an active connection in python?



The following is my current code for connecting to gmail's smtp server on port 587. After issuing the STARTTLS command how would I finish negotiating the TLS session and begin issuing commands such as AUTH LOGIN and MAIL FROM? I have ommitted my Base64 encoded gmail username and replaced it with xxxxxxxx near the bottom of my code.



My output from this program as it is, is:




220 mx.google.com ESMTP y10sm3296641yhd.6



250-mx.google.com at your service, [75.66.47.144]




250-SIZE 35882577



250-8BITMIME



250-STARTTLS



250 ENHANCEDSTATUSCODES



220 2.0.0 Ready to start 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

Answer



You can ssl wrap a connected socket. This will give you the 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


look at the AUTH LOGIN section of this page for info about the username/password encoding: http://www.samlogic.net/articles/smtp-commands-reference-auth.htm





After that the AUTH LOGIN command has been sent to the server, the
server asks for username and password by sending BASE64 encoded text
(questions) to the client. “VXNlcm5hbWU6” is the BASE64 encoded text
for the word "Username" and “UGFzc3dvcmQ6” is the BASE64 encoded text
for the word "Password" in the example above. The client sends
username and password also using BASE64 encoding. "adlxdkej", in the
example above, is a BASE64 encoded username and "lkujsefxlj" is a
BASE64 encoded password.




No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...