=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/mux.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- src/usr.bin/ssh/mux.c 2008/06/12 15:19:17 1.4 +++ src/usr.bin/ssh/mux.c 2008/06/13 00:16:49 1.5 @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.4 2008/06/12 15:19:17 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.5 2008/06/13 00:16:49 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -132,10 +132,16 @@ old_umask = umask(0177); if (bind(muxserver_sock, (struct sockaddr *)&addr, addr.sun_len) == -1) { muxserver_sock = -1; - if (errno == EINVAL || errno == EADDRINUSE) - fatal("ControlSocket %s already exists", - options.control_path); - else + if (errno == EINVAL || errno == EADDRINUSE) { + error("ControlSocket %s already exists, " + "disabling multiplexing", options.control_path); + close(muxserver_sock); + muxserver_sock = -1; + xfree(options.control_path); + options.control_path = NULL; + options.control_master = SSHCTL_MASTER_NO; + return; + } else fatal("%s bind(): %s", __func__, strerror(errno)); } umask(old_umask); @@ -488,7 +494,7 @@ Buffer m; char *term; extern char **environ; - u_int flags; + u_int allowed, flags; if (muxclient_command == 0) muxclient_command = SSHMUX_COMMAND_OPEN; @@ -559,17 +565,38 @@ /* Send our command to server */ buffer_put_int(&m, muxclient_command); buffer_put_int(&m, flags); - if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) - fatal("%s: msg_send", __func__); + if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) { + error("%s: msg_send", __func__); + muxerr: + close(sock); + buffer_free(&m); + if (muxclient_command != SSHMUX_COMMAND_OPEN) + cleanup_exit(255); + logit("Falling back to non-multiplexed connection"); + xfree(options.control_path); + options.control_path = NULL; + options.control_master = SSHCTL_MASTER_NO; + return; + } buffer_clear(&m); /* Get authorisation status and PID of controlee */ - if (ssh_msg_recv(sock, &m) == -1) - fatal("%s: msg_recv", __func__); - if (buffer_get_char(&m) != SSHMUX_VER) - fatal("%s: wrong version", __func__); - if (buffer_get_int(&m) != 1) - fatal("Connection to master denied"); + if (ssh_msg_recv(sock, &m) == -1) { + error("%s: msg_recv", __func__); + goto muxerr; + } + if (buffer_get_char(&m) != SSHMUX_VER) { + error("%s: wrong version", __func__); + goto muxerr; + } + if (buffer_get_int_ret(&allowed, &m) != 0) { + error("%s: bad server reply", __func__); + goto muxerr; + } + if (allowed != 1) { + error("Connection to master denied"); + goto muxerr; + } muxserver_pid = buffer_get_int(&m); buffer_clear(&m); @@ -613,13 +640,22 @@ fatal("unrecognised muxclient_command %d", muxclient_command); } - if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) - fatal("%s: msg_send", __func__); + if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) { + error("%s: msg_send", __func__); + goto muxerr; + } if (mm_send_fd(sock, STDIN_FILENO) == -1 || mm_send_fd(sock, STDOUT_FILENO) == -1 || - mm_send_fd(sock, STDERR_FILENO) == -1) - fatal("%s: send fds failed", __func__); + mm_send_fd(sock, STDERR_FILENO) == -1) { + error("%s: send fds failed", __func__); + goto muxerr; + } + + /* + * Mux errors are non-recoverable from this point as the master + * has ownership of the session now. + */ /* Wait for reply, so master has a chance to gather ttymodes */ buffer_clear(&m);