diff options
| author | Lars Ingebrigtsen | 2016-02-15 18:24:08 +1100 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2016-02-15 18:24:08 +1100 |
| commit | 9c74f2fea6bfa6bc38358835539944017cf35917 (patch) | |
| tree | 17463dee36e640d38c302b3ef2c169b4e536e33c /src/process.c | |
| parent | 40155283c380a795c1a0036a31e1b41ed1df0f38 (diff) | |
| download | emacs-9c74f2fea6bfa6bc38358835539944017cf35917.tar.gz emacs-9c74f2fea6bfa6bc38358835539944017cf35917.zip | |
Call the network security manager after doing TLS negotiation
* lisp/net/network-stream.el (network-stream-open-tls):
Postpone NSM verification when running async.
* src/process.c (Fset_process_filter): This function doesn't
need to wait.
(connect_network_socket): Set the process status to "run" only
after TLS negotiation.
(wait_for_socket_fds): Take a name parameter for more debugging.
(wait_reading_process_output): Don't change status to "run"
unless TLS negotiation has finished.
(send_process): Wait for the process here instead of
send_process_string.
(connect_network_socket): Call the network security manager.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 114 |
1 files changed, 79 insertions, 35 deletions
diff --git a/src/process.c b/src/process.c index 1dd52742e16..e8900715158 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -284,7 +284,7 @@ static Lisp_Object chan_process[FD_SETSIZE]; | |||
| 284 | #ifdef HAVE_GETADDRINFO_A | 284 | #ifdef HAVE_GETADDRINFO_A |
| 285 | /* Pending DNS requests. */ | 285 | /* Pending DNS requests. */ |
| 286 | static Lisp_Object dns_processes; | 286 | static Lisp_Object dns_processes; |
| 287 | static void wait_for_socket_fds (Lisp_Object process); | 287 | static void wait_for_socket_fds (Lisp_Object process, char *name); |
| 288 | #endif | 288 | #endif |
| 289 | 289 | ||
| 290 | /* Alist of elements (NAME . PROCESS). */ | 290 | /* Alist of elements (NAME . PROCESS). */ |
| @@ -1031,9 +1031,6 @@ The string argument is normally a multibyte string, except: | |||
| 1031 | 1031 | ||
| 1032 | CHECK_PROCESS (process); | 1032 | CHECK_PROCESS (process); |
| 1033 | 1033 | ||
| 1034 | if (NETCONN_P (process)) | ||
| 1035 | wait_for_socket_fds (process); | ||
| 1036 | |||
| 1037 | p = XPROCESS (process); | 1034 | p = XPROCESS (process); |
| 1038 | 1035 | ||
| 1039 | /* Don't signal an error if the process's input file descriptor | 1036 | /* Don't signal an error if the process's input file descriptor |
| @@ -1119,7 +1116,7 @@ DEFUN ("set-process-window-size", Fset_process_window_size, | |||
| 1119 | CHECK_PROCESS (process); | 1116 | CHECK_PROCESS (process); |
| 1120 | 1117 | ||
| 1121 | if (NETCONN_P (process)) | 1118 | if (NETCONN_P (process)) |
| 1122 | wait_for_socket_fds (process); | 1119 | wait_for_socket_fds (process, "set-process-window-size"); |
| 1123 | 1120 | ||
| 1124 | /* All known platforms store window sizes as 'unsigned short'. */ | 1121 | /* All known platforms store window sizes as 'unsigned short'. */ |
| 1125 | CHECK_RANGED_INTEGER (height, 0, USHRT_MAX); | 1122 | CHECK_RANGED_INTEGER (height, 0, USHRT_MAX); |
| @@ -1204,7 +1201,7 @@ list of keywords. */) | |||
| 1204 | #ifdef DATAGRAM_SOCKETS | 1201 | #ifdef DATAGRAM_SOCKETS |
| 1205 | 1202 | ||
| 1206 | if (NETCONN_P (process)) | 1203 | if (NETCONN_P (process)) |
| 1207 | wait_for_socket_fds (process); | 1204 | wait_for_socket_fds (process, "process-contact"); |
| 1208 | 1205 | ||
| 1209 | if (DATAGRAM_CONN_P (process) | 1206 | if (DATAGRAM_CONN_P (process) |
| 1210 | && (EQ (key, Qt) || EQ (key, QCremote))) | 1207 | && (EQ (key, Qt) || EQ (key, QCremote))) |
| @@ -2436,7 +2433,7 @@ DEFUN ("process-datagram-address", Fprocess_datagram_address, Sprocess_datagram_ | |||
| 2436 | CHECK_PROCESS (process); | 2433 | CHECK_PROCESS (process); |
| 2437 | 2434 | ||
| 2438 | if (NETCONN_P (process)) | 2435 | if (NETCONN_P (process)) |
| 2439 | wait_for_socket_fds (process); | 2436 | wait_for_socket_fds (process, "process-datagram-address"); |
| 2440 | 2437 | ||
| 2441 | if (!DATAGRAM_CONN_P (process)) | 2438 | if (!DATAGRAM_CONN_P (process)) |
| 2442 | return Qnil; | 2439 | return Qnil; |
| @@ -2458,7 +2455,7 @@ Returns nil upon error setting address, ADDRESS otherwise. */) | |||
| 2458 | CHECK_PROCESS (process); | 2455 | CHECK_PROCESS (process); |
| 2459 | 2456 | ||
| 2460 | if (NETCONN_P (process)) | 2457 | if (NETCONN_P (process)) |
| 2461 | wait_for_socket_fds (process); | 2458 | wait_for_socket_fds (process, "set-process-datagram-address"); |
| 2462 | 2459 | ||
| 2463 | if (!DATAGRAM_CONN_P (process)) | 2460 | if (!DATAGRAM_CONN_P (process)) |
| 2464 | return Qnil; | 2461 | return Qnil; |
| @@ -2628,7 +2625,7 @@ OPTION is not a supported option, return nil instead; otherwise return t. */) | |||
| 2628 | if (!NETCONN1_P (p)) | 2625 | if (!NETCONN1_P (p)) |
| 2629 | error ("Process is not a network process"); | 2626 | error ("Process is not a network process"); |
| 2630 | 2627 | ||
| 2631 | wait_for_socket_fds (process); | 2628 | wait_for_socket_fds (process, "set-network-process-option"); |
| 2632 | 2629 | ||
| 2633 | s = p->infd; | 2630 | s = p->infd; |
| 2634 | if (s < 0) | 2631 | if (s < 0) |
| @@ -3332,16 +3329,49 @@ void connect_network_socket (Lisp_Object proc, Lisp_Object ip_addresses) | |||
| 3332 | { | 3329 | { |
| 3333 | Lisp_Object boot, params = p->gnutls_boot_parameters; | 3330 | Lisp_Object boot, params = p->gnutls_boot_parameters; |
| 3334 | 3331 | ||
| 3335 | p->gnutls_boot_parameters = Qnil; | ||
| 3336 | boot = Fgnutls_boot (proc, XCAR (params), XCDR (params)); | 3332 | boot = Fgnutls_boot (proc, XCAR (params), XCDR (params)); |
| 3337 | if (NILP (boot) || STRINGP (boot)) { | 3333 | p->gnutls_boot_parameters = Qnil; |
| 3338 | deactivate_process (proc); | 3334 | |
| 3339 | if (NILP (boot)) | 3335 | if (NILP (boot) || STRINGP (boot)) |
| 3340 | pset_status (p, list2 (Qfailed, | 3336 | { |
| 3341 | build_string ("TLS negotiation failed"))); | 3337 | deactivate_process (proc); |
| 3342 | else | 3338 | if (NILP (boot)) |
| 3343 | pset_status (p, list2 (Qfailed, boot)); | 3339 | pset_status (p, list2 (Qfailed, |
| 3344 | } | 3340 | build_string ("TLS negotiation failed"))); |
| 3341 | else | ||
| 3342 | pset_status (p, list2 (Qfailed, boot)); | ||
| 3343 | } | ||
| 3344 | else | ||
| 3345 | { | ||
| 3346 | Lisp_Object result = Qt; | ||
| 3347 | |||
| 3348 | if (!NILP (Ffboundp (Qnsm_verify_connection))) | ||
| 3349 | result = call3 (Qnsm_verify_connection, | ||
| 3350 | proc, | ||
| 3351 | Fplist_get (contact, QChost), | ||
| 3352 | Fplist_get (contact, QCservice)); | ||
| 3353 | |||
| 3354 | if (NILP (result)) | ||
| 3355 | { | ||
| 3356 | pset_status (p, list2 (Qfailed, | ||
| 3357 | build_string ("The Network Security Manager stopped the connections"))); | ||
| 3358 | deactivate_process (proc); | ||
| 3359 | } | ||
| 3360 | else | ||
| 3361 | { | ||
| 3362 | /* If we cleared the connection wait mask before we did | ||
| 3363 | the TLS setup, then we have to say that the process | ||
| 3364 | is finally "open" here. */ | ||
| 3365 | if (! FD_ISSET (p->outfd, &connect_wait_mask)) | ||
| 3366 | { | ||
| 3367 | pset_status (p, Qrun); | ||
| 3368 | /* Execute the sentinel here. If we had relied on | ||
| 3369 | status_notify to do it later, it will read input | ||
| 3370 | from the process before calling the sentinel. */ | ||
| 3371 | exec_sentinel (proc, build_string ("open\n")); | ||
| 3372 | } | ||
| 3373 | } | ||
| 3374 | } | ||
| 3345 | } | 3375 | } |
| 3346 | #endif | 3376 | #endif |
| 3347 | 3377 | ||
| @@ -4670,27 +4700,36 @@ check_for_dns (Lisp_Object proc) | |||
| 4670 | #endif /* HAVE_GETADDRINFO_A */ | 4700 | #endif /* HAVE_GETADDRINFO_A */ |
| 4671 | 4701 | ||
| 4672 | static void | 4702 | static void |
| 4673 | wait_for_socket_fds (Lisp_Object process) | 4703 | wait_for_socket_fds (Lisp_Object process, char *name) |
| 4674 | { | 4704 | { |
| 4675 | while (XPROCESS (process)->infd < 0 && | 4705 | while (XPROCESS (process)->infd < 0 && |
| 4676 | EQ (XPROCESS (process)->status, Qconnect)) | 4706 | EQ (XPROCESS (process)->status, Qconnect)) |
| 4677 | wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0); | 4707 | { |
| 4708 | printf("Waiting for socket from %s...\n", name); | ||
| 4709 | wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0); | ||
| 4710 | } | ||
| 4678 | } | 4711 | } |
| 4679 | 4712 | ||
| 4680 | static void | 4713 | static void |
| 4681 | wait_while_connecting (Lisp_Object process) | 4714 | wait_while_connecting (Lisp_Object process) |
| 4682 | { | 4715 | { |
| 4683 | while (EQ (XPROCESS (process)->status, Qconnect)) | 4716 | while (EQ (XPROCESS (process)->status, Qconnect)) |
| 4684 | wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0); | 4717 | { |
| 4718 | printf("Waiting for connection...\n"); | ||
| 4719 | wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0); | ||
| 4720 | } | ||
| 4685 | } | 4721 | } |
| 4686 | 4722 | ||
| 4687 | static void | 4723 | static void |
| 4688 | wait_for_tls_negotiation (Lisp_Object process) | 4724 | wait_for_tls_negotiation (Lisp_Object process) |
| 4689 | { | 4725 | { |
| 4690 | #ifdef HAVE_GNUTLS | 4726 | #ifdef HAVE_GNUTLS |
| 4691 | while (EQ (XPROCESS (process)->status, Qrun) && | 4727 | while (EQ (XPROCESS (process)->status, Qconnect) && |
| 4692 | !NILP (XPROCESS (process)->gnutls_boot_parameters)) | 4728 | !NILP (XPROCESS (process)->gnutls_boot_parameters)) |
| 4693 | wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0); | 4729 | { |
| 4730 | printf("Waiting for TLS...\n"); | ||
| 4731 | wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0); | ||
| 4732 | } | ||
| 4694 | #endif | 4733 | #endif |
| 4695 | } | 4734 | } |
| 4696 | 4735 | ||
| @@ -5486,11 +5525,15 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5486 | } | 5525 | } |
| 5487 | else | 5526 | else |
| 5488 | { | 5527 | { |
| 5489 | pset_status (p, Qrun); | 5528 | if (NILP (p->gnutls_boot_parameters)) |
| 5490 | /* Execute the sentinel here. If we had relied on | 5529 | { |
| 5491 | status_notify to do it later, it will read input | 5530 | pset_status (p, Qrun); |
| 5492 | from the process before calling the sentinel. */ | 5531 | /* Execute the sentinel here. If we had relied on |
| 5493 | exec_sentinel (proc, build_string ("open\n")); | 5532 | status_notify to do it later, it will read input |
| 5533 | from the process before calling the sentinel. */ | ||
| 5534 | exec_sentinel (proc, build_string ("open\n")); | ||
| 5535 | } | ||
| 5536 | |||
| 5494 | if (0 <= p->infd && !EQ (p->filter, Qt) | 5537 | if (0 <= p->infd && !EQ (p->filter, Qt) |
| 5495 | && !EQ (p->command, Qt)) | 5538 | && !EQ (p->command, Qt)) |
| 5496 | { | 5539 | { |
| @@ -5947,6 +5990,11 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len, | |||
| 5947 | ssize_t rv; | 5990 | ssize_t rv; |
| 5948 | struct coding_system *coding; | 5991 | struct coding_system *coding; |
| 5949 | 5992 | ||
| 5993 | if (NETCONN_P (proc)) { | ||
| 5994 | wait_while_connecting (proc); | ||
| 5995 | wait_for_tls_negotiation (proc); | ||
| 5996 | } | ||
| 5997 | |||
| 5950 | if (p->raw_status_new) | 5998 | if (p->raw_status_new) |
| 5951 | update_status (p); | 5999 | update_status (p); |
| 5952 | if (! EQ (p->status, Qrun)) | 6000 | if (! EQ (p->status, Qrun)) |
| @@ -6201,11 +6249,6 @@ Output from processes can arrive in between bunches. */) | |||
| 6201 | CHECK_STRING (string); | 6249 | CHECK_STRING (string); |
| 6202 | proc = get_process (process); | 6250 | proc = get_process (process); |
| 6203 | 6251 | ||
| 6204 | if (NETCONN_P (proc)) { | ||
| 6205 | wait_while_connecting (proc); | ||
| 6206 | wait_for_tls_negotiation (proc); | ||
| 6207 | } | ||
| 6208 | |||
| 6209 | send_process (proc, SSDATA (string), | 6252 | send_process (proc, SSDATA (string), |
| 6210 | SBYTES (string), string); | 6253 | SBYTES (string), string); |
| 6211 | return Qnil; | 6254 | return Qnil; |
| @@ -7081,7 +7124,7 @@ encode subprocess input. */) | |||
| 7081 | CHECK_PROCESS (process); | 7124 | CHECK_PROCESS (process); |
| 7082 | 7125 | ||
| 7083 | if (NETCONN_P (process)) | 7126 | if (NETCONN_P (process)) |
| 7084 | wait_for_socket_fds (process); | 7127 | wait_for_socket_fds (process, "set-process-coding-system"); |
| 7085 | 7128 | ||
| 7086 | p = XPROCESS (process); | 7129 | p = XPROCESS (process); |
| 7087 | 7130 | ||
| @@ -7123,7 +7166,7 @@ suppressed. */) | |||
| 7123 | CHECK_PROCESS (process); | 7166 | CHECK_PROCESS (process); |
| 7124 | 7167 | ||
| 7125 | if (NETCONN_P (process)) | 7168 | if (NETCONN_P (process)) |
| 7126 | wait_for_socket_fds (process); | 7169 | wait_for_socket_fds (process, "set-process-filter-multibyte"); |
| 7127 | 7170 | ||
| 7128 | p = XPROCESS (process); | 7171 | p = XPROCESS (process); |
| 7129 | if (NILP (flag)) | 7172 | if (NILP (flag)) |
| @@ -7817,6 +7860,7 @@ syms_of_process (void) | |||
| 7817 | DEFSYM (QCnowait, ":nowait"); | 7860 | DEFSYM (QCnowait, ":nowait"); |
| 7818 | DEFSYM (QCsentinel, ":sentinel"); | 7861 | DEFSYM (QCsentinel, ":sentinel"); |
| 7819 | DEFSYM (QCtls_parameters, ":tls-parameters"); | 7862 | DEFSYM (QCtls_parameters, ":tls-parameters"); |
| 7863 | DEFSYM (Qnsm_verify_connection, "nsm-verify-connection"); | ||
| 7820 | DEFSYM (QClog, ":log"); | 7864 | DEFSYM (QClog, ":log"); |
| 7821 | DEFSYM (QCnoquery, ":noquery"); | 7865 | DEFSYM (QCnoquery, ":noquery"); |
| 7822 | DEFSYM (QCstop, ":stop"); | 7866 | DEFSYM (QCstop, ":stop"); |