Skip to content

Instantly share code, notes, and snippets.

@arthurafarias
Created June 7, 2017 04:58
Show Gist options
  • Save arthurafarias/b4b5feda467530514a4c6500c4800968 to your computer and use it in GitHub Desktop.
Save arthurafarias/b4b5feda467530514a4c6500c4800968 to your computer and use it in GitHub Desktop.
Atividade de Redes de Computadores - Questão 02
#!/usr/bin/env python
"""Google SMTP Client.
Usage:
gsmtpc (-l=<email>|--login=<email>)
gsmtpc (-l=<email>|--login=<email>) [-p=<plain> | --password=<plain>] [-r=<email> | --recipient=<email>] [-s=<text> | --subject=<text>] [-m=<text> | --message=<text>]
gsmtpc (-h | --help)
Options:
-h --help Show this screen.
-l --login=<email> User's account used to login in smtp server.
-p --password=<plain> User's account plain password to login in gmail smtp server.
-r --recipient=<email> Recipient e-mail account.
-s --subject=<text> Subject of the message.
-m --message=<text> Message.
"""
from docopt import docopt
from types import *
import base64
import socket
import ssl
import re
import sys
DEBUGGING = True
from getpass import getpass
import readline
def rlinput(prompt, prefill=''):
try:
return raw_input(prompt)
finally:
readline.set_startup_hook()
# Classe que, por interface em linha de comando oferece toda a autenticação e
# arcabouço facilitado para envio de e-mails pelo gmail.
class GoogleSMTPClient(object):
# Cada propriedade, quando chamada, mas não definida é interativamente
# solicitada ao usuário.
@property
def args(self):
return self._args
@args.setter
def args(self, value):
self._args = value
self.user = self._args.get("--login")
self.password = self._args.get("--password")
self.recipient = self._args.get("--recipient")
self.subject = self._args.get("--subject")
self.message = self._args.get("--message")
@property
def user(self):
try:
if not self._user:
self._user = raw_input("type your username (ex. login@gmail.com): ")
return self._user
else:
return self._user
except AttributeError:
self._user = None
return self.user
@user.setter
def user(self, value):
self._user = value
@property
def password(self):
try:
if not self._password:
self._password = getpass("Type your password: ")
return self._password
else:
return self._password
except AttributeError:
self._password = None
return self.password
@password.setter
def password(self, value):
self._password = value
@property
def recipient(self):
try:
if not self._recipient:
self._recipient = raw_input("type the recipient (ex. example@outlook.com): ")
return self._recipient
else:
return self._recipient
except AttributeError:
self._recipient = None
return self.recipient
@recipient.setter
def recipient(self, value):
self._recipient = value
@property
def subject(self):
try:
if not self._subject:
self._subject = raw_input("type the subject of the message: ")
return self._subject
else:
return self._subject
except AttributeError:
self._subject = None
return self.subject
@subject.setter
def subject(self, value):
self._subject = value
@property
def message(self):
try:
if not self._message:
print("type the message (exit: cntrl + c): ")
self._message = ""
while True:
try:
input_str = raw_input("> ")
self._message += input_str + "\r\n"
except KeyboardInterrupt:
print ("Is message correct?")
print ("\n===text===")
print (self.message)
print ("===text===\n")
while True:
confirm = raw_input("Discard? (y/n):")
if ( (confirm == "Y") | (confirm == "y") ):
self.message = ""
break
elif( (confirm == "N") | (confirm == "n") ):
return self._message
else:
print("Invalid Input")
else:
return self._message
except AttributeError:
self._message = None
return self.message
@message.setter
def message(self, value):
self._message = value
@property
def authcode(self):
return base64.b64encode("\000" + self.user + "\000" + self.password )
def gsmtp_create_context(self):
# Inicia um contexto SSL
self.ssl_context = ssl.create_default_context()
# Cria-se uma conexxão SSL
self.ssl_connection = self.ssl_context.wrap_socket(socket.socket( socket.AF_INET, socket.SOCK_STREAM ), server_hostname="smtp.gmail.com")
pass
def gsmtp_send_command(self, command):
if DEBUGGING:
print command
self.ssl_connection.sendall(command + "\r\n")
def gsmtp_connect(self):
# Tenta-se Criar um Contexto SMTP com o GOOGLE
self.gsmtp_create_context()
# Tenta-se conectar ao servidor SMTP do gmail através da conexão recém
# criada.
self.ssl_connection.connect(("smtp.gmail.com", 465))
self.gsmtp_get_response()
# Inicia-se a seção de funcionamento do servidor
self.gsmtp_send_command("HELO .")
self.gsmtp_get_response()
# Parser em expressão regular das respostas às requisições SMTP
def gsmtp_get_response(self):
buff = self.ssl_connection.recv(8192)
buff_parsed = re.search("([0-9]{0,1})[0-9]{0,1}[0-9]{0,1}\-{0,1}[0-9]{0,1}\.{0,1}[0-9]{0,1}\.{0,1}[0-9]{0,1} (.*)\r\n(([0-9]{0,1})[0-9]{0,1}[0-9]{0,1} {0,1}[0-9]{0,1}\.{0,1}[0-9]{0,1}\.{0,1}[0-9]{0,1} (.*)\r\n){0,1}", buff)
response = ( buff_parsed.group(1), buff_parsed.group(2) + str(buff_parsed.group(5)) )
if DEBUGGING:
print buff
print response
return response
def gsmtp_auth(self):
while True:
# Tenta-se enviar o comando de autenticação ao servidor SMTP
self.gsmtp_send_command("AUTH PLAIN "+ self.authcode)
# Recebe-se a resposta
response = self.gsmtp_get_response()
# Se o código da resposta é diferente de 5, encerra-se a
# autenticação com sucesso.
if response[0] != '5':
break
# Se o código da resposta é 5, encerra-se a autenticação com erro
else:
raise Exception("Could not authenticate at GMAIL.")
self.user = None
self.password = None
def gsmtp_send_message(self):
# Configuração da Mensagem de E-Mail
self.gsmtp_send_command("MAIL FROM: <"+ self.user +">")
self.gsmtp_get_response()
self.gsmtp_send_command("rcpt to: <"+ self.recipient +">")
self.gsmtp_get_response()
self.gsmtp_send_command("DATA")
self.gsmtp_get_response()
self.gsmtp_send_command("From: "+ self.user +"")
self.gsmtp_send_command("To: "+ self.recipient +"")
self.gsmtp_send_command("Subject: "+ self.subject +"")
self.gsmtp_send_command(""+ self.message +"")
# Sinal de término da Mensagem de E-Mail
self.gsmtp_send_command(".")
self.gsmtp_get_response()
def __init__(self):
try:
# Document Options
self.args = docopt(__doc__, version="Google's SMTP Client v0.2")
# Chama o método de inicialização da conexão
self.gsmtp_connect()
# Tenta realizar a autenticação. Note que cada parâmetro não
# definido e necessário será definido interativamente quando
# invocado o getter do atributo referente ao parâmetro.
self.gsmtp_auth()
# Tenta enviar a mensagem
self.gsmtp_send_message()
except KeyboardInterrupt, SystemExit:
# Se há interrupção pelo teclado ou o sistema operacional tenta
# enviar algum sinal de interrupção ao processo, invoca-se a saída
# do script.
sys.exit()
except Exception as e:
# Qualquer outra exceção que ocorra, ela será impressa na saída
# e o processo será encerrado com sucesso
print "Error: " + e.message
# Inicializa a classe quando solicitado o nome padrão "__name__" é definido como
# '__main__'.
if __name__ == '__main__':
GoogleSMTPClient()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment