summaryrefslogtreecommitdiff
path: root/serverloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'serverloop.c')
-rw-r--r--serverloop.c82
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 "