(plist-get parameters :nowait))
(open-tls-stream name buffer host service)))
(eoc (plist-get parameters :end-of-command)))
- ;; Check certificate validity etc.
- (when (and (gnutls-available-p) stream)
- (setq stream (nsm-verify-connection stream host service)))
- (if (null stream)
- (list nil nil nil 'plain)
- ;; If we're using tls.el, we have to delete the output from
- ;; openssl/gnutls-cli.
- (when (and (not (gnutls-available-p))
- eoc)
- (network-stream-get-response stream start eoc)
- (goto-char (point-min))
- (when (re-search-forward eoc nil t)
- (goto-char (match-beginning 0))
- (delete-region (point-min) (line-beginning-position))))
- (let ((capability-command (plist-get parameters :capability-command))
- (eo-capa (or (plist-get parameters :end-of-capability)
- eoc)))
- (list stream
- (network-stream-get-response stream start eoc)
- (network-stream-command stream capability-command eo-capa)
- 'tls))))))
+ (if (plist-get parameters :nowait)
+ (list stream nil nil 'tls)
+ ;; Check certificate validity etc.
+ (when (and (gnutls-available-p) stream)
+ (setq stream (nsm-verify-connection stream host service)))
+ (if (null stream)
+ (list nil nil nil 'plain)
+ ;; If we're using tls.el, we have to delete the output from
+ ;; openssl/gnutls-cli.
+ (when (and (not (gnutls-available-p))
+ eoc)
+ (network-stream-get-response stream start eoc)
+ (goto-char (point-min))
+ (when (re-search-forward eoc nil t)
+ (goto-char (match-beginning 0))
+ (delete-region (point-min) (line-beginning-position))))
+ (let ((capability-command (plist-get parameters :capability-command))
+ (eo-capa (or (plist-get parameters :end-of-capability)
+ eoc)))
+ (list stream
+ (network-stream-get-response stream start eoc)
+ (network-stream-command stream capability-command eo-capa)
+ 'tls)))))))
(defun network-stream-open-shell (name buffer host service parameters)
(require 'format-spec)
#ifdef HAVE_GETADDRINFO_A
/* Pending DNS requests. */
static Lisp_Object dns_processes;
-static void wait_for_socket_fds (Lisp_Object process);
+static void wait_for_socket_fds (Lisp_Object process, char *name);
#endif
/* Alist of elements (NAME . PROCESS). */
CHECK_PROCESS (process);
- if (NETCONN_P (process))
- wait_for_socket_fds (process);
-
p = XPROCESS (process);
/* Don't signal an error if the process's input file descriptor
CHECK_PROCESS (process);
if (NETCONN_P (process))
- wait_for_socket_fds (process);
+ wait_for_socket_fds (process, "set-process-window-size");
/* All known platforms store window sizes as 'unsigned short'. */
CHECK_RANGED_INTEGER (height, 0, USHRT_MAX);
#ifdef DATAGRAM_SOCKETS
if (NETCONN_P (process))
- wait_for_socket_fds (process);
+ wait_for_socket_fds (process, "process-contact");
if (DATAGRAM_CONN_P (process)
&& (EQ (key, Qt) || EQ (key, QCremote)))
CHECK_PROCESS (process);
if (NETCONN_P (process))
- wait_for_socket_fds (process);
+ wait_for_socket_fds (process, "process-datagram-address");
if (!DATAGRAM_CONN_P (process))
return Qnil;
CHECK_PROCESS (process);
if (NETCONN_P (process))
- wait_for_socket_fds (process);
+ wait_for_socket_fds (process, "set-process-datagram-address");
if (!DATAGRAM_CONN_P (process))
return Qnil;
if (!NETCONN1_P (p))
error ("Process is not a network process");
- wait_for_socket_fds (process);
+ wait_for_socket_fds (process, "set-network-process-option");
s = p->infd;
if (s < 0)
{
Lisp_Object boot, params = p->gnutls_boot_parameters;
- p->gnutls_boot_parameters = Qnil;
boot = Fgnutls_boot (proc, XCAR (params), XCDR (params));
- if (NILP (boot) || STRINGP (boot)) {
- deactivate_process (proc);
- if (NILP (boot))
- pset_status (p, list2 (Qfailed,
- build_string ("TLS negotiation failed")));
- else
- pset_status (p, list2 (Qfailed, boot));
- }
+ p->gnutls_boot_parameters = Qnil;
+
+ if (NILP (boot) || STRINGP (boot))
+ {
+ deactivate_process (proc);
+ if (NILP (boot))
+ pset_status (p, list2 (Qfailed,
+ build_string ("TLS negotiation failed")));
+ else
+ pset_status (p, list2 (Qfailed, boot));
+ }
+ else
+ {
+ Lisp_Object result = Qt;
+
+ if (!NILP (Ffboundp (Qnsm_verify_connection)))
+ result = call3 (Qnsm_verify_connection,
+ proc,
+ Fplist_get (contact, QChost),
+ Fplist_get (contact, QCservice));
+
+ if (NILP (result))
+ {
+ pset_status (p, list2 (Qfailed,
+ build_string ("The Network Security Manager stopped the connections")));
+ deactivate_process (proc);
+ }
+ else
+ {
+ /* If we cleared the connection wait mask before we did
+ the TLS setup, then we have to say that the process
+ is finally "open" here. */
+ if (! FD_ISSET (p->outfd, &connect_wait_mask))
+ {
+ pset_status (p, Qrun);
+ /* Execute the sentinel here. If we had relied on
+ status_notify to do it later, it will read input
+ from the process before calling the sentinel. */
+ exec_sentinel (proc, build_string ("open\n"));
+ }
+ }
+ }
}
#endif
#endif /* HAVE_GETADDRINFO_A */
static void
-wait_for_socket_fds (Lisp_Object process)
+wait_for_socket_fds (Lisp_Object process, char *name)
{
while (XPROCESS (process)->infd < 0 &&
EQ (XPROCESS (process)->status, Qconnect))
- wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0);
+ {
+ printf("Waiting for socket from %s...\n", name);
+ wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0);
+ }
}
static void
wait_while_connecting (Lisp_Object process)
{
while (EQ (XPROCESS (process)->status, Qconnect))
- wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0);
+ {
+ printf("Waiting for connection...\n");
+ wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0);
+ }
}
static void
wait_for_tls_negotiation (Lisp_Object process)
{
#ifdef HAVE_GNUTLS
- while (EQ (XPROCESS (process)->status, Qrun) &&
+ while (EQ (XPROCESS (process)->status, Qconnect) &&
!NILP (XPROCESS (process)->gnutls_boot_parameters))
- wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0);
+ {
+ printf("Waiting for TLS...\n");
+ wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0);
+ }
#endif
}
}
else
{
- pset_status (p, Qrun);
- /* Execute the sentinel here. If we had relied on
- status_notify to do it later, it will read input
- from the process before calling the sentinel. */
- exec_sentinel (proc, build_string ("open\n"));
+ if (NILP (p->gnutls_boot_parameters))
+ {
+ pset_status (p, Qrun);
+ /* Execute the sentinel here. If we had relied on
+ status_notify to do it later, it will read input
+ from the process before calling the sentinel. */
+ exec_sentinel (proc, build_string ("open\n"));
+ }
+
if (0 <= p->infd && !EQ (p->filter, Qt)
&& !EQ (p->command, Qt))
{
ssize_t rv;
struct coding_system *coding;
+ if (NETCONN_P (proc)) {
+ wait_while_connecting (proc);
+ wait_for_tls_negotiation (proc);
+ }
+
if (p->raw_status_new)
update_status (p);
if (! EQ (p->status, Qrun))
CHECK_STRING (string);
proc = get_process (process);
- if (NETCONN_P (proc)) {
- wait_while_connecting (proc);
- wait_for_tls_negotiation (proc);
- }
-
send_process (proc, SSDATA (string),
SBYTES (string), string);
return Qnil;
CHECK_PROCESS (process);
if (NETCONN_P (process))
- wait_for_socket_fds (process);
+ wait_for_socket_fds (process, "set-process-coding-system");
p = XPROCESS (process);
CHECK_PROCESS (process);
if (NETCONN_P (process))
- wait_for_socket_fds (process);
+ wait_for_socket_fds (process, "set-process-filter-multibyte");
p = XPROCESS (process);
if (NILP (flag))
DEFSYM (QCnowait, ":nowait");
DEFSYM (QCsentinel, ":sentinel");
DEFSYM (QCtls_parameters, ":tls-parameters");
+ DEFSYM (Qnsm_verify_connection, "nsm-verify-connection");
DEFSYM (QClog, ":log");
DEFSYM (QCnoquery, ":noquery");
DEFSYM (QCstop, ":stop");