From 5bb869d789b94d46172af7ee149cb7e197385dba Mon Sep 17 00:00:00 2001 From: Lars Magne Ingebrigtsen Date: Wed, 29 Sep 2010 14:48:29 +0200 Subject: [PATCH] Make sure all reads/writes to gnutls streams go via the gnutls functions. --- lisp/ChangeLog | 4 ++++ lisp/net/gnutls.el | 16 +++++----------- src/ChangeLog | 14 ++++++++++++++ src/gnutls.c | 21 +++++++++++++++------ src/gnutls.h | 4 ++-- src/process.c | 13 +++++++------ src/process.h | 1 + 7 files changed, 48 insertions(+), 25 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 7ebd8517203..f44149cf476 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2010-09-29 Lars Magne Ingebrigtsen + + * net/gnutls.el (starttls-negotiate): Loop a lot longer. + 2010-09-29 Glenn Morris * calendar/diary-lib.el (diary-list-entries): Use temp buffers when diff --git a/lisp/net/gnutls.el b/lisp/net/gnutls.el index 6a2d5aff68f..e1d093ebf79 100644 --- a/lisp/net/gnutls.el +++ b/lisp/net/gnutls.el @@ -37,7 +37,7 @@ :prefix "gnutls-" :group 'net-utils) -(defcustom gnutls-log-level 2 +(defcustom gnutls-log-level 0 "Logging level to be used by `starttls-negotiate' and GnuTLS." :type 'integer :group 'gnutls) @@ -91,20 +91,14 @@ CREDENTIALS-FILE is a filename with meaning dependent on CREDENTIALS." (error "Could not boot GnuTLS for this process")); (let ((ret 'gnutls-e-again) - (n 25000)) + (n 250000)) (while (and (not (eq ret t)) (not (gnutls-error-fatalp ret)) (> n 0)) (setq n (1- n)) - (setq ret (gnutls-handshake proc)) - ) - (if (gnutls-errorp ret) - (progn - (message "Ouch, error return %s (%s)" - ret (gnutls-error-string ret)) - (setq proc nil)) - (message "Handshake complete %s." ret))) - proc)) + (setq ret (gnutls-handshake proc))) + (message "Handshake complete %s." ret)) + proc)) (defun starttls-open-stream (name buffer host service) "Open a TLS connection for a service to a host. diff --git a/src/ChangeLog b/src/ChangeLog index 003f4805e28..5d4d5e31d47 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2010-09-29 Lars Magne Ingebrigtsen + + * process.h (Lisp_Process): Add a gnutls_p field to Lisp_Process. + + * process.c (make_process): Set the gnutls_p field to zero by + default. + (read_process_output): Always call the gnutls_read function if the + stream is a gnutls stream. + (send_process): Ditto for writes. + + * gnutls.c (emacs_gnutls_write, emacs_gnutls_read): Refuse to read + or write anything until the state is GNUTLS_STAGE_READY. + (Fgnutls_boot): Mark the stream as being a gnutls stream. + 2010-09-29 Eli Zaretskii * xdisp.c (reseat_1): Initialize bidi_it.paragraph_dir to diff --git a/src/gnutls.c b/src/gnutls.c index 4b8016aab37..2d1aa3247f8 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -33,10 +33,14 @@ Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again, int global_initialized; int -emacs_gnutls_write (int fildes, gnutls_session_t state, char *buf, +emacs_gnutls_write (int fildes, struct Lisp_Process *proc, char *buf, unsigned int nbyte) { register int rtnval, bytes_written; + gnutls_session_t state = proc->gnutls_state; + + if (proc->gnutls_initstage != GNUTLS_STAGE_READY) + return 0; bytes_written = 0; @@ -62,16 +66,20 @@ emacs_gnutls_write (int fildes, gnutls_session_t state, char *buf, } int -emacs_gnutls_read (int fildes, gnutls_session_t state, char *buf, +emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf, unsigned int nbyte) { register int rtnval; + gnutls_session_t state = proc->gnutls_state; + + if (proc->gnutls_initstage != GNUTLS_STAGE_READY) + return 0; rtnval = gnutls_read (state, buf, nbyte); if (rtnval >= 0) return rtnval; else - return -1; + return 0; } /* convert an integer error to a Lisp_Object; it will be either a @@ -272,6 +280,7 @@ KEYFILE and optionally CALLBACK. */) CHECK_STRING (priority_string); state = XPROCESS (proc)->gnutls_state; + XPROCESS (proc)->gnutls_p = 1; if (NUMBERP (loglevel)) { @@ -281,7 +290,7 @@ KEYFILE and optionally CALLBACK. */) max_log_level = XINT (loglevel); XPROCESS (proc)->gnutls_log_level = max_log_level; } - + /* always initialize globals. */ global_init = gnutls_emacs_global_init (); if (! NILP (Fgnutls_errorp (global_init))) @@ -483,7 +492,7 @@ or `gnutls-e-interrupted'. In that case you may resume the handshake if (GNUTLS_INITSTAGE (proc) < GNUTLS_STAGE_HANDSHAKE_CANDO) return Qgnutls_e_not_ready_for_handshake; - + if (GNUTLS_INITSTAGE (proc) < GNUTLS_STAGE_TRANSPORT_POINTERS_SET) { /* for a network process in Emacs infd and outfd are the same @@ -502,7 +511,7 @@ or `gnutls-e-interrupted'. In that case you may resume the handshake ret = gnutls_handshake (state); GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_HANDSHAKE_TRIED; - if (GNUTLS_E_SUCCESS == ret) + if (ret == GNUTLS_E_SUCCESS) { /* here we're finally done. */ GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_READY; diff --git a/src/gnutls.h b/src/gnutls.h index d63555a8a94..bcf9776963f 100644 --- a/src/gnutls.h +++ b/src/gnutls.h @@ -49,10 +49,10 @@ typedef enum #define GNUTLS_LOG(level, max, string) if (level <= max) { gnutls_log_function (level, "(Emacs) " string); } int -emacs_gnutls_write (int fildes, gnutls_session_t state, char *buf, +emacs_gnutls_write (int fildes, struct Lisp_Process *proc, char *buf, unsigned int nbyte); int -emacs_gnutls_read (int fildes, gnutls_session_t state, char *buf, +emacs_gnutls_read (int fildes, struct Lisp_Process *proc, char *buf, unsigned int nbyte); extern void syms_of_gnutls (void); diff --git a/src/process.c b/src/process.c index 4536dcc2a8e..a698e56fe39 100644 --- a/src/process.c +++ b/src/process.c @@ -672,6 +672,7 @@ make_process (Lisp_Object name) #ifdef HAVE_GNUTLS p->gnutls_initstage = GNUTLS_STAGE_EMPTY; p->gnutls_log_level = 0; + p->gnutls_p = 0; #endif /* If name is already in use, modify it until it is unused. */ @@ -5203,8 +5204,8 @@ read_process_output (Lisp_Object proc, register int channel) if (proc_buffered_char[channel] < 0) { #ifdef HAVE_GNUTLS - if (NETCONN_P(proc) && GNUTLS_PROCESS_USABLE (proc)) - nbytes = emacs_gnutls_read (channel, XPROCESS (proc)->gnutls_state, + if (XPROCESS (proc)->gnutls_p) + nbytes = emacs_gnutls_read (channel, XPROCESS (proc), chars + carryover, readmax); else #endif @@ -5242,8 +5243,8 @@ read_process_output (Lisp_Object proc, register int channel) chars[carryover] = proc_buffered_char[channel]; proc_buffered_char[channel] = -1; #ifdef HAVE_GNUTLS - if (NETCONN_P(proc) && GNUTLS_PROCESS_USABLE (proc)) - nbytes = emacs_gnutls_read (channel, XPROCESS (proc)->gnutls_state, + if (XPROCESS (proc)->gnutls_p) + nbytes = emacs_gnutls_read (channel, XPROCESS (proc), chars + carryover + 1, readmax - 1); else #endif @@ -5658,9 +5659,9 @@ send_process (volatile Lisp_Object proc, const unsigned char *volatile buf, #endif { #ifdef HAVE_GNUTLS - if (NETCONN_P(proc) && GNUTLS_PROCESS_USABLE (proc)) + if (XPROCESS (proc)->gnutls_p) rv = emacs_gnutls_write (outfd, - XPROCESS (proc)->gnutls_state, + XPROCESS (proc), (char *) buf, this); else #endif diff --git a/src/process.h b/src/process.h index a28bf090ba9..0350e95310d 100644 --- a/src/process.h +++ b/src/process.h @@ -136,6 +136,7 @@ struct Lisp_Process gnutls_certificate_client_credentials gnutls_x509_cred; gnutls_anon_client_credentials_t gnutls_anon_cred; int gnutls_log_level; + int gnutls_p; #endif }; -- 2.11.4.GIT