Mercurial > emacs
comparison src/gnutls.c @ 110649:2f0d755fa21b
Do the gnutls handshake from the reader loop, instead of looping over
the handshake from Emacs Lisp.
author | Lars Magne Ingebrigtsen <larsi@gnus.org> |
---|---|
date | Wed, 29 Sep 2010 15:25:24 +0200 |
parents | 256dd50b2a63 |
children | 056ce44cedcd |
comparison
equal
deleted
inserted
replaced
110648:256dd50b2a63 | 110649:2f0d755fa21b |
---|---|
29 Lisp_Object Qgnutls_code; | 29 Lisp_Object Qgnutls_code; |
30 Lisp_Object Qgnutls_anon, Qgnutls_x509pki; | 30 Lisp_Object Qgnutls_anon, Qgnutls_x509pki; |
31 Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again, | 31 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; |
33 int global_initialized; | 33 int global_initialized; |
34 | |
35 void | |
36 emacs_gnutls_handshake (struct Lisp_Process *proc) | |
37 { | |
38 gnutls_session_t state = proc->gnutls_state; | |
39 int ret; | |
40 | |
41 if (proc->gnutls_initstage < GNUTLS_STAGE_HANDSHAKE_CANDO) | |
42 return; | |
43 | |
44 if (proc->gnutls_initstage < GNUTLS_STAGE_TRANSPORT_POINTERS_SET) | |
45 { | |
46 /* FIXME: This can't be right: infd and outfd are integers (file handles) | |
47 whereas the function expects args of type gnutls_transport_ptr_t. */ | |
48 gnutls_transport_set_ptr2 (state, proc->infd, proc->outfd); | |
49 | |
50 proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET; | |
51 } | |
52 | |
53 ret = gnutls_handshake (state); | |
54 proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED; | |
55 | |
56 if (ret == GNUTLS_E_SUCCESS) | |
57 { | |
58 /* here we're finally done. */ | |
59 proc->gnutls_initstage = GNUTLS_STAGE_READY; | |
60 } | |
61 } | |
34 | 62 |
35 int | 63 int |
36 emacs_gnutls_write (int fildes, struct Lisp_Process *proc, char *buf, | 64 emacs_gnutls_write (int fildes, struct Lisp_Process *proc, char *buf, |
37 unsigned int nbyte) | 65 unsigned int nbyte) |
38 { | 66 { |
70 unsigned int nbyte) | 98 unsigned int nbyte) |
71 { | 99 { |
72 register int rtnval; | 100 register int rtnval; |
73 gnutls_session_t state = proc->gnutls_state; | 101 gnutls_session_t state = proc->gnutls_state; |
74 | 102 |
75 if (proc->gnutls_initstage != GNUTLS_STAGE_READY) | 103 if (proc->gnutls_initstage != GNUTLS_STAGE_READY) { |
76 return 0; | 104 emacs_gnutls_handshake (proc); |
105 return -1; | |
106 } | |
77 | 107 |
78 rtnval = gnutls_read (state, buf, nbyte); | 108 rtnval = gnutls_read (state, buf, nbyte); |
79 if (rtnval >= 0) | 109 if (rtnval >= 0) |
80 return rtnval; | 110 return rtnval; |
81 else | 111 else |
433 XPROCESS (proc)->gnutls_x509_cred = x509_cred; | 463 XPROCESS (proc)->gnutls_x509_cred = x509_cred; |
434 XPROCESS (proc)->gnutls_cred_type = type; | 464 XPROCESS (proc)->gnutls_cred_type = type; |
435 | 465 |
436 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET; | 466 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET; |
437 | 467 |
468 emacs_gnutls_handshake (XPROCESS (proc)); | |
469 | |
438 return gnutls_make_error (GNUTLS_E_SUCCESS); | 470 return gnutls_make_error (GNUTLS_E_SUCCESS); |
439 } | 471 } |
440 | 472 |
441 DEFUN ("gnutls-bye", Fgnutls_bye, | 473 DEFUN ("gnutls-bye", Fgnutls_bye, |
442 Sgnutls_bye, 2, 2, 0, | 474 Sgnutls_bye, 2, 2, 0, |
465 NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); | 497 NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); |
466 | 498 |
467 return gnutls_make_error (ret); | 499 return gnutls_make_error (ret); |
468 } | 500 } |
469 | 501 |
470 DEFUN ("gnutls-handshake", Fgnutls_handshake, | |
471 Sgnutls_handshake, 1, 1, 0, | |
472 doc: /* Perform GNU TLS handshake for PROCESS. | |
473 The identity of the peer is checked automatically. This function will | |
474 fail if any problem is encountered, and will return a negative error | |
475 code. In case of a client, if it has been asked to resume a session, | |
476 but the server didn't, then a full handshake will be performed. | |
477 | |
478 If the error `gnutls-e-not-ready-for-handshake' is returned, you | |
479 didn't call `gnutls-boot' first. | |
480 | |
481 This function may also return the non-fatal errors `gnutls-e-again', | |
482 or `gnutls-e-interrupted'. In that case you may resume the handshake | |
483 (by calling this function again). */) | |
484 (Lisp_Object proc) | |
485 { | |
486 gnutls_session_t state; | |
487 int ret; | |
488 | |
489 CHECK_PROCESS (proc); | |
490 state = XPROCESS (proc)->gnutls_state; | |
491 | |
492 if (GNUTLS_INITSTAGE (proc) < GNUTLS_STAGE_HANDSHAKE_CANDO) | |
493 return Qgnutls_e_not_ready_for_handshake; | |
494 | |
495 | |
496 if (GNUTLS_INITSTAGE (proc) < GNUTLS_STAGE_TRANSPORT_POINTERS_SET) | |
497 { | |
498 /* for a network process in Emacs infd and outfd are the same | |
499 but this shows our intent more clearly. */ | |
500 message ("gnutls: handshake: setting the transport pointers to %d/%d", | |
501 XPROCESS (proc)->infd, XPROCESS (proc)->outfd); | |
502 | |
503 /* FIXME: This can't be right: infd and outfd are integers (file handles) | |
504 whereas the function expects args of type gnutls_transport_ptr_t. */ | |
505 gnutls_transport_set_ptr2 (state, XPROCESS (proc)->infd, | |
506 XPROCESS (proc)->outfd); | |
507 | |
508 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_TRANSPORT_POINTERS_SET; | |
509 } | |
510 | |
511 ret = gnutls_handshake (state); | |
512 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_HANDSHAKE_TRIED; | |
513 | |
514 if (ret == GNUTLS_E_SUCCESS) | |
515 { | |
516 /* here we're finally done. */ | |
517 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_READY; | |
518 } | |
519 | |
520 return gnutls_make_error (ret); | |
521 } | |
522 | |
523 void | 502 void |
524 syms_of_gnutls (void) | 503 syms_of_gnutls (void) |
525 { | 504 { |
526 global_initialized = 0; | 505 global_initialized = 0; |
527 | 506 |
559 defsubr (&Sgnutls_errorp); | 538 defsubr (&Sgnutls_errorp); |
560 defsubr (&Sgnutls_error_fatalp); | 539 defsubr (&Sgnutls_error_fatalp); |
561 defsubr (&Sgnutls_error_string); | 540 defsubr (&Sgnutls_error_string); |
562 defsubr (&Sgnutls_boot); | 541 defsubr (&Sgnutls_boot); |
563 defsubr (&Sgnutls_deinit); | 542 defsubr (&Sgnutls_deinit); |
564 defsubr (&Sgnutls_handshake); | |
565 defsubr (&Sgnutls_bye); | 543 defsubr (&Sgnutls_bye); |
566 } | 544 } |
567 #endif | 545 #endif |