]> git.eshelyaron.com Git - emacs.git/commitdiff
Allow making TLS negotiation blocking
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Sat, 5 Mar 2016 16:04:23 +0000 (17:04 +0100)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Sat, 5 Mar 2016 16:04:34 +0000 (17:04 +0100)
* lisp/net/gnutls.el (gnutls-negotiate): Make negotiation blocking.

* src/gnutls.c (Fgnutls_boot): Provide a new keyword,
:complete-negotiation, to specify that we want complete
negotiation even if the socket is non-blocking.
(gnutls_try_handshake): Complete negotiation if given that keyword.

* src/process.h (L): Added gnutls_complete_negotiation_p.

etc/NEWS
lisp/net/gnutls.el
src/gnutls.c
src/process.h

index b29d460b19a4a0e75fdb8d9c0673ca46fb251015..92d69d2ccd194e5df52920e025e1a2209891b90c 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -150,6 +150,10 @@ If no insurmountable problems before next release, it can stay that way.
 ** `ert-with-function-mocked' of 'ert-x package allows mocking of functions
 in unit tests.
 
+---
+** `gnutls-boot' now takes a parameter :complete-negotiation that says
+that negotiation should complete even on non-blocking sockets.
+
 +++
 ** New functions `window-pixel-width-before-size-change' and
 `window-pixel-height-before-size-change' allow to detect which window
index 0baf2e34ecd34db41a837d2382bc53b76e8b7b29..9ed1c8b830539f0e2399d033f5842bf2a00aba90 100644 (file)
@@ -175,7 +175,9 @@ For the meaning of the rest of the parameters, see `gnutls-boot-parameters'."
                   :verify-hostname-error verify-hostname-error))
          ret)
     (gnutls-message-maybe
-     (setq ret (gnutls-boot process type params))
+     (setq ret (gnutls-boot process type
+                            (append (list :complete-negotiation t)
+                                    params)))
      "boot: %s" params)
 
     (when (gnutls-errorp ret)
index 988c010486911786a65f671503b199e2eb8bb8a9..db22c924f0cb3841ec282053e2794a486a7150c5 100644 (file)
@@ -402,8 +402,12 @@ gnutls_try_handshake (struct Lisp_Process *proc)
 {
   gnutls_session_t state = proc->gnutls_state;
   int ret;
+  bool non_blocking = proc->is_non_blocking_client;
 
-  if (proc->is_non_blocking_client)
+  if (proc->gnutls_complete_negotiation_p)
+    non_blocking = false;
+
+  if (non_blocking)
     proc->gnutls_p = true;
 
   do
@@ -412,8 +416,9 @@ gnutls_try_handshake (struct Lisp_Process *proc)
       emacs_gnutls_handle_error (state, ret);
       QUIT;
     }
-  while (ret < 0 && gnutls_error_is_fatal (ret) == 0
-        && ! proc->is_non_blocking_client);
+  while (ret < 0
+        && gnutls_error_is_fatal (ret) == 0
+        && ! non_blocking);
 
   proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
 
@@ -1354,6 +1359,9 @@ t to do all checks.  Currently it can contain `:trustfiles' and
 :min-prime-bits is the minimum accepted number of bits the client will
 accept in Diffie-Hellman key exchange.
 
+:complete-negotiation, if non-nil, will make negotiation complete
+before returning even on non-blocking sockets.
+
 The debug level will be set for this process AND globally for GnuTLS.
 So if you set it higher or lower at any point, it affects global
 debugging.
@@ -1642,6 +1650,8 @@ one trustfile (usually a CA bundle).  */)
        return gnutls_make_error (ret);
     }
 
+  XPROCESS (proc)->gnutls_complete_negotiation_p =
+    !NILP (Fplist_get (proplist, QCgnutls_complete_negotiation));
   GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET;
   ret = emacs_gnutls_handshake (XPROCESS (proc));
   if (ret < GNUTLS_E_SUCCESS)
@@ -1734,6 +1744,7 @@ syms_of_gnutls (void)
   DEFSYM (QCgnutls_bootprop_crlfiles, ":crlfiles");
   DEFSYM (QCgnutls_bootprop_min_prime_bits, ":min-prime-bits");
   DEFSYM (QCgnutls_bootprop_loglevel, ":loglevel");
+  DEFSYM (QCgnutls_complete_negotiation, ":complete-negotiation");
   DEFSYM (QCgnutls_bootprop_verify_flags, ":verify-flags");
   DEFSYM (QCgnutls_bootprop_verify_error, ":verify-error");
 
index 038d58b737070584b305ea68cf7a50e22866865b..95bd1b653635ab06a8a6528c2e7ecc5cd55a277b 100644 (file)
@@ -193,6 +193,7 @@ struct Lisp_Process
     int gnutls_log_level;
     int gnutls_handshakes_tried;
     bool_bf gnutls_p : 1;
+    bool_bf gnutls_complete_negotiation_p : 1;
 #endif
 };