diff options
Diffstat (limited to 'serverloop.c')
| -rw-r--r-- | serverloop.c | 82 |
1 files changed, 55 insertions, 27 deletions
diff --git a/serverloop.c b/serverloop.c index 24bbae322c348..d6fe24cc1dbb0 100644 --- a/serverloop.c +++ b/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.198 2017/09/12 06:35:32 djm Exp $ */ +/* $OpenBSD: serverloop.c,v 1.205 2018/03/03 03:15:51 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -82,6 +82,7 @@ extern ServerOptions options; /* XXX */ extern Authctxt *the_authctxt; +extern struct sshauthopt *auth_opts; extern int use_privsep; static int no_more_sessions = 0; /* Disallow further sessions. */ @@ -99,6 +100,9 @@ static volatile sig_atomic_t received_sigterm = 0; /* prototypes */ static void server_init_dispatch(void); +/* requested tunnel forwarding interface(s), shared with session.c */ +char *tun_fwd_ifnames = NULL; + /* * we write to this pipe if a SIGCHLD is caught in order to avoid * the race between select() and child_terminated @@ -150,9 +154,6 @@ sigchld_handler(int sig) { int save_errno = errno; child_terminated = 1; -#ifndef _UNICOS - mysignal(SIGCHLD, sigchld_handler); -#endif notify_parent(); errno = save_errno; } @@ -168,10 +169,12 @@ static void client_alive_check(struct ssh *ssh) { int channel_id; + char remote_id[512]; /* timeout, check to see how many we have had */ if (packet_inc_alive_timeouts() > options.client_alive_count_max) { - logit("Timeout, client not responding."); + sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); + logit("Timeout, client not responding from %s", remote_id); cleanup_exit(255); } @@ -371,7 +374,7 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt) debug("Entering interactive session for SSH2."); - mysignal(SIGCHLD, sigchld_handler); + signal(SIGCHLD, sigchld_handler); child_terminated = 0; connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); @@ -454,12 +457,13 @@ server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg) originator_port = packet_get_int(); packet_check_eom(); - debug("server_request_direct_tcpip: originator %s port %d, target %s " - "port %d", originator, originator_port, target, target_port); + debug("%s: originator %s port %d, target %s port %d", __func__, + originator, originator_port, target, target_port); /* XXX fine grained permissions */ if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && - !no_port_forwarding_flag && !options.disable_forwarding) { + auth_opts->permit_port_forwarding_flag && + !options.disable_forwarding) { c = channel_connect_to_port(ssh, target, target_port, "direct-tcpip", "direct-tcpip", reason, errmsg); } else { @@ -485,20 +489,20 @@ server_request_direct_streamlocal(struct ssh *ssh) struct passwd *pw = the_authctxt->pw; if (pw == NULL || !the_authctxt->valid) - fatal("server_input_global_request: no/invalid user"); + fatal("%s: no/invalid user", __func__); target = packet_get_string(NULL); originator = packet_get_string(NULL); originator_port = packet_get_int(); packet_check_eom(); - debug("server_request_direct_streamlocal: originator %s port %d, target %s", + debug("%s: originator %s port %d, target %s", __func__, originator, originator_port, target); /* XXX fine grained permissions */ if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && - !no_port_forwarding_flag && !options.disable_forwarding && - (pw->pw_uid == 0 || use_privsep)) { + auth_opts->permit_port_forwarding_flag && + !options.disable_forwarding && (pw->pw_uid == 0 || use_privsep)) { c = channel_connect_to_path(ssh, target, "direct-streamlocal@openssh.com", "direct-streamlocal"); } else { @@ -517,8 +521,8 @@ static Channel * server_request_tun(struct ssh *ssh) { Channel *c = NULL; - int mode, tun; - int sock; + int mode, tun, sock; + char *tmp, *ifname = NULL; mode = packet_get_int(); switch (mode) { @@ -536,14 +540,16 @@ server_request_tun(struct ssh *ssh) } tun = packet_get_int(); - if (forced_tun_device != -1) { - if (tun != SSH_TUNID_ANY && forced_tun_device != tun) + if (auth_opts->force_tun_device != -1) { + if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != tun) goto done; - tun = forced_tun_device; + tun = auth_opts->force_tun_device; } - sock = tun_open(tun, mode); + sock = tun_open(tun, mode, &ifname); if (sock < 0) goto done; + debug("Tunnel forwarding using interface %s", ifname); + c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); c->datagram = 1; @@ -553,6 +559,19 @@ server_request_tun(struct ssh *ssh) sys_tun_outfilter, NULL, NULL); #endif + /* + * Update the list of names exposed to the session + * XXX remove these if the tunnels are closed (won't matter + * much if they are already in the environment though) + */ + tmp = tun_fwd_ifnames; + xasprintf(&tun_fwd_ifnames, "%s%s%s", + tun_fwd_ifnames == NULL ? "" : tun_fwd_ifnames, + tun_fwd_ifnames == NULL ? "" : ",", + ifname); + free(tmp); + free(ifname); + done: if (c == NULL) packet_send_debug("Failed to open the tunnel device."); @@ -635,10 +654,8 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(rchan); packet_put_int(reason); - if (!(datafellows & SSH_BUG_OPENFAILURE)) { - packet_put_cstring(errmsg ? errmsg : "open failed"); - packet_put_cstring(""); - } + packet_put_cstring(errmsg ? errmsg : "open failed"); + packet_put_cstring(""); packet_send(); } free(ctype); @@ -651,7 +668,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) struct sshbuf *resp = NULL; struct sshbuf *sigbuf = NULL; struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; - int r, ndx, success = 0; + int r, ndx, kexsigtype, use_kexsigtype, success = 0; const u_char *blob; u_char *sig = 0; size_t blen, slen; @@ -659,6 +676,8 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) fatal("%s: sshbuf_new", __func__); + kexsigtype = sshkey_type_plain( + sshkey_type_from_name(ssh->kex->hostkey_alg)); while (ssh_packet_remaining(ssh) > 0) { sshkey_free(key); key = NULL; @@ -689,13 +708,20 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) sshbuf_reset(sigbuf); free(sig); sig = NULL; + /* + * For RSA keys, prefer to use the signature type negotiated + * during KEX to the default (SHA1). + */ + use_kexsigtype = kexsigtype == KEY_RSA && + sshkey_type_plain(key->type) == KEY_RSA; if ((r = sshbuf_put_cstring(sigbuf, "hostkeys-prove-00@openssh.com")) != 0 || (r = sshbuf_put_string(sigbuf, ssh->kex->session_id, ssh->kex->session_id_len)) != 0 || (r = sshkey_puts(key, sigbuf)) != 0 || (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen, - sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), NULL, 0)) != 0 || + sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), + use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0)) != 0 || (r = sshbuf_put_string(resp, sig, slen)) != 0) { error("%s: couldn't prepare signature: %s", __func__, ssh_err(r)); @@ -742,7 +768,8 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) /* check permissions */ if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || - no_port_forwarding_flag || options.disable_forwarding || + !auth_opts->permit_port_forwarding_flag || + options.disable_forwarding || (!want_reply && fwd.listen_port == 0) || (fwd.listen_port != 0 && !bind_permitted(fwd.listen_port, pw->pw_uid))) { @@ -780,7 +807,8 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) /* check permissions */ if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0 - || no_port_forwarding_flag || options.disable_forwarding || + || !auth_opts->permit_port_forwarding_flag || + options.disable_forwarding || (pw->pw_uid != 0 && !use_privsep)) { success = 0; packet_send_debug("Server has disabled " |
