diff options
| author | Ted Zlatanov | 2012-04-09 08:46:16 -0400 |
|---|---|---|
| committer | Ted Zlatanov | 2012-04-09 08:46:16 -0400 |
| commit | a18ecafa99e7e7c3caa35ed68dd8a7b9b5d2b8e3 (patch) | |
| tree | 51714f1203b0b06d44591f57f245ca7c94acde48 /src | |
| parent | b4d3bc10dc84f6b01a2b6b215d0e489555aa6edd (diff) | |
| download | emacs-a18ecafa99e7e7c3caa35ed68dd8a7b9b5d2b8e3.tar.gz emacs-a18ecafa99e7e7c3caa35ed68dd8a7b9b5d2b8e3.zip | |
Limit number of GnuTLS handshakes per connection.
* gnutls.c (gnutls_log_function2i): Convenience log function.
(emacs_gnutls_read): Use new log functions,
`gnutls_handshakes_tried' process member, and
`GNUTLS_EMACS_HANDSHAKES_LIMIT' to limit the number of handshake
attempts per process (connection).
* gnutls.h: Add `GNUTLS_EMACS_HANDSHAKES_LIMIT' upper limit. Add
convenience `GNUTLS_LOG2i' macro.
* process.c (make_process):
* process.h: Add integer `gnutls_handshakes_tried' member to
process struct.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 15 | ||||
| -rw-r--r-- | src/gnutls.c | 28 | ||||
| -rw-r--r-- | src/gnutls.h | 5 | ||||
| -rw-r--r-- | src/process.c | 3 | ||||
| -rw-r--r-- | src/process.h | 1 |
5 files changed, 50 insertions, 2 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 7c3dd115c5b..f7889d99335 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,18 @@ | |||
| 1 | 2012-04-09 Teodor Zlatanov <tzz@lifelogs.com> | ||
| 2 | |||
| 3 | * process.c (make_process): | ||
| 4 | * process.h: Add integer `gnutls_handshakes_tried' member to | ||
| 5 | process struct. | ||
| 6 | |||
| 7 | * gnutls.h: Add `GNUTLS_EMACS_HANDSHAKES_LIMIT' upper limit. Add | ||
| 8 | convenience `GNUTLS_LOG2i' macro. | ||
| 9 | |||
| 10 | * gnutls.c (gnutls_log_function2i): Convenience log function. | ||
| 11 | (emacs_gnutls_read): Use new log functions, | ||
| 12 | `gnutls_handshakes_tried' process member, and | ||
| 13 | `GNUTLS_EMACS_HANDSHAKES_LIMIT' to limit the number of handshake | ||
| 14 | attempts per process (connection). | ||
| 15 | |||
| 1 | 2012-04-09 Chong Yidong <cyd@gnu.org> | 16 | 2012-04-09 Chong Yidong <cyd@gnu.org> |
| 2 | 17 | ||
| 3 | * eval.c (Fuser_variable_p, user_variable_p_eh) | 18 | * eval.c (Fuser_variable_p, user_variable_p_eh) |
diff --git a/src/gnutls.c b/src/gnutls.c index 6b5cb47001b..70eea3b0b89 100644 --- a/src/gnutls.c +++ b/src/gnutls.c | |||
| @@ -247,18 +247,27 @@ init_gnutls_functions (Lisp_Object libraries) | |||
| 247 | #endif /* !WINDOWSNT */ | 247 | #endif /* !WINDOWSNT */ |
| 248 | 248 | ||
| 249 | 249 | ||
| 250 | /* Function to log a simple message. */ | ||
| 250 | static void | 251 | static void |
| 251 | gnutls_log_function (int level, const char* string) | 252 | gnutls_log_function (int level, const char* string) |
| 252 | { | 253 | { |
| 253 | message ("gnutls.c: [%d] %s", level, string); | 254 | message ("gnutls.c: [%d] %s", level, string); |
| 254 | } | 255 | } |
| 255 | 256 | ||
| 257 | /* Function to log a message and a string. */ | ||
| 256 | static void | 258 | static void |
| 257 | gnutls_log_function2 (int level, const char* string, const char* extra) | 259 | gnutls_log_function2 (int level, const char* string, const char* extra) |
| 258 | { | 260 | { |
| 259 | message ("gnutls.c: [%d] %s %s", level, string, extra); | 261 | message ("gnutls.c: [%d] %s %s", level, string, extra); |
| 260 | } | 262 | } |
| 261 | 263 | ||
| 264 | /* Function to log a message and an integer. */ | ||
| 265 | static void | ||
| 266 | gnutls_log_function2i (int level, const char* string, int extra) | ||
| 267 | { | ||
| 268 | message ("gnutls.c: [%d] %s %d", level, string, extra); | ||
| 269 | } | ||
| 270 | |||
| 262 | static int | 271 | static int |
| 263 | emacs_gnutls_handshake (struct Lisp_Process *proc) | 272 | emacs_gnutls_handshake (struct Lisp_Process *proc) |
| 264 | { | 273 | { |
| @@ -399,10 +408,25 @@ emacs_gnutls_read (struct Lisp_Process *proc, char *buf, EMACS_INT nbyte) | |||
| 399 | ssize_t rtnval; | 408 | ssize_t rtnval; |
| 400 | gnutls_session_t state = proc->gnutls_state; | 409 | gnutls_session_t state = proc->gnutls_state; |
| 401 | 410 | ||
| 411 | int log_level = proc->gnutls_log_level; | ||
| 412 | |||
| 402 | if (proc->gnutls_initstage != GNUTLS_STAGE_READY) | 413 | if (proc->gnutls_initstage != GNUTLS_STAGE_READY) |
| 403 | { | 414 | { |
| 404 | emacs_gnutls_handshake (proc); | 415 | /* If the handshake count is under the limit, try the handshake |
| 405 | return -1; | 416 | again and increment the handshake count. This count is kept |
| 417 | per process (connection), not globally. */ | ||
| 418 | if (proc->gnutls_handshakes_tried < GNUTLS_EMACS_HANDSHAKES_LIMIT) | ||
| 419 | { | ||
| 420 | proc->gnutls_handshakes_tried++; | ||
| 421 | emacs_gnutls_handshake (proc); | ||
| 422 | GNUTLS_LOG2i (5, log_level, "Retried handshake", | ||
| 423 | proc->gnutls_handshakes_tried); | ||
| 424 | return -1; | ||
| 425 | } | ||
| 426 | |||
| 427 | GNUTLS_LOG (2, log_level, "Giving up on handshake; resetting retries"); | ||
| 428 | proc->gnutls_handshakes_tried = 0; | ||
| 429 | return 0; | ||
| 406 | } | 430 | } |
| 407 | rtnval = fn_gnutls_record_recv (state, buf, nbyte); | 431 | rtnval = fn_gnutls_record_recv (state, buf, nbyte); |
| 408 | if (rtnval >= 0) | 432 | if (rtnval >= 0) |
diff --git a/src/gnutls.h b/src/gnutls.h index 474da77aec5..37b9a2eb4df 100644 --- a/src/gnutls.h +++ b/src/gnutls.h | |||
| @@ -23,6 +23,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 23 | #include <gnutls/gnutls.h> | 23 | #include <gnutls/gnutls.h> |
| 24 | #include <gnutls/x509.h> | 24 | #include <gnutls/x509.h> |
| 25 | 25 | ||
| 26 | /* This limits the attempts to handshake per process (connection). */ | ||
| 27 | #define GNUTLS_EMACS_HANDSHAKES_LIMIT 100 | ||
| 28 | |||
| 26 | typedef enum | 29 | typedef enum |
| 27 | { | 30 | { |
| 28 | /* Initialization stages. */ | 31 | /* Initialization stages. */ |
| @@ -53,6 +56,8 @@ typedef enum | |||
| 53 | 56 | ||
| 54 | #define GNUTLS_LOG2(level, max, string, extra) do { if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); } } while (0) | 57 | #define GNUTLS_LOG2(level, max, string, extra) do { if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); } } while (0) |
| 55 | 58 | ||
| 59 | #define GNUTLS_LOG2i(level, max, string, extra) do { if (level <= max) { gnutls_log_function2i (level, "(Emacs) " string, extra); } } while (0) | ||
| 60 | |||
| 56 | extern EMACS_INT | 61 | extern EMACS_INT |
| 57 | emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, EMACS_INT nbyte); | 62 | emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, EMACS_INT nbyte); |
| 58 | extern EMACS_INT | 63 | extern EMACS_INT |
diff --git a/src/process.c b/src/process.c index f2f33a9eafc..dc43191ebef 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -640,7 +640,10 @@ make_process (Lisp_Object name) | |||
| 640 | 640 | ||
| 641 | #ifdef HAVE_GNUTLS | 641 | #ifdef HAVE_GNUTLS |
| 642 | p->gnutls_initstage = GNUTLS_STAGE_EMPTY; | 642 | p->gnutls_initstage = GNUTLS_STAGE_EMPTY; |
| 643 | /* Default log level. */ | ||
| 643 | p->gnutls_log_level = 0; | 644 | p->gnutls_log_level = 0; |
| 645 | /* GnuTLS handshakes attempted for this connection. */ | ||
| 646 | p->gnutls_handshakes_tried = 0; | ||
| 644 | p->gnutls_p = 0; | 647 | p->gnutls_p = 0; |
| 645 | p->gnutls_state = NULL; | 648 | p->gnutls_state = NULL; |
| 646 | p->gnutls_x509_cred = NULL; | 649 | p->gnutls_x509_cred = NULL; |
diff --git a/src/process.h b/src/process.h index 9efde261386..3eb94cb196b 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -134,6 +134,7 @@ struct Lisp_Process | |||
| 134 | gnutls_certificate_client_credentials gnutls_x509_cred; | 134 | gnutls_certificate_client_credentials gnutls_x509_cred; |
| 135 | gnutls_anon_client_credentials_t gnutls_anon_cred; | 135 | gnutls_anon_client_credentials_t gnutls_anon_cred; |
| 136 | int gnutls_log_level; | 136 | int gnutls_log_level; |
| 137 | int gnutls_handshakes_tried; | ||
| 137 | int gnutls_p; | 138 | int gnutls_p; |
| 138 | #endif | 139 | #endif |
| 139 | }; | 140 | }; |