Commit Graph

70 Commits

Author SHA1 Message Date
Gregory Szorc
35166670e2 mail: unsupport smtp.verifycert (BC)
smtp.verifycert was accidentally broken by 799db3fe9866. And,
I believe the "loose" value has been broken for longer than that.
The current code refuses to talk to a remote server unless the
CA is trusted or the fingerprint is validated. In other words,
we lost the ability for smtp.verifycert to lower/disable security.

There are special considerations for smtp.verifycert in
sslutil.validatesocket() (the "strict" argument). This violates
the direction sslutil is evolving towards, which has all security
options determined at wrapsocket() time and a unified code path and
configs for determining security options.

Since smtp.verifycert is broken and since we'll soon have new
security defaults and new mechanisms for controlling host security,
this patch formally deprecates smtp.verifycert. With this patch,
the socket security code in mail.py now effectively mirrors code
in url.py and other places we're doing socket security.

For the record, removing smtp.verifycert because it was accidentally
broken is a poor excuse to remove it. However, I would have done this
anyway because smtp.verifycert is a one-off likely used by few people
(users of the patchbomb extension) and I don't think the existence
of this seldom-used one-off in security code can be justified,
especially when you consider that better mechanisms are right around
the corner.
2016-06-04 11:13:28 -07:00
Gregory Szorc
5c94b9af48 mail: remove use of sslkwargs 2016-05-25 19:56:20 -07:00
Gregory Szorc
548b4e9e2c sslutil: remove ui from sslkwargs (API)
Arguments to sslutil.wrapsocket() are partially determined by
calling sslutil.sslkwargs(). This function receives a ui and
a hostname and determines what settings, if any, need to be
applied when the socket is wrapped.

Both the ui and hostname are passed into wrapsocket(). The
other arguments to wrapsocket() provided by sslkwargs() (ca_certs
and cert_reqs) are not looked at or modified anywhere outside
of sslutil.py. So, sslkwargs() doesn't need to exist as a
separate public API called before wrapsocket().

This commit starts the process of removing external consumers of
sslkwargs() by removing the "ui" key/argument from its return.
All callers now pass the ui argument explicitly.
2016-05-25 19:43:22 -07:00
Gregory Szorc
6fd76860b1 sslutil: convert socket validation from a class to a function (API)
Now that the socket validator doesn't have any instance state,
we can make it a generic function.

The "validator" class has been converted into the "validatesocket"
function and all consumers have been updated.
2016-05-15 11:38:38 -07:00
Pulkit Goyal
e244ccece0 py3: use setattr() to assign new class attribute
The old method produces error 'object does not supports item assignment'.
So setattr() is used to assign a new class attribute via __dict__ .
2016-05-17 05:32:36 +05:30
timeless
099d7d30ce mail: retain hostname for sslutil.wrapsocket (issue5203)
SMTPS + STARTTLS need to provide serverhostname,
and we can't store it in sslkwargs because that breaks
something involving the https protocol.
2016-04-15 17:43:47 +00:00
Julien Cristau
1c82b3fc6d patch: when importing from email, RFC2047-decode From/Subject headers
Reported at https://bugs.debian.org/737498
2016-03-03 18:34:19 +01:00
Gregory Szorc
ade216b11a mail: use print function
We no longer use the print statement in mercurial.* \o/
2016-01-02 11:47:07 -08:00
timeless
d454b6c02e mail: drop python 2.5 self.sock.read workaround 2015-10-15 17:24:42 -04:00
timeless@mozdev.org
716b455ed5 l10n: use %d instead of %s for numbers 2015-10-14 22:29:03 -04:00
timeless@mozdev.org
88f3ab0903 mail: drop python 2.5 support 2015-10-14 22:21:05 -04:00
Pierre-Yves David
30913031d4 error: get Abort from 'error' instead of 'util'
The home of 'Abort' is 'error' not 'util' however, a lot of code seems to be
confused about that and gives all the credit to 'util' instead of the
hardworking 'error'. In a spirit of equity, we break the cycle of injustice and
give back to 'error' the respect it deserves. And screw that 'util' poser.

For great justice.
2015-10-08 12:55:45 -07:00
timeless@mozdev.org
52eae47139 spelling: behaviour -> behavior 2015-08-28 10:53:55 -04:00
Gregory Szorc
47f7f541e8 mail: use absolute_import 2015-08-08 19:32:19 -07:00
Matt Mackall
c513e9d5f5 email: fix config default value inconsistency 2015-06-25 17:52:20 -05:00
Gregory Szorc
5380dea2a7 global: mass rewrite to use modern exception syntax
Python 2.6 introduced the "except type as instance" syntax, replacing
the "except type, instance" syntax that came before. Python 3 dropped
support for the latter syntax. Since we no longer support Python 2.4 or
2.5, we have no need to continue supporting the "except type, instance".

This patch mass rewrites the exception syntax to be Python 2.6+ and
Python 3 compatible.

This patch was produced by running `2to3 -f except -w -n .`.
2015-06-23 22:20:08 -07:00
Yuya Nishihara
0c290c5ab8 mail: pass ui to sslutil.wrapsocket() even if verifycert is off (issue4713)
64e4c6bb733d made 'ui' argument is passed via sslutil.sslkwargs(), but mailer
doesn't call sslkwargs() if smtp.verifycert is off. So we have to put it in
sslkwargs manually.
2015-06-07 09:30:15 +09:00
Yuya Nishihara
d3afea0260 ssl: rename ssl_wrap_socket() to conform to our naming convention
I've removed ssl_ prefix because the module name contains ssl.
2015-06-05 21:25:28 +09:00
Pierre-Yves David
c2d40c5751 mail: drop explicit mail import required by Python 2.4
He's dead, Jim.
2015-05-18 16:46:32 -05:00
Pierre-Yves David
4919d2a337 mail: actually use the verifycert config value
The mail module only verifies the smtp ssl certificate if 'verifycert' is enabled
(the default). The 'verifycert' can take three possible values:

- 'strict'
- 'loose'
- any "False" value, eg: 'false' or '0'

We tested the validity of the third value, but never converted it to actual
falseness, making 'False' an equivalent for 'loose'.

This changeset fixes it.
2014-11-05 18:31:39 +00:00
Augie Fackler
67877b90cc python2.4: fix imports of sub-packages of the email package
These all have an obvious comment so if/when we finally ditch Python
2.4 we can eradicate them easily.
2013-09-24 15:10:32 -04:00
Augie Fackler
a49f3fa2a8 mail: correct import of email module 2013-09-20 10:16:02 -04:00
FUJIWARA Katsunori
2f162b6837 smtp: use 465 as default port for SMTPS
Before this patch, port 25 (wellknown port of SMTP) is used as default
port, even if "[smtp] tls" is configured as "smtps".

This patch uses port 465 (wellknown port of SMTPS) as default port, if
"[smtp] tls" is configured as "smtps".
2013-04-19 01:26:23 +09:00
Bryan O'Sullivan
855ee49f38 mail: add missing import of sys
Found using Cython.
2013-04-12 17:17:35 -07:00
FUJIWARA Katsunori
3a3aca3c72 smtp: verify the certificate of the SMTP server for STARTTLS/SMTPS
Before this patch, the certificate of the SMTP server for STARTTLS or
SMTPS isn't verified.

This may cause man-in-the-middle security problem (stealing
authentication information), even though SMTP channel itself is
encrypted by SSL.

When "[smtp] tls" is configured as "smtps" or "starttls", this patch:

  - uses classes introduced by preceding patches instead of "SMTP" or
    "SMTP_SSL" of smtplib, and

  - verifies the certificate of the SMTP server, if "[smtp]
    verifycert" is configured as other than False

"[smtp] verifycert" can be configured in 3 levels:

  - "strict":

    This verifies peer certificate, and aborts if:

      - peer certification is not valid, or
      - no configuration in "[hostfingerprints]" and "[web] cacerts"

    This is default value of "[smtp] verifycert" for security.

  - "loose":

    This verifies peer certificate, and aborts if peer certification is
    not valid.

    This just shows warning message ("certificate not verified"), if
    there is no configuration in "[hostfingerprints]" and "[web]
    cacerts".

    This is as same as verification for HTTPS connection.

  - False(no verification):

    Peer certificate is not verified.

    This is as same as the behavior before this patch series.

"hg email --insecure" uses "loose" level, and ignores "[web] cacerts"
as same as push/pull/etc... with --insecure.

Ignoring "[web] cacerts" configuration for "hg email --insecure" is
already done in "dispatch._dispatch()" by looking "insecure" up in the
table of command options.
2013-03-26 02:28:10 +09:00
FUJIWARA Katsunori
8fbfb98e72 smtp: add the class to verify the certificate of the SMTP server for SMTPS
Original "smtplib.SMTP_SSL" has no route to pass "ca_certs" and
"cert_reqs" arguments to underlying SSL socket creation. This causes
that "getpeercert()" on SSL socket returns empty dict, so the peer
certificate for SMTPS can't be verified.

This patch introduces the "SMTPS" class derived from "smtplib.SMTP" to
pass "ca_certs" and "cert_reqs" arguments to underlying SSL socket
creation.

"SMTPS" class is derived directly from "smtplib.SMTP", because amount
of "smtplib.SMTP_SSL" definition derived from "smtplib.SMTP" is as
same as one needed to override it.

This patch defines "SMTPS" class, only when "smtplib.SMTP" class has
"_get_socket()" method, because this makes using SSL socket instead of
normal socket easy.

"smtplib.SMTP" class of Python 2.5.x or earlier doesn't have this
method. Omitting SMTPS support for them is reasonable, because
"smtplib.SMTP_SSL" is already unavailable for them before this patch.

Almost all code of "SMTPS" class is imported from "smtplib.SMTP_SSL"
of Python 2.7.3, but it differs from original code in point below:

  - "ssl.wrap_socket()" is replaced by "sslutil.ssl_wrap_socket()" for
    compatibility between Python versions
2013-03-26 02:27:43 +09:00
FUJIWARA Katsunori
12eb9a4035 smtp: add the class to verify the certificate of the SMTP server for STARTTLS
Original "smtplib.SMTP" has no route to pass "ca_certs" and
"cert_reqs" arguments to underlying SSL socket creation. This causes
that "getpeercert()" on SSL socket returns empty dict, so the peer
certificate for STARTTLS can't be verified.

This patch introduces the "STARTTLS" class derived from "smtplib.SMTP"
to pass "ca_certs" and "cert_reqs" arguments to underlying SSL socket
creation.

Almost all code of "starttls()" in this class is imported from
"smtplib.SMTP" of Python 2.7.3, but it differs from original code in
points below:

  - "self.ehlo_or_helo_if_needed()" invocation is omitted, because:

    - "ehlo_or_helo_if_needed()" is available with Python 2.6 or later, and
    - "ehlo()" is explicitly invoked in "mercurial.mail._smtp()"

  - "if not _have_ssl:" check is omitted, because:

    - "_have_ssl" is available with Python 2.6 or later, and
    - same checking is done in "mercurial.sslutil.ssl_wrap_socket()"

  - "ssl.wrap_socket()" is replaced by "sslutil.ssl_wrap_socket()" for
    compatibility between Python versions

  - use "sock.recv()" also as "sock.read()", if "sock" doesn't have
    "read()" method

    with Python 2.5.x or earlier, "sslutil.ssl_wrap_socket()" returns
    "httplib.FakeSocket"-ed object, and it doesn't have "read()"
    method, which is invoked via "smtplib.SSLFakeFile".
2013-03-26 02:27:23 +09:00
Mads Kiilerich
5e3dc3e383 avoid using abbreviations that look like spelling errors 2012-08-27 23:14:27 +02:00
Mads Kiilerich
2f4504e446 fix trivial spelling errors 2012-08-15 22:38:42 +02:00
Mads Kiilerich
1961772a73 mail: use quoted-printable for mime encoding to avoid too long lines (issue3075)
Quoted-printable was already used for the more critical patch mails, so it
should be fine for everything else as well.
2011-11-23 02:44:11 +01:00
Mads Kiilerich
ae4bd7a809 notify: add option for writing to mbox
This makes it possible to test how the mails that are sent _really_ look like.
2011-11-23 02:36:33 +01:00
Mads Kiilerich
c30004d07d mail: mbox handling as a part of mail handling, refactored from patchbomb 2011-11-23 02:11:24 +01:00
Augie Fackler
f773c43752 mail: use safehasattr instead of hasattr 2011-07-25 16:02:15 -05:00
Adrian Buehlmann
4163cf2e6f rename util.find_exe to findexe 2011-05-08 20:35:46 +02:00
Adrian Buehlmann
e94d06bb79 rename explain_exit to explainexit 2011-05-06 15:31:09 +02:00
Patrick Mezard
6f893497c0 mail: fix regression when parsing unset smtp.tls option 2011-01-07 20:50:42 +01:00
Zhigang Wang
5376237d45 smtp: fix for server doesn't support starttls extension
Currently we only support enabling TLS by using SMTP STARTTLS extension. But
not all the servers support it.

With this patch, user can choose which way to enable TLS:

* Default:

      tls = none
      port = 25

* To use STARTTLS:

      tls = starttls
      port = 465

* To use SMTP over SSL:

      tls = smtps
      port = 465

To keep backward compatibility, when tls = true, we use STARTTLS to enable TLS.

Signed-off-by: Zhigang Wang <w1z2g3@gmail.com>
2010-12-20 16:56:54 +08:00
Martin Geisler
3abe0ff1c7 merge with stable 2010-08-30 22:52:00 +02:00
Martin Geisler
24891dc092 mail: use standard section.entry format in error message 2010-08-30 22:47:38 +02:00
Brodie Rao
d1905b7d87 mail/hgweb: support service names for ports (issue2350)
This adds util.getport(port) which tries to parse port as an int, and
failing that, looks it up using socket.getservbyname(). Thus, the
following will work:

    [smtp]
    port = submission

    [web]
    port = http

This does not apply to ports in URLs used in clone, pull, etc.
2010-08-28 12:31:07 -04:00
Nicolas Dumazet
6b2a6dc615 mail: ensure that Python2.4 to 2.7 use the same header format
Wrapping format for long headers changed in Python2.7 (see Python issue1974).
Adopt the Python2.7 behaviour and backport it for 2.4-2.6
2010-07-06 18:24:04 +09:00
Matt Mackall
cd3ef170f7 Merge with stable 2010-01-19 22:45:09 -06:00
Matt Mackall
595d66f424 Update license to GPLv2+ 2010-01-19 22:20:08 -06:00
Marti Raudsepp
da98f0beee patchbomb: fix handling of email addresses with Unicode domains (IDNA)
dom.encode('idna') requires dom to be a Unicode string.
2009-11-05 10:49:28 +01:00
David Soria Parra
7322d10ac4 email: Catch exceptions during send.
Catch SMTPlib exceptions to avoid mercurial showing a backtrace during
an e.g. authentication error.
2009-07-27 02:27:24 +02:00
Marti Raudsepp
271fb63ee3 mail: add parseaddrlist() function for parsing many addresses at once
Adds a new function addrlistencode() to mercurial.mail, like addressencode(),
but accepts a list of addresses as input, and returns a list of formatted
addresses. This will be used by patchbomb.

The difference is that each element in the input list can contain multiple
addresses (comma separated or otherwise), and are split using Python's
email.Utils.getaddresses().
2009-11-26 10:47:39 +02:00
Martin Geisler
a46b13f8bb mail: updated comment 2009-05-08 15:14:04 +02:00
Rocco Rutte
00891e0e67 patchbomb: quoted-printable encode overly long lines
RfC2822 mandates a line length limit of 998 byte + CRLF.
Python mail tools break lines at 990 byte. To prevent
that, we quoted-printable encode overly long lines.
2009-05-08 18:30:44 +02:00
Simon Heimberg
09ac1e6c92 separate import lines from mercurial and general python modules 2009-04-28 17:40:46 +02:00
Martin Geisler
750183bdad updated license to be explicit about GPL version 2 2009-04-26 01:08:54 +02:00