aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Magne Ingebrigtsen2010-10-04 00:37:37 +0200
committerLars Magne Ingebrigtsen2010-10-04 00:37:37 +0200
commitc1ae068bbb12dfadbe5f7198fa6584e9c4d7d054 (patch)
tree7a2bcf8d2422a6bbfdb6214ae14aebb81e626bb9 /src
parent5589b70e5789a355d1aa88b469acdaac423ccbbb (diff)
downloademacs-c1ae068bbb12dfadbe5f7198fa6584e9c4d7d054.tar.gz
emacs-c1ae068bbb12dfadbe5f7198fa6584e9c4d7d054.zip
Rework the gnutls boot interface.
From Teodor Zlatanov.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog12
-rw-r--r--src/gnutls.c153
-rw-r--r--src/gnutls.h2
3 files changed, 130 insertions, 37 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c8fb869c583..960602a6d08 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,15 @@
12010-10-03 Teodor Zlatanov <tzz@lifelogs.com>
2
3 * gnutls.h (GNUTLS_LOG2): Convenience macro.
4
5 * gnutls.c: Add property list symbol holders.
6 (emacs_gnutls_handshake): Clarify how sockets are passed to
7 GnuTLS.
8 (gnutls_log_function2): Convenience function using GNUTLS_LOG2.
9 (Fgnutls_boot): Get all parameters from a plist. Require trustfiles
10 and keyfiles to be a list of file names. Default to "NORMAL" for
11 the priority string. Improve logging.
12
12010-10-03 Glenn Morris <rgm@gnu.org> 132010-10-03 Glenn Morris <rgm@gnu.org>
2 14
3 * fileio.c (Vdirectory_sep_char): Remove. 15 * fileio.c (Vdirectory_sep_char): Remove.
diff --git a/src/gnutls.c b/src/gnutls.c
index f765abe92e8..0913e1a3d2f 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -32,6 +32,13 @@ Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again,
32 Qgnutls_e_invalid_session, Qgnutls_e_not_ready_for_handshake; 32 Qgnutls_e_invalid_session, Qgnutls_e_not_ready_for_handshake;
33int global_initialized; 33int global_initialized;
34 34
35/* The following are for the property list of `gnutls-boot'. */
36Lisp_Object Qgnutls_bootprop_priority;
37Lisp_Object Qgnutls_bootprop_trustfiles;
38Lisp_Object Qgnutls_bootprop_keyfiles;
39Lisp_Object Qgnutls_bootprop_callbacks;
40Lisp_Object Qgnutls_bootprop_loglevel;
41
35static void 42static void
36emacs_gnutls_handshake (struct Lisp_Process *proc) 43emacs_gnutls_handshake (struct Lisp_Process *proc)
37{ 44{
@@ -43,6 +50,9 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
43 50
44 if (proc->gnutls_initstage < GNUTLS_STAGE_TRANSPORT_POINTERS_SET) 51 if (proc->gnutls_initstage < GNUTLS_STAGE_TRANSPORT_POINTERS_SET)
45 { 52 {
53 /* This is how GnuTLS takes sockets: as file descriptors passed
54 in. For an Emacs process socket, infd and outfd are the
55 same but we use this two-argument version for clarity. */
46 gnutls_transport_set_ptr2 (state, 56 gnutls_transport_set_ptr2 (state,
47 (gnutls_transport_ptr_t) (long) proc->infd, 57 (gnutls_transport_ptr_t) (long) proc->infd,
48 (gnutls_transport_ptr_t) (long) proc->outfd); 58 (gnutls_transport_ptr_t) (long) proc->outfd);
@@ -271,20 +281,29 @@ gnutls_log_function (int level, const char* string)
271 message ("gnutls.c: [%d] %s", level, string); 281 message ("gnutls.c: [%d] %s", level, string);
272} 282}
273 283
274DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 7, 0, 284static void
275 doc: /* Initialize client-mode GnuTLS for process PROC. 285gnutls_log_function2 (int level, const char* string, const char* extra)
286{
287 message ("gnutls.c: [%d] %s %s", level, string, extra);
288}
289
290DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0,
291 doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST.
276Currently only client mode is supported. Returns a success/failure 292Currently only client mode is supported. Returns a success/failure
277value you can check with `gnutls-errorp'. 293value you can check with `gnutls-errorp'.
278 294
279PRIORITY-STRING is a string describing the priority. 295TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'.
280TYPE is either `gnutls-anon' or `gnutls-x509pki'. 296PROPLIST is a property list with the following keys:
281TRUSTFILE is a PEM encoded trust file for `gnutls-x509pki'. 297
282KEYFILE is ... for `gnutls-x509pki' (TODO). 298:priority is a GnuTLS priority string, defaults to "NORMAL".
283CALLBACK is ... for `gnutls-x509pki' (TODO). 299:trustfiles is a list of PEM-encoded trust files for `gnutls-x509pki'.
284LOGLEVEL is the debug level requested from GnuTLS, try 4. 300:keyfiles is a list of PEM-encoded key files for `gnutls-x509pki'.
301:callbacks is an alist of callback functions (TODO).
302:loglevel is the debug level requested from GnuTLS, try 4.
285 303
286LOGLEVEL will be set for this process AND globally for GnuTLS. So if 304The debug level will be set for this process AND globally for GnuTLS.
287you set it higher or lower at any point, it affects global debugging. 305So if you set it higher or lower at any point, it affects global
306debugging.
288 307
289Note that the priority is set on the client. The server does not use 308Note that the priority is set on the client. The server does not use
290the protocols's priority except for disabling protocols that were not 309the protocols's priority except for disabling protocols that were not
@@ -295,11 +314,9 @@ functions are used. This function allocates resources which can only
295be deallocated by calling `gnutls-deinit' or by calling it again. 314be deallocated by calling `gnutls-deinit' or by calling it again.
296 315
297Each authentication type may need additional information in order to 316Each authentication type may need additional information in order to
298work. For X.509 PKI (`gnutls-x509pki'), you need TRUSTFILE and 317work. For X.509 PKI (`gnutls-x509pki'), you probably need at least
299KEYFILE and optionally CALLBACK. */) 318one trustfile (usually a CA bundle). */)
300 (Lisp_Object proc, Lisp_Object priority_string, Lisp_Object type, 319 (Lisp_Object proc, Lisp_Object type, Lisp_Object proplist)
301 Lisp_Object trustfile, Lisp_Object keyfile, Lisp_Object callback,
302 Lisp_Object loglevel)
303{ 320{
304 int ret = GNUTLS_E_SUCCESS; 321 int ret = GNUTLS_E_SUCCESS;
305 322
@@ -312,10 +329,25 @@ KEYFILE and optionally CALLBACK. */)
312 gnutls_certificate_credentials_t x509_cred; 329 gnutls_certificate_credentials_t x509_cred;
313 gnutls_anon_client_credentials_t anon_cred; 330 gnutls_anon_client_credentials_t anon_cred;
314 Lisp_Object global_init; 331 Lisp_Object global_init;
332 char* priority_string_ptr = "NORMAL"; /* default priority string. */
333 Lisp_Object tail;
334
335 /* Placeholders for the property list elements. */
336 Lisp_Object priority_string;
337 Lisp_Object trustfiles;
338 Lisp_Object keyfiles;
339 Lisp_Object callbacks;
340 Lisp_Object loglevel;
315 341
316 CHECK_PROCESS (proc); 342 CHECK_PROCESS (proc);
317 CHECK_SYMBOL (type); 343 CHECK_SYMBOL (type);
318 CHECK_STRING (priority_string); 344 CHECK_LIST (proplist);
345
346 priority_string = Fplist_get (proplist, Qgnutls_bootprop_priority);
347 trustfiles = Fplist_get (proplist, Qgnutls_bootprop_trustfiles);
348 keyfiles = Fplist_get (proplist, Qgnutls_bootprop_keyfiles);
349 callbacks = Fplist_get (proplist, Qgnutls_bootprop_callbacks);
350 loglevel = Fplist_get (proplist, Qgnutls_bootprop_loglevel);
319 351
320 state = XPROCESS (proc)->gnutls_state; 352 state = XPROCESS (proc)->gnutls_state;
321 XPROCESS (proc)->gnutls_p = 1; 353 XPROCESS (proc)->gnutls_p = 1;
@@ -394,29 +426,49 @@ KEYFILE and optionally CALLBACK. */)
394 426
395 if (EQ (type, Qgnutls_x509pki)) 427 if (EQ (type, Qgnutls_x509pki))
396 { 428 {
397 if (STRINGP (trustfile)) 429 for (tail = trustfiles; !NILP (tail); tail = Fcdr (tail))
398 { 430 {
399 GNUTLS_LOG (1, max_log_level, "setting the trustfile"); 431 Lisp_Object trustfile = Fcar (tail);
400 ret = gnutls_certificate_set_x509_trust_file 432 if (STRINGP (trustfile))
401 (x509_cred, 433 {
402 SDATA (trustfile), 434 GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
403 file_format); 435 SDATA (trustfile));
404 436 ret = gnutls_certificate_set_x509_trust_file
405 if (ret < GNUTLS_E_SUCCESS) 437 (x509_cred,
406 return gnutls_make_error (ret); 438 SDATA (trustfile),
407 } 439 file_format);
440
441 if (ret < GNUTLS_E_SUCCESS)
442 return gnutls_make_error (ret);
443 }
444 else
445 {
446 error ("Sorry, GnuTLS can't use non-string trustfile %s",
447 trustfile);
448 }
449 }
408 450
409 if (STRINGP (keyfile)) 451 for (tail = keyfiles; !NILP (tail); tail = Fcdr (tail))
410 { 452 {
411 GNUTLS_LOG (1, max_log_level, "setting the keyfile"); 453 Lisp_Object keyfile = Fcar (tail);
412 ret = gnutls_certificate_set_x509_crl_file 454 if (STRINGP (keyfile))
413 (x509_cred, 455 {
414 SDATA (keyfile), 456 GNUTLS_LOG2 (1, max_log_level, "setting the keyfile: ",
415 file_format); 457 SDATA (keyfile));
416 458 ret = gnutls_certificate_set_x509_crl_file
417 if (ret < GNUTLS_E_SUCCESS) 459 (x509_cred,
418 return gnutls_make_error (ret); 460 SDATA (keyfile),
419 } 461 file_format);
462
463 if (ret < GNUTLS_E_SUCCESS)
464 return gnutls_make_error (ret);
465 }
466 else
467 {
468 error ("Sorry, GnuTLS can't use non-string keyfile %s",
469 keyfile);
470 }
471 }
420 } 472 }
421 473
422 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES; 474 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES;
@@ -432,10 +484,22 @@ KEYFILE and optionally CALLBACK. */)
432 484
433 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT; 485 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT;
434 486
487 if (STRINGP (priority_string))
488 {
489 priority_string_ptr = (char*) SDATA (priority_string);
490 GNUTLS_LOG2 (1, max_log_level, "got non-default priority string:",
491 priority_string_ptr);
492 }
493 else
494 {
495 GNUTLS_LOG2 (1, max_log_level, "using default priority string:",
496 priority_string_ptr);
497 }
498
435 GNUTLS_LOG (1, max_log_level, "setting the priority string"); 499 GNUTLS_LOG (1, max_log_level, "setting the priority string");
436 500
437 ret = gnutls_priority_set_direct (state, 501 ret = gnutls_priority_set_direct (state,
438 (char*) SDATA (priority_string), 502 priority_string_ptr,
439 NULL); 503 NULL);
440 504
441 if (ret < GNUTLS_E_SUCCESS) 505 if (ret < GNUTLS_E_SUCCESS)
@@ -514,6 +578,21 @@ syms_of_gnutls (void)
514 Qgnutls_x509pki = intern_c_string ("gnutls-x509pki"); 578 Qgnutls_x509pki = intern_c_string ("gnutls-x509pki");
515 staticpro (&Qgnutls_x509pki); 579 staticpro (&Qgnutls_x509pki);
516 580
581 Qgnutls_bootprop_priority = intern_c_string ("priority");
582 staticpro (&Qgnutls_bootprop_priority);
583
584 Qgnutls_bootprop_trustfiles = intern_c_string ("trustfiles");
585 staticpro (&Qgnutls_bootprop_trustfiles);
586
587 Qgnutls_bootprop_keyfiles = intern_c_string ("keyfiles");
588 staticpro (&Qgnutls_bootprop_keyfiles);
589
590 Qgnutls_bootprop_callbacks = intern_c_string ("callbacks");
591 staticpro (&Qgnutls_bootprop_callbacks);
592
593 Qgnutls_bootprop_loglevel = intern_c_string ("loglevel");
594 staticpro (&Qgnutls_bootprop_loglevel);
595
517 Qgnutls_e_interrupted = intern_c_string ("gnutls-e-interrupted"); 596 Qgnutls_e_interrupted = intern_c_string ("gnutls-e-interrupted");
518 staticpro (&Qgnutls_e_interrupted); 597 staticpro (&Qgnutls_e_interrupted);
519 Fput (Qgnutls_e_interrupted, Qgnutls_code, 598 Fput (Qgnutls_e_interrupted, Qgnutls_code,
diff --git a/src/gnutls.h b/src/gnutls.h
index bcf9776963f..2669317e97a 100644
--- a/src/gnutls.h
+++ b/src/gnutls.h
@@ -48,6 +48,8 @@ typedef enum
48 48
49#define GNUTLS_LOG(level, max, string) if (level <= max) { gnutls_log_function (level, "(Emacs) " string); } 49#define GNUTLS_LOG(level, max, string) if (level <= max) { gnutls_log_function (level, "(Emacs) " string); }
50 50
51#define GNUTLS_LOG2(level, max, string, extra) if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); }
52
51int 53int
52emacs_gnutls_write (int fildes, struct Lisp_Process *proc, char *buf, 54emacs_gnutls_write (int fildes, struct Lisp_Process *proc, char *buf,
53 unsigned int nbyte); 55 unsigned int nbyte);