GNU bug report logs - #10904
24.0.93; Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL handshake

Previous Next

Package: emacs;

Reported by: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>

Date: Mon, 27 Feb 2012 23:57:02 UTC

Severity: normal

Found in version 24.0.93

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 10904 in the body.
You can then email your comments to 10904 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Mon, 27 Feb 2012 23:57:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Thomas Fitzsimmons <fitzsim <at> fitzsim.org>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Mon, 27 Feb 2012 23:57:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
To: bug-gnu-emacs <at> gnu.org
Subject: 24.0.93; Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Mon, 27 Feb 2012 18:51:35 -0500
[Message part 1 (text/plain, inline)]
In GNU Emacs 24.0.93.7 (i686-pc-linux-gnu, GTK+ Version 2.12.12)
 of 2012-02-23
Configured using:
 `configure '--prefix=/home/fitzsim/Programs/emacs-24.0.93'
 '--x-libraries=/home/fitzsim/Programs/awesome-3.4.11/lib''
Built against: GnuTLS 3.0.8

When I attempt to connect to an Exchange server using IMAP, Emacs
sometimes enters an infinite loop in the GnuTLS code.

I can replicate it on about 50% of attempts:

1. Run:

emacs -Q

2. Evaluate:

(setq gnutls-log-level 5
      message-log-max t
      gnus-directory "~/.emacs.d/gnus/News/"
      gnus-startup-file "~/.emacs.d/gnus/.newsrc"
      gnus-secondary-select-methods
      (quote ((nnimap "<imap_server_hostname>"
                      (nnimap-server-address "<imap_server_hostname>")
                      (nnimap-server-port 993)
                      (nnimap-user "fitzsim")))))

3. Run:

M-x gnus

I've attached the *Messages* output for the passing and failing cases.
I've redacted the IMAP server name, and I had to install a patch to
limit the number of iterations of the loop to 100 so that I could copy
*Messages*.

In the failing case the server returns a non-zero-length SessionID, then
the infinite read loop is entered; when SessionID's length is 0, the
handshake succeeds and I'm greeted with the IMAP password prompt.

Thomas
[messages-pass.txt (text/plain, attachment)]
[messages-fail.txt (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Sat, 03 Mar 2012 14:59:01 GMT) Full text and rfc822 format available.

Message #8 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Lars Magne Ingebrigtsen <larsi <at> gnus.org>
To: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
Cc: 10904 <at> debbugs.gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Sat, 03 Mar 2012 15:56:59 +0100
Thomas Fitzsimmons <fitzsim <at> fitzsim.org> writes:

The error seems to be this?

> gnutls.c: [4] REC[0x90155c8]: Decrypted Packet[1] Handshake(22) with
> length: 3404
>
> gnutls.c: [3] HSK[0x90155c8]: CERTIFICATE was received. Length
> 3400[3400], frag offset 0, frag length: 3400, sequence: 0
>
> gnutls.c: [2] ASSERT:
> /home/fitzsim/sources/gnutls-3.0.8/lib/gnutls_buffers.c:1037
>
> gnutls.c: [1] Received unexpected handshake message 'CERTIFICATE'
> (11). Expected 'SERVER HELLO' (2)
>
> gnutls.c: [2] ASSERT:
> /home/fitzsim/sources/gnutls-3.0.8/lib/gnutls_handshake.c:1226
>
> gnutls.c: [2] ASSERT:
> /home/fitzsim/sources/gnutls-3.0.8/lib/gnutls_handshake.c:2432
>
> gnutls.c: [0] (Emacs) fatal error: An unexpected TLS handshake packet
> was received.

That is, GnuTLS expects SERVER HELLO, but gets CERTIFICATE from the IMAP
server.

Does anybody know what this might mean?

-- 
(domestic pets only, the antidote for overdose, milk.)
  bloggy blog http://lars.ingebrigtsen.no/




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Mon, 19 Mar 2012 14:26:02 GMT) Full text and rfc822 format available.

Message #11 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Ted Zlatanov <tzz <at> lifelogs.com>
To: Lars Magne Ingebrigtsen <larsi <at> gnus.org>
Cc: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>, 10904 <at> debbugs.gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Mon, 19 Mar 2012 09:54:57 -0400
On Sat, 03 Mar 2012 15:56:59 +0100 Lars Magne Ingebrigtsen <larsi <at> gnus.org> wrote: 

LMI> Thomas Fitzsimmons <fitzsim <at> fitzsim.org> writes:
LMI> The error seems to be this?

>> gnutls.c: [4] REC[0x90155c8]: Decrypted Packet[1] Handshake(22) with
>> length: 3404
>> 
>> gnutls.c: [3] HSK[0x90155c8]: CERTIFICATE was received. Length
>> 3400[3400], frag offset 0, frag length: 3400, sequence: 0
>> 
>> gnutls.c: [2] ASSERT:
>> /home/fitzsim/sources/gnutls-3.0.8/lib/gnutls_buffers.c:1037
>> 
>> gnutls.c: [1] Received unexpected handshake message 'CERTIFICATE'
>> (11). Expected 'SERVER HELLO' (2)
>> 
>> gnutls.c: [2] ASSERT:
>> /home/fitzsim/sources/gnutls-3.0.8/lib/gnutls_handshake.c:1226
>> 
>> gnutls.c: [2] ASSERT:
>> /home/fitzsim/sources/gnutls-3.0.8/lib/gnutls_handshake.c:2432
>> 
>> gnutls.c: [0] (Emacs) fatal error: An unexpected TLS handshake packet
>> was received.

LMI> That is, GnuTLS expects SERVER HELLO, but gets CERTIFICATE from the IMAP
LMI> server.

LMI> Does anybody know what this might mean?

(sorry for the late reply)

It seems like a buggy server or something in GnuTLS itself.  I have
never seen this problem before and the lockup is happening in the GnuTLS
internals, where Emacs doesn't play at all (we use the GnuTLS API in a
very straightforward way).

Thomas, can you open a connection to this server with the GnuTLS
command-line tools (gnutls-cli)?  That will reduce the problem to Emacs
vs. GnuTLS.

Thanks
Ted




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Wed, 21 Mar 2012 16:13:01 GMT) Full text and rfc822 format available.

Message #14 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
To: Ted Zlatanov <tzz <at> lifelogs.com>
Cc: Lars Magne Ingebrigtsen <larsi <at> gnus.org>, 10904 <at> debbugs.gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Wed, 21 Mar 2012 11:40:09 -0400
Ted Zlatanov <tzz <at> lifelogs.com> writes:

> On Sat, 03 Mar 2012 15:56:59 +0100 Lars Magne Ingebrigtsen <larsi <at> gnus.org> wrote:
>
> LMI> Thomas Fitzsimmons <fitzsim <at> fitzsim.org> writes:
> LMI> The error seems to be this?
>
>>> gnutls.c: [4] REC[0x90155c8]: Decrypted Packet[1] Handshake(22) with
>>> length: 3404
>>>
>>> gnutls.c: [3] HSK[0x90155c8]: CERTIFICATE was received. Length
>>> 3400[3400], frag offset 0, frag length: 3400, sequence: 0
>>>
>>> gnutls.c: [2] ASSERT:
>>> /home/fitzsim/sources/gnutls-3.0.8/lib/gnutls_buffers.c:1037
>>>
>>> gnutls.c: [1] Received unexpected handshake message 'CERTIFICATE'
>>> (11). Expected 'SERVER HELLO' (2)
>>>
>>> gnutls.c: [2] ASSERT:
>>> /home/fitzsim/sources/gnutls-3.0.8/lib/gnutls_handshake.c:1226
>>>
>>> gnutls.c: [2] ASSERT:
>>> /home/fitzsim/sources/gnutls-3.0.8/lib/gnutls_handshake.c:2432
>>>
>>> gnutls.c: [0] (Emacs) fatal error: An unexpected TLS handshake packet
>>> was received.
>
> LMI> That is, GnuTLS expects SERVER HELLO, but gets CERTIFICATE from the IMAP
> LMI> server.
>
> LMI> Does anybody know what this might mean?
>
> (sorry for the late reply)
>
> It seems like a buggy server or something in GnuTLS itself.  I have
> never seen this problem before and the lockup is happening in the GnuTLS
> internals, where Emacs doesn't play at all (we use the GnuTLS API in a
> very straightforward way).
>
> Thomas, can you open a connection to this server with the GnuTLS
> command-line tools (gnutls-cli)?  That will reduce the problem to Emacs
> vs. GnuTLS.

I did some more investigation using the command line tools.  It turned
out that the IMAP server hostname was resolving to one of a set of
Microsoft Exchange front-end servers.  GnuTLS would fail to connect to
some of the front-end servers but not to others.  This explained why I
would only see the issue sometimes (about half the time).

By explicitly pointing <imap_hostname> in /etc/hosts at one or another
front-end server I was able to make the GnuTLS connection either pass or
fail consistently.  Then I tried "openssl s_client" and it worked on
both GnuTLS-passing and GnuTLS-failing servers.  The servers Gnus failed
to access reported:

[...]
---
New, TLSv1/SSLv3, Cipher is DES-CBC3-SHA
Server public key is 2048 bit
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DES-CBC3-SHA
    Session-ID: 56EFB2D45A0A7A15F173CE086AC0A754016BA00300602F30B47273E565792400
    Session-ID-ctx:
    Master-Key: CD97CB5CB685B42815C8FB056032ABF03C890B42790A07B570E6ED93AEC70D81970EE344265C133100D84BB3789E6B5D
    Key-Arg   : None
    Krb5 Principal: None
    Start Time: 1332336762
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
* OK [...]

and the ones it could access reported:

[...]
---
New, TLSv1/SSLv3, Cipher is RC4-MD5
Server public key is 2048 bit
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-MD5
    Session-ID:
    Session-ID-ctx:
    Master-Key: B6A8BCC0224B72A00A34435DEA66580BD5BFA0FA5D1467471E8070968F206134B410715AE8808C754000B9F1BC1BBD84
    Key-Arg   : None
    Krb5 Principal: None
    Start Time: 1332271498
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
* OK [...]

All of the front-end Exchange servers reported the same version string
but some (the failing set) were configured with the DES-CBC3-SHA cipher
and others (the passing set) were configured with the RC4-MD5 cipher.

Then I went back to gnutls-cli to experiment with its supported ciphers
list.  I discovered that adding the --priority "PERFORMANCE" option
resulted in success for previously-passing and previously-failing server
connections.

The result from gnutls-cli for the previously-passing server
configuration after I added --priority "PERFORMANCE" was:

- The hostname in the certificate matches '<imap_hostname>'.
- Peer's certificate issuer is unknown
- Peer's certificate is NOT trusted
- Version: TLS1.0
- Key Exchange: RSA
- Cipher: ARCFOUR-128
- MAC: MD5
- Compression: NULL
- Session ID: (null)
- Channel binding 'tls-unique': c38c134cd89ef6f0ba9c51f9
- Handshake was completed

- Simple Client Mode:

[...]

- Received[104]: * OK [...]

which was the same as without the --priority option.  However the result
for the previously-failing server configuration after I added --priority
"PERFORMANCE" was:

- The hostname in the certificate matches '<imap_hostname>'.
- Peer's certificate issuer is unknown
- Peer's certificate is NOT trusted
- Version: TLS1.0
- Key Exchange: RSA
- Cipher: ARCFOUR-128
- MAC: SHA1
- Compression: NULL
- Session ID: 35:B3:B2:CE:52:FF:00:D3:0F:DF:0C:25:E0:27:A8:CF:02:9D:17:03:00:14:1C:5B:F3:0F:46:86:02:69:49:64
- Channel binding 'tls-unique': 63b922f2b761712f1f25c40e
- Handshake was completed

- Simple Client Mode:

[...]

- Received[109]: * OK [...]

so --priority "PERFORMANCE" worked around the handshake failure by
selecting a cipher other than the failing DES-CBC3-SHA.

In Emacs I worked around the issue by customizing
gnutls-algorithm-priority to "performance".  Now Gnus always connects
successfully.

But there are still two issues:

1) GnuTLS fails to handshake with a server that uses the DES-CBC3-SHA
   cipher, whereas OpenSSL succeeds

2) If gnutls.el fails to handshake with a server then Emacs enters an
   infinite loop retrying the handshake

Thomas




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Thu, 22 Mar 2012 22:01:02 GMT) Full text and rfc822 format available.

Message #17 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Lars Magne Ingebrigtsen <larsi <at> gnus.org>
To: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
Cc: Ted Zlatanov <tzz <at> lifelogs.com>, 10904 <at> debbugs.gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Thu, 22 Mar 2012 22:29:42 +0100
Thomas Fitzsimmons <fitzsim <at> fitzsim.org> writes:

> 1) GnuTLS fails to handshake with a server that uses the DES-CBC3-SHA
>    cipher, whereas OpenSSL succeeds

This seems like an internal GnuTLS bug, I think?  Could you report it to
gnutls-devel <at> gnu.org?

> 2) If gnutls.el fails to handshake with a server then Emacs enters an
>    infinite loop retrying the handshake

That sounds like a bug on our part.  Do you know whether there's any way
to reproduce this bug without having access to a server that has the
particular problems you've encountered?  For instance, a setting that
makes gnutls try the wrong ciphers or something.  Then I could try to
reproduce and chase down the infloop bug on the Emacs side.

-- 
(domestic pets only, the antidote for overdose, milk.)
  bloggy blog http://lars.ingebrigtsen.no/




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Sat, 24 Mar 2012 22:37:01 GMT) Full text and rfc822 format available.

Message #20 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
To: Lars Magne Ingebrigtsen <larsi <at> gnus.org>
Cc: Ted Zlatanov <tzz <at> lifelogs.com>, 10904 <at> debbugs.gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Sat, 24 Mar 2012 18:04:33 -0400
Lars Magne Ingebrigtsen <larsi <at> gnus.org> writes:

> Thomas Fitzsimmons <fitzsim <at> fitzsim.org> writes:
>
>> 1) GnuTLS fails to handshake with a server that uses the DES-CBC3-SHA
>>    cipher, whereas OpenSSL succeeds
>
> This seems like an internal GnuTLS bug, I think?  Could you report it to
> gnutls-devel <at> gnu.org?

Done.  I sent a bug report to bug-gnutls <at> gnu.org.

>> 2) If gnutls.el fails to handshake with a server then Emacs enters an
>>    infinite loop retrying the handshake
>
> That sounds like a bug on our part.  Do you know whether there's any way
> to reproduce this bug without having access to a server that has the
> particular problems you've encountered?  For instance, a setting that
> makes gnutls try the wrong ciphers or something.  Then I could try to
> reproduce and chase down the infloop bug on the Emacs side.

Yes, this replicates it on my setup:

$ gnutls-serv --http

$ emacs -Q

Eval:

(setq gnutls-log-level 5
      message-log-max t
      gnus-directory "~/.emacs.d/gnus/News/"
      gnus-startup-file "~/.emacs.d/gnus/.newsrc"
      gnus-secondary-select-methods
      (quote ((nnimap "localhost"
                      (nnimap-server-address "localhost")
                      (nnimap-server-port 5556)
                      (nnimap-user "fitzsim")))))

M-x gnus

Thomas




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Fri, 30 Mar 2012 12:47:01 GMT) Full text and rfc822 format available.

Message #23 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ted Zlatanov <tzz <at> lifelogs.com>
To: bug-gnu-emacs <at> gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Fri, 30 Mar 2012 08:13:44 -0400
On Sat, 24 Mar 2012 18:04:33 -0400 Thomas Fitzsimmons <fitzsim <at> fitzsim.org> wrote: 

TF> Lars Magne Ingebrigtsen <larsi <at> gnus.org> writes:
>> Thomas Fitzsimmons <fitzsim <at> fitzsim.org> writes:
>>> 2) If gnutls.el fails to handshake with a server then Emacs enters an
>>> infinite loop retrying the handshake
>> 
>> That sounds like a bug on our part.  Do you know whether there's any way
>> to reproduce this bug without having access to a server that has the
>> particular problems you've encountered?  For instance, a setting that
>> makes gnutls try the wrong ciphers or something.  Then I could try to
>> reproduce and chase down the infloop bug on the Emacs side.

TF> Yes, this replicates it on my setup:

TF> $ gnutls-serv --http

TF> $ emacs -Q

TF> Eval:

TF> (setq gnutls-log-level 5
TF>       message-log-max t
TF>       gnus-directory "~/.emacs.d/gnus/News/"
TF>       gnus-startup-file "~/.emacs.d/gnus/.newsrc"
TF>       gnus-secondary-select-methods
TF>       (quote ((nnimap "localhost"
TF>                       (nnimap-server-address "localhost")
TF>                       (nnimap-server-port 5556)
TF>                       (nnimap-user "fitzsim")))))

TF> M-x gnus

The `gnutls-serv' call has nothing to do with Gnus, right?

I started it with -p 5556 and then

(open-gnutls-stream "tls" "tls-buffer" "localhost" 5556)

prints the following in *Messages*:

gnutls.c: [0] (Emacs) fatal error: A TLS fatal alert has been received.
gnutls.c: [0] (Emacs) Received alert:  Handshake failed
gnutls.el: (err=[-12] A TLS fatal alert has been received.) boot: (:priority NORMAL :hostname localhost :loglevel 0 :min-prime-bits nil :trustfiles (/etc/ssl/certs/ca-certificates.crt) :crlfiles nil :keylist nil :verify-flags nil :verify-error nil :verify-hostname-error nil :callbacks nil)
Entering debugger...
gnutls.c: [0] (Emacs) fatal error: The specified session has been invalidated for some reason.

So there's no infinite loop with the default settings to a `gnutls-serv'
instance, and I'm sure we would have heard about such a lockup from
other users if it was happening.  It seems to be specific to your IMAP
server only.  I'm not sure how to replicate the bug, unfortunately.  Is
setting up a tunnel to your server out of the question?

Ted





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Fri, 30 Mar 2012 21:53:01 GMT) Full text and rfc822 format available.

Message #26 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
To: bug-gnu-emacs <at> gnu.org
Cc: Ted Zlatanov <tzz <at> lifelogs.com>, Lars Magne Ingebrigtsen <larsi <at> gnus.org>
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Fri, 30 Mar 2012 17:52:24 -0400
Hi Ted,

Ted Zlatanov <tzz <at> lifelogs.com> writes:

> The `gnutls-serv' call has nothing to do with Gnus, right?

No, the `gnutls-serv --http' call was meant to simulate an IMAP server
that speaks SSL, configured with a ciphersuite that GnuTLS's default
priority string will fail to handshake with.  It was just the simplest
way I thought of to simulate an SSL server; even though Gnus will not
speak HTTP, the negotiation doesn't get that far on my setup.

Can you try the recipe in Message #20, including running gnus?

Thanks,
Thomas




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Sun, 08 Apr 2012 17:48:01 GMT) Full text and rfc822 format available.

Message #29 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
To: Lars Magne Ingebrigtsen <larsi <at> gnus.org>
Cc: Ted Zlatanov <tzz <at> lifelogs.com>, 10904 <at> debbugs.gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Sun, 08 Apr 2012 13:46:56 -0400
[Message part 1 (text/plain, inline)]
I rechecked this against bzr Emacs and GnuTLS 3.0.17 and it's still
there.  I tried to create a smaller test case and came up with this:

$ gnutls-serv --http &
$ emacs -Q

(progn
  (setq gnutls-log-level 5
        message-log-max t)
  (open-protocol-stream
        "*nnimap*" (current-buffer) "localhost"
        5556
        :type 'ssl
        :return-list t
        :shell-command "ssh %s imapd"
        :capability-command "1 CAPABILITY\r\n"
        :end-of-command "\r\n"
        :success " OK "
        :starttls-function
        (lambda (capabilities)
          (when (gnus-string-match-p "STARTTLS" capabilities)
            "1 STARTTLS\r\n"))))

The open-protocol-stream call is how nnimap-open-connection-1 in
lisp/gnus/nnimap.el creates the IMAP network process.

The loop happens when the GnuTLS handshake fails for some reason, within
a network process.  I use the attached patch to limit the number of
iterations.  I'm not familiar enough with the Emacs process code to
suggest a fix though.

It would be nice if one of you could try against gnutls-serv and confirm
you see this -- I think the problem is general enough that this proves
it and will allow a fix that I can test against my IMAP server.

However, if need-be I can try to arrange a tunnel to the IMAP server I'm
trying to connect to.

As for why this hasn't been seen before, it doesn't affect the GnuTLS
backend standalone (as Ted pointed out) -- it seems to only happen when
an SSL-using process is created and the GnuTLS handshake fails, so it
will be rare that it happens.  Still, an infinite loop is not a nice
failure mode, even if it's rare.

Thomas
[emacs-gnutls-limit-loop.patch (text/x-patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Mon, 09 Apr 2012 00:39:01 GMT) Full text and rfc822 format available.

Message #32 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Ted Zlatanov <tzz <at> lifelogs.com>
To: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
Cc: Lars Magne Ingebrigtsen <larsi <at> gnus.org>, 10904 <at> debbugs.gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Sun, 08 Apr 2012 20:37:32 -0400
[Message part 1 (text/plain, inline)]
On Sun, 08 Apr 2012 13:46:56 -0400 Thomas Fitzsimmons <fitzsim <at> fitzsim.org> wrote: 

TF> The loop happens when the GnuTLS handshake fails for some reason, within
TF> a network process.  I use the attached patch to limit the number of
TF> iterations.  I'm not familiar enough with the Emacs process code to
TF> suggest a fix though.

Thanks again for the help and provided patch.  I modified it to keep the
number of handshakes tried per connection, not globally.  Please try
it.  I will also propose it on emacs-devel for inclusion in the upcoming
24.1 release.

Ted

[gnutls-handshakes.patch (text/x-diff, inline)]
=== modified file 'src/gnutls.c'
--- src/gnutls.c	2012-02-13 20:39:46 +0000
+++ src/gnutls.c	2012-04-09 00:34:32 +0000
@@ -259,6 +259,12 @@
   message ("gnutls.c: [%d] %s %s", level, string, extra);
 }
 
+static void
+gnutls_log_function2i (int level, const char* string, int extra)
+{
+  message ("gnutls.c: [%d] %s %d", level, string, extra);
+}
+
 static int
 emacs_gnutls_handshake (struct Lisp_Process *proc)
 {
@@ -399,10 +405,22 @@
   ssize_t rtnval;
   gnutls_session_t state = proc->gnutls_state;
 
+  int log_level = proc->gnutls_log_level;
+
   if (proc->gnutls_initstage != GNUTLS_STAGE_READY)
     {
-      emacs_gnutls_handshake (proc);
-      return -1;
+      if (proc->gnutls_handshakes_tried < GNUTLS_EMACS_HANDSHAKES_LIMIT)
+        {
+          proc->gnutls_handshakes_tried++;
+          emacs_gnutls_handshake (proc);
+          GNUTLS_LOG2i (5, log_level, "Retried handshake", 
+                        proc->gnutls_handshakes_tried);
+          return -1;
+        }
+
+      GNUTLS_LOG (2, log_level, "Giving up on handshake; resetting retries");
+      proc->gnutls_handshakes_tried = 0;
+      return 0;
     }
   rtnval = fn_gnutls_record_recv (state, buf, nbyte);
   if (rtnval >= 0)

=== modified file 'src/gnutls.h'
--- src/gnutls.h	2012-01-05 09:46:05 +0000
+++ src/gnutls.h	2012-04-09 00:29:27 +0000
@@ -23,6 +23,8 @@
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
 
+#define GNUTLS_EMACS_HANDSHAKES_LIMIT 100
+
 typedef enum
 {
   /* Initialization stages.  */
@@ -53,6 +55,8 @@
 
 #define GNUTLS_LOG2(level, max, string, extra) do { if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); } } while (0)
 
+#define GNUTLS_LOG2i(level, max, string, extra) do { if (level <= max) { gnutls_log_function2i (level, "(Emacs) " string, extra); } } while (0)
+
 extern EMACS_INT
 emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, EMACS_INT nbyte);
 extern EMACS_INT

=== modified file 'src/process.c'
--- src/process.c	2012-03-23 12:23:14 +0000
+++ src/process.c	2012-04-09 00:24:07 +0000
@@ -641,6 +641,7 @@
 #ifdef HAVE_GNUTLS
   p->gnutls_initstage = GNUTLS_STAGE_EMPTY;
   p->gnutls_log_level = 0;
+  p->gnutls_handshakes_tried = 0;
   p->gnutls_p = 0;
   p->gnutls_state = NULL;
   p->gnutls_x509_cred = NULL;

=== modified file 'src/process.h'
--- src/process.h	2012-01-19 07:21:25 +0000
+++ src/process.h	2012-04-09 00:23:24 +0000
@@ -134,6 +134,7 @@
     gnutls_certificate_client_credentials gnutls_x509_cred;
     gnutls_anon_client_credentials_t gnutls_anon_cred;
     int gnutls_log_level;
+    int gnutls_handshakes_tried;
     int gnutls_p;
 #endif
 };


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Mon, 09 Apr 2012 13:17:02 GMT) Full text and rfc822 format available.

Message #35 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ted Zlatanov <tzz <at> lifelogs.com>
To: bug-gnu-emacs <at> gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Mon, 09 Apr 2012 09:14:52 -0400
On Sun, 08 Apr 2012 20:37:32 -0400 Ted Zlatanov <tzz <at> lifelogs.com> wrote: 

TZ> On Sun, 08 Apr 2012 13:46:56 -0400 Thomas Fitzsimmons <fitzsim <at> fitzsim.org> wrote: 
TF> The loop happens when the GnuTLS handshake fails for some reason, within
TF> a network process.  I use the attached patch to limit the number of
TF> iterations.  I'm not familiar enough with the Emacs process code to
TF> suggest a fix though.

TZ> Thanks again for the help and provided patch.  I modified it to keep the
TZ> number of handshakes tried per connection, not globally.  Please try
TZ> it.  I will also propose it on emacs-devel for inclusion in the upcoming
TZ> 24.1 release.

The patch with some slight modification is in the Emacs trunk, so please
pull and test from there.

Ted





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Tue, 10 Apr 2012 03:09:02 GMT) Full text and rfc822 format available.

Message #38 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
To: Ted Zlatanov <tzz <at> lifelogs.com>
Cc: Lars Magne Ingebrigtsen <larsi <at> gnus.org>, 10904 <at> debbugs.gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Mon, 09 Apr 2012 23:07:34 -0400
Ted Zlatanov <tzz <at> lifelogs.com> writes:

> On Sun, 08 Apr 2012 13:46:56 -0400 Thomas Fitzsimmons <fitzsim <at> fitzsim.org> wrote:
>
> TF> The loop happens when the GnuTLS handshake fails for some reason, within
> TF> a network process.  I use the attached patch to limit the number of
> TF> iterations.  I'm not familiar enough with the Emacs process code to
> TF> suggest a fix though.
>
> Thanks again for the help and provided patch.  I modified it to keep the
> number of handshakes tried per connection, not globally.  Please try
> it.  I will also propose it on emacs-devel for inclusion in the upcoming
> 24.1 release.

I tried trunk against my IMAP server and the applied patch prevents the
infinite loop.  At the default gnutls-log-level, a connection attempt
fails with:

Warning: Opening nnimap server on <imap_server_hostname>...failed: ; Unable to open server nnimap+<imap_server_hostname> due to: GnuTLS error: #<process *nnimap*>, -9
gnutls.c: [0] (Emacs) fatal error: The specified session has been invalidated for some reason.

A nice improvement would be to detect when the server uses a ciphersuite
that GnuTLS's default priority list ("NORMAL") rejects, warn the user,
and ask if they want to retry with a more permissive list
("PERFORMANCE").  But that's a separate enhancement -- for now your
patch fixes the infinite loop and setting gnutls-algorithm-priority to
"performance" works around the server's weak ciphersuite.

Thanks,
Thomas




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Tue, 10 Apr 2012 11:56:02 GMT) Full text and rfc822 format available.

Message #41 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Ted Zlatanov <tzz <at> lifelogs.com>
To: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
Cc: Lars Magne Ingebrigtsen <larsi <at> gnus.org>, 10904 <at> debbugs.gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Tue, 10 Apr 2012 07:54:01 -0400
On Mon, 09 Apr 2012 23:07:34 -0400 Thomas Fitzsimmons <fitzsim <at> fitzsim.org> wrote: 

TF> I tried trunk against my IMAP server and the applied patch prevents the
TF> infinite loop.  At the default gnutls-log-level, a connection attempt
TF> fails with:

TF> Warning: Opening nnimap server on <imap_server_hostname>...failed: ; Unable to open server nnimap+<imap_server_hostname> due to: GnuTLS error: #<process *nnimap*>, -9
TF> gnutls.c: [0] (Emacs) fatal error: The specified session has been invalidated for some reason.

Wonderful.

TF> A nice improvement would be to detect when the server uses a ciphersuite
TF> that GnuTLS's default priority list ("NORMAL") rejects, warn the user,
TF> and ask if they want to retry with a more permissive list
TF> ("PERFORMANCE").  But that's a separate enhancement -- for now your
TF> patch fixes the infinite loop and setting gnutls-algorithm-priority to
TF> "performance" works around the server's weak ciphersuite.

I plan to follow Nikos' advice here:

http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/6017

so we'll drop from NORMAL to PERFORMANCE, basically, if the user
approves.  After the 24.1 release I'll look at this.

Ted




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Tue, 10 Apr 2012 17:46:01 GMT) Full text and rfc822 format available.

Message #44 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Lars Magne Ingebrigtsen <larsi <at> gnus.org>
To: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
Cc: 10904 <at> debbugs.gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Tue, 10 Apr 2012 19:44:03 +0200
Ted Zlatanov <tzz <at> lifelogs.com> writes:

> I plan to follow Nikos' advice here:
>
> http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/6017
>
> so we'll drop from NORMAL to PERFORMANCE, basically, if the user
> approves.  After the 24.1 release I'll look at this.

Warning the user is fine, but I don't think the user needs to be
queried.

-- 
(domestic pets only, the antidote for overdose, milk.)
  bloggy blog http://lars.ingebrigtsen.no/




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Wed, 11 Apr 2012 12:05:02 GMT) Full text and rfc822 format available.

Message #47 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ted Zlatanov <tzz <at> lifelogs.com>
To: bug-gnu-emacs <at> gnu.org
Subject: Re: bug#10904: 24.0.93;
	Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
	handshake
Date: Wed, 11 Apr 2012 08:02:54 -0400
On Tue, 10 Apr 2012 19:44:03 +0200 Lars Magne Ingebrigtsen <larsi <at> gnus.org> wrote: 

LMI> Ted Zlatanov <tzz <at> lifelogs.com> writes:
>> I plan to follow Nikos' advice here:
>> 
>> http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/6017
>> 
>> so we'll drop from NORMAL to PERFORMANCE, basically, if the user
>> approves.  After the 24.1 release I'll look at this.

LMI> Warning the user is fine, but I don't think the user needs to be
LMI> queried.

OK.

Ted





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Mon, 08 Dec 2014 20:07:01 GMT) Full text and rfc822 format available.

Message #50 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Lars Magne Ingebrigtsen <larsi <at> gnus.org>
To: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
Cc: Ted Zlatanov <tzz <at> lifelogs.com>, 10904 <at> debbugs.gnu.org
Subject: Re: bug#10904: 24.0.93;
 Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
 handshake
Date: Mon, 08 Dec 2014 21:06:21 +0100
Ted Zlatanov <tzz <at> lifelogs.com> writes:

> I plan to follow Nikos' advice here:
>
> http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/6017
>
> so we'll drop from NORMAL to PERFORMANCE, basically, if the user
> approves.  After the 24.1 release I'll look at this.

Would it make sense to just default to PERFORMANCE now that we have the
NSM?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Wed, 10 Dec 2014 16:10:01 GMT) Full text and rfc822 format available.

Message #53 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Ted Zlatanov <tzz <at> lifelogs.com>
To: Lars Magne Ingebrigtsen <larsi <at> gnus.org>
Cc: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>, 10904 <at> debbugs.gnu.org
Subject: Re: bug#10904: 24.0.93;
 Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
 handshake
Date: Wed, 10 Dec 2014 11:10:08 -0500
On Mon, 08 Dec 2014 21:06:21 +0100 Lars Magne Ingebrigtsen <larsi <at> gnus.org> wrote: 

LMI> Ted Zlatanov <tzz <at> lifelogs.com> writes:
>> I plan to follow Nikos' advice here:
>> 
>> http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/6017
>> 
>> so we'll drop from NORMAL to PERFORMANCE, basically, if the user
>> approves.  After the 24.1 release I'll look at this.

LMI> Would it make sense to just default to PERFORMANCE now that we have the
LMI> NSM?

The default priority string should correspond to the medium
`network-security-level' so yes, I think so.  But I really think those
two should be bound closer together, as I mentioned.

Ted




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Fri, 05 Feb 2016 07:28:02 GMT) Full text and rfc822 format available.

Message #56 received at 10904 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: 10904 <at> debbugs.gnu.org
Cc: Thomas Fitzsimmons <fitzsim <at> fitzsim.org>
Subject: Re: bug#10904: 24.0.93;
 Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
 handshake
Date: Fri, 05 Feb 2016 18:26:46 +1100
Ted Zlatanov <tzz <at> lifelogs.com> writes:

> On Mon, 08 Dec 2014 21:06:21 +0100 Lars Magne Ingebrigtsen <larsi <at> gnus.org> wrote: 
>
> LMI> Ted Zlatanov <tzz <at> lifelogs.com> writes:
>>> I plan to follow Nikos' advice here:
>>> 
>>> http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/6017
>>> 
>>> so we'll drop from NORMAL to PERFORMANCE, basically, if the user
>>> approves.  After the 24.1 release I'll look at this.
>
> LMI> Would it make sense to just default to PERFORMANCE now that we have the
> LMI> NSM?
>
> The default priority string should correspond to the medium
> `network-security-level' so yes, I think so.  But I really think those
> two should be bound closer together, as I mentioned.

Yeah...  running with PERFORMANCE by default is perhaps hubris.  :-)
But how would we do this within the open-network-stream/nsm
framework...  Basically, with NORMAL the tls negotiation will fail.  It
would be nice if we could then let the NSM query the user for whether
they want to lower the security to PERFORMANCE and reconnect.

But that doesn't quite fit the way all of this is structured.  If the
user says "yes, go ahead and lower security", then the NSM will have to,
er, bind something, and then call open-network-stream all over again?
Sort of?

That's probably possible, but it may require some extensive tinkering
with how `nsm-verify-connection' is called...  or with how
open-network-stream structures the call to NSM.

*time passes*

Hm!  Perhaps it won't be that difficult or invasive.  This is how this
is called:

(defun network-stream-open-tls (name buffer host service parameters)
  (with-current-buffer buffer
    (let* ((start (point-max))
	   (stream
            (if (gnutls-available-p)
                (open-gnutls-stream name buffer host service
                                    (plist-get parameters :nowait))
              (open-tls-stream name buffer host service)))
	   (eoc (plist-get parameters :end-of-command)))
      ;; Check certificate validity etc.
      (when (and (gnutls-available-p) stream)
	(setq stream (nsm-verify-connection stream host service)))

So what happens here is that stream will be nil or dead from
open-gnutls-stream.  In that case, it could call nsm-verify-connection
with some special parameters, have it prompt, and then reconnect if the
user says "yes"...

Hm.  But then those stores parameters should be used the next time in
network-stream, and it doesn't have access to those stored parameters.

Gah.  This stuff is hard.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#10904; Package emacs. (Thu, 02 Jun 2016 14:23:02 GMT) Full text and rfc822 format available.

Message #59 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ted Zlatanov <tzz <at> lifelogs.com>
To: bug-gnu-emacs <at> gnu.org
Subject: Re: bug#10904: 24.0.93;
 Infinite loop in GnuTLS code during Gnus nnimap-initiated SSL
 handshake
Date: Thu, 02 Jun 2016 10:21:12 -0400
On Fri, 05 Feb 2016 18:26:46 +1100 Lars Ingebrigtsen <larsi <at> gnus.org> wrote: 

LI> Hm.  But then those stores parameters should be used the next time in
LI> network-stream, and it doesn't have access to those stored parameters.

Specific security-related could be saved in network-security.data on the
fly. This would serve the use case of "I just want to override this
right now."

They could also be provided by auth-source.el, so you could say

    server specialserver priority-string "PERFORMANCE"

This would serve the use case of "I want to override the priority string
every time but without customizing variables".

Finally, `gnutls-algorithm-priority' can be extended similarly to
`gnutls-verify-error' to work per host. So that would provide for the
third use case of the Customize user.

I think the better way is to make a top-level `gnutls-boot-parameters'
variable that has all the relevant settings per host, and make the
function `gnutls-boot-parameters' simply look inside that variable (the
name may not be right). Then we could obsolete
`gnutls-algorithm-priority', `gnutls-verify-error' and
`gnutls-min-prime-bits' in favor of that variable, and provide the
corresponding auth-source.el glue so the settings could also be
retrieved from auth-source.

Ted





bug closed, send any further explanations to 10904 <at> debbugs.gnu.org and Thomas Fitzsimmons <fitzsim <at> fitzsim.org> Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Fri, 13 Apr 2018 12:39:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 12 May 2018 11:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 7 years and 40 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.