whisperback (1.8.3)
[whisperback.git] / whisperBack / mail.py
blob7524de345aef4d469dcdb1128daa1119066fa244
1 #!/usr/bin/env python3
2 # -*- coding: UTF-8 -*-
4 ########################################################################
5 # WhisperBack - Send feedback in an encrypted mail
6 # Copyright (C) 2009-2018 Tails developers <tails@boum.org>
8 # This file is part of WhisperBack
10 # WhisperBack is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 3 of the License, or (at
13 # your option) any later version.
15 # This program is distributed in the hope that it will be useful, but
16 # WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 # General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 ########################################################################
24 """WhisperBack mailing library
26 """
28 import logging
29 import smtplib
30 import socket
31 import socks
33 LOG = logging.getLogger(__name__)
36 #pylint: disable=R0913
37 def send_message (from_address, to_address, message, host="localhost",
38 port=25, socks_host="127.0.0.1", socks_port=9050):
39 """Sends a mail
41 Send the message via our own SMTP server, but don't include the
42 envelope header. This is based on an example from doc.python.org
44 @param from_address The sender's address
45 @param to_address The recipient address
46 @param message The content of the mail
47 @param host The host of the smtp server to connect to
48 @param port The port of the smtp server to connect to
49 @param socks_host The host of the SOCKS proxy to connect through
50 @param socks_port The port of the SOCKS proxy to connect through
51 """
53 LOG.debug("Sending mail")
54 # Monkeypatching the entire connection through the SOCKS proxy
55 socks.set_default_proxy(socks.SOCKS5, socks_host, socks_port)
56 socket.socket = socks.socksocket
58 try:
59 # We set a long timeout because Tor is slow
60 smtp = smtplib.SMTP(timeout=120, host=host, port=port)
61 except ValueError:
62 # socks assumes the host resolves to AF_INET and triggers a ValueError
63 # if it's not the case. If a .onion address is given, it resolves to an
64 # AF_INET address and to an AF_INET6 address. If the 1st doesn't connect,
65 # the 2nd is tried, which make socks trigger the ValueError.
66 # This issue is fixed upstream in socks, in which this situation raises
67 # a socket.error (https://github.com/Anorov/PySocks/commit/4081b79)
68 # XXX: this workaround should be removed when a version of socks containing
69 # this commit reaches Tails.
70 raise socket.error("PySocks doesn't support IPv6")
72 smtp.sendmail(from_address, [to_address], message)
73 smtp.quit()