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 24bbae322..d6fe24cc1 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: serverloop.c,v 1.198 2017/09/12 06:35:32 djm Exp $ */ | 1 | /* $OpenBSD: serverloop.c,v 1.205 2018/03/03 03:15:51 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -82,6 +82,7 @@ extern ServerOptions options; | |||
82 | 82 | ||
83 | /* XXX */ | 83 | /* XXX */ |
84 | extern Authctxt *the_authctxt; | 84 | extern Authctxt *the_authctxt; |
85 | extern struct sshauthopt *auth_opts; | ||
85 | extern int use_privsep; | 86 | extern int use_privsep; |
86 | 87 | ||
87 | static int no_more_sessions = 0; /* Disallow further sessions. */ | 88 | static int no_more_sessions = 0; /* Disallow further sessions. */ |
@@ -99,6 +100,9 @@ static volatile sig_atomic_t received_sigterm = 0; | |||
99 | /* prototypes */ | 100 | /* prototypes */ |
100 | static void server_init_dispatch(void); | 101 | static void server_init_dispatch(void); |
101 | 102 | ||
103 | /* requested tunnel forwarding interface(s), shared with session.c */ | ||
104 | char *tun_fwd_ifnames = NULL; | ||
105 | |||
102 | /* | 106 | /* |
103 | * we write to this pipe if a SIGCHLD is caught in order to avoid | 107 | * we write to this pipe if a SIGCHLD is caught in order to avoid |
104 | * the race between select() and child_terminated | 108 | * the race between select() and child_terminated |
@@ -150,9 +154,6 @@ sigchld_handler(int sig) | |||
150 | { | 154 | { |
151 | int save_errno = errno; | 155 | int save_errno = errno; |
152 | child_terminated = 1; | 156 | child_terminated = 1; |
153 | #ifndef _UNICOS | ||
154 | mysignal(SIGCHLD, sigchld_handler); | ||
155 | #endif | ||
156 | notify_parent(); | 157 | notify_parent(); |
157 | errno = save_errno; | 158 | errno = save_errno; |
158 | } | 159 | } |
@@ -168,10 +169,12 @@ static void | |||
168 | client_alive_check(struct ssh *ssh) | 169 | client_alive_check(struct ssh *ssh) |
169 | { | 170 | { |
170 | int channel_id; | 171 | int channel_id; |
172 | char remote_id[512]; | ||
171 | 173 | ||
172 | /* timeout, check to see how many we have had */ | 174 | /* timeout, check to see how many we have had */ |
173 | if (packet_inc_alive_timeouts() > options.client_alive_count_max) { | 175 | if (packet_inc_alive_timeouts() > options.client_alive_count_max) { |
174 | logit("Timeout, client not responding."); | 176 | sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); |
177 | logit("Timeout, client not responding from %s", remote_id); | ||
175 | cleanup_exit(255); | 178 | cleanup_exit(255); |
176 | } | 179 | } |
177 | 180 | ||
@@ -371,7 +374,7 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt) | |||
371 | 374 | ||
372 | debug("Entering interactive session for SSH2."); | 375 | debug("Entering interactive session for SSH2."); |
373 | 376 | ||
374 | mysignal(SIGCHLD, sigchld_handler); | 377 | signal(SIGCHLD, sigchld_handler); |
375 | child_terminated = 0; | 378 | child_terminated = 0; |
376 | connection_in = packet_get_connection_in(); | 379 | connection_in = packet_get_connection_in(); |
377 | connection_out = packet_get_connection_out(); | 380 | connection_out = packet_get_connection_out(); |
@@ -454,12 +457,13 @@ server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg) | |||
454 | originator_port = packet_get_int(); | 457 | originator_port = packet_get_int(); |
455 | packet_check_eom(); | 458 | packet_check_eom(); |
456 | 459 | ||
457 | debug("server_request_direct_tcpip: originator %s port %d, target %s " | 460 | debug("%s: originator %s port %d, target %s port %d", __func__, |
458 | "port %d", originator, originator_port, target, target_port); | 461 | originator, originator_port, target, target_port); |
459 | 462 | ||
460 | /* XXX fine grained permissions */ | 463 | /* XXX fine grained permissions */ |
461 | if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && | 464 | if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && |
462 | !no_port_forwarding_flag && !options.disable_forwarding) { | 465 | auth_opts->permit_port_forwarding_flag && |
466 | !options.disable_forwarding) { | ||
463 | c = channel_connect_to_port(ssh, target, target_port, | 467 | c = channel_connect_to_port(ssh, target, target_port, |
464 | "direct-tcpip", "direct-tcpip", reason, errmsg); | 468 | "direct-tcpip", "direct-tcpip", reason, errmsg); |
465 | } else { | 469 | } else { |
@@ -485,20 +489,20 @@ server_request_direct_streamlocal(struct ssh *ssh) | |||
485 | struct passwd *pw = the_authctxt->pw; | 489 | struct passwd *pw = the_authctxt->pw; |
486 | 490 | ||
487 | if (pw == NULL || !the_authctxt->valid) | 491 | if (pw == NULL || !the_authctxt->valid) |
488 | fatal("server_input_global_request: no/invalid user"); | 492 | fatal("%s: no/invalid user", __func__); |
489 | 493 | ||
490 | target = packet_get_string(NULL); | 494 | target = packet_get_string(NULL); |
491 | originator = packet_get_string(NULL); | 495 | originator = packet_get_string(NULL); |
492 | originator_port = packet_get_int(); | 496 | originator_port = packet_get_int(); |
493 | packet_check_eom(); | 497 | packet_check_eom(); |
494 | 498 | ||
495 | debug("server_request_direct_streamlocal: originator %s port %d, target %s", | 499 | debug("%s: originator %s port %d, target %s", __func__, |
496 | originator, originator_port, target); | 500 | originator, originator_port, target); |
497 | 501 | ||
498 | /* XXX fine grained permissions */ | 502 | /* XXX fine grained permissions */ |
499 | if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && | 503 | if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && |
500 | !no_port_forwarding_flag && !options.disable_forwarding && | 504 | auth_opts->permit_port_forwarding_flag && |
501 | (pw->pw_uid == 0 || use_privsep)) { | 505 | !options.disable_forwarding && (pw->pw_uid == 0 || use_privsep)) { |
502 | c = channel_connect_to_path(ssh, target, | 506 | c = channel_connect_to_path(ssh, target, |
503 | "direct-streamlocal@openssh.com", "direct-streamlocal"); | 507 | "direct-streamlocal@openssh.com", "direct-streamlocal"); |
504 | } else { | 508 | } else { |
@@ -517,8 +521,8 @@ static Channel * | |||
517 | server_request_tun(struct ssh *ssh) | 521 | server_request_tun(struct ssh *ssh) |
518 | { | 522 | { |
519 | Channel *c = NULL; | 523 | Channel *c = NULL; |
520 | int mode, tun; | 524 | int mode, tun, sock; |
521 | int sock; | 525 | char *tmp, *ifname = NULL; |
522 | 526 | ||
523 | mode = packet_get_int(); | 527 | mode = packet_get_int(); |
524 | switch (mode) { | 528 | switch (mode) { |
@@ -536,14 +540,16 @@ server_request_tun(struct ssh *ssh) | |||
536 | } | 540 | } |
537 | 541 | ||
538 | tun = packet_get_int(); | 542 | tun = packet_get_int(); |
539 | if (forced_tun_device != -1) { | 543 | if (auth_opts->force_tun_device != -1) { |
540 | if (tun != SSH_TUNID_ANY && forced_tun_device != tun) | 544 | if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != tun) |
541 | goto done; | 545 | goto done; |
542 | tun = forced_tun_device; | 546 | tun = auth_opts->force_tun_device; |
543 | } | 547 | } |
544 | sock = tun_open(tun, mode); | 548 | sock = tun_open(tun, mode, &ifname); |
545 | if (sock < 0) | 549 | if (sock < 0) |
546 | goto done; | 550 | goto done; |
551 | debug("Tunnel forwarding using interface %s", ifname); | ||
552 | |||
547 | c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1, | 553 | c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1, |
548 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); | 554 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); |
549 | c->datagram = 1; | 555 | c->datagram = 1; |
@@ -553,6 +559,19 @@ server_request_tun(struct ssh *ssh) | |||
553 | sys_tun_outfilter, NULL, NULL); | 559 | sys_tun_outfilter, NULL, NULL); |
554 | #endif | 560 | #endif |
555 | 561 | ||
562 | /* | ||
563 | * Update the list of names exposed to the session | ||
564 | * XXX remove these if the tunnels are closed (won't matter | ||
565 | * much if they are already in the environment though) | ||
566 | */ | ||
567 | tmp = tun_fwd_ifnames; | ||
568 | xasprintf(&tun_fwd_ifnames, "%s%s%s", | ||
569 | tun_fwd_ifnames == NULL ? "" : tun_fwd_ifnames, | ||
570 | tun_fwd_ifnames == NULL ? "" : ",", | ||
571 | ifname); | ||
572 | free(tmp); | ||
573 | free(ifname); | ||
574 | |||
556 | done: | 575 | done: |
557 | if (c == NULL) | 576 | if (c == NULL) |
558 | packet_send_debug("Failed to open the tunnel device."); | 577 | 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) | |||
635 | packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); | 654 | packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); |
636 | packet_put_int(rchan); | 655 | packet_put_int(rchan); |
637 | packet_put_int(reason); | 656 | packet_put_int(reason); |
638 | if (!(datafellows & SSH_BUG_OPENFAILURE)) { | 657 | packet_put_cstring(errmsg ? errmsg : "open failed"); |
639 | packet_put_cstring(errmsg ? errmsg : "open failed"); | 658 | packet_put_cstring(""); |
640 | packet_put_cstring(""); | ||
641 | } | ||
642 | packet_send(); | 659 | packet_send(); |
643 | } | 660 | } |
644 | free(ctype); | 661 | free(ctype); |
@@ -651,7 +668,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) | |||
651 | struct sshbuf *resp = NULL; | 668 | struct sshbuf *resp = NULL; |
652 | struct sshbuf *sigbuf = NULL; | 669 | struct sshbuf *sigbuf = NULL; |
653 | struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; | 670 | struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; |
654 | int r, ndx, success = 0; | 671 | int r, ndx, kexsigtype, use_kexsigtype, success = 0; |
655 | const u_char *blob; | 672 | const u_char *blob; |
656 | u_char *sig = 0; | 673 | u_char *sig = 0; |
657 | size_t blen, slen; | 674 | size_t blen, slen; |
@@ -659,6 +676,8 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) | |||
659 | if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) | 676 | if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) |
660 | fatal("%s: sshbuf_new", __func__); | 677 | fatal("%s: sshbuf_new", __func__); |
661 | 678 | ||
679 | kexsigtype = sshkey_type_plain( | ||
680 | sshkey_type_from_name(ssh->kex->hostkey_alg)); | ||
662 | while (ssh_packet_remaining(ssh) > 0) { | 681 | while (ssh_packet_remaining(ssh) > 0) { |
663 | sshkey_free(key); | 682 | sshkey_free(key); |
664 | key = NULL; | 683 | key = NULL; |
@@ -689,13 +708,20 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) | |||
689 | sshbuf_reset(sigbuf); | 708 | sshbuf_reset(sigbuf); |
690 | free(sig); | 709 | free(sig); |
691 | sig = NULL; | 710 | sig = NULL; |
711 | /* | ||
712 | * For RSA keys, prefer to use the signature type negotiated | ||
713 | * during KEX to the default (SHA1). | ||
714 | */ | ||
715 | use_kexsigtype = kexsigtype == KEY_RSA && | ||
716 | sshkey_type_plain(key->type) == KEY_RSA; | ||
692 | if ((r = sshbuf_put_cstring(sigbuf, | 717 | if ((r = sshbuf_put_cstring(sigbuf, |
693 | "hostkeys-prove-00@openssh.com")) != 0 || | 718 | "hostkeys-prove-00@openssh.com")) != 0 || |
694 | (r = sshbuf_put_string(sigbuf, | 719 | (r = sshbuf_put_string(sigbuf, |
695 | ssh->kex->session_id, ssh->kex->session_id_len)) != 0 || | 720 | ssh->kex->session_id, ssh->kex->session_id_len)) != 0 || |
696 | (r = sshkey_puts(key, sigbuf)) != 0 || | 721 | (r = sshkey_puts(key, sigbuf)) != 0 || |
697 | (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen, | 722 | (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen, |
698 | sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), NULL, 0)) != 0 || | 723 | sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), |
724 | use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0)) != 0 || | ||
699 | (r = sshbuf_put_string(resp, sig, slen)) != 0) { | 725 | (r = sshbuf_put_string(resp, sig, slen)) != 0) { |
700 | error("%s: couldn't prepare signature: %s", | 726 | error("%s: couldn't prepare signature: %s", |
701 | __func__, ssh_err(r)); | 727 | __func__, ssh_err(r)); |
@@ -742,7 +768,8 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) | |||
742 | 768 | ||
743 | /* check permissions */ | 769 | /* check permissions */ |
744 | if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || | 770 | if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || |
745 | no_port_forwarding_flag || options.disable_forwarding || | 771 | !auth_opts->permit_port_forwarding_flag || |
772 | options.disable_forwarding || | ||
746 | (!want_reply && fwd.listen_port == 0) || | 773 | (!want_reply && fwd.listen_port == 0) || |
747 | (fwd.listen_port != 0 && | 774 | (fwd.listen_port != 0 && |
748 | !bind_permitted(fwd.listen_port, pw->pw_uid))) { | 775 | !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) | |||
780 | 807 | ||
781 | /* check permissions */ | 808 | /* check permissions */ |
782 | if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0 | 809 | if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0 |
783 | || no_port_forwarding_flag || options.disable_forwarding || | 810 | || !auth_opts->permit_port_forwarding_flag || |
811 | options.disable_forwarding || | ||
784 | (pw->pw_uid != 0 && !use_privsep)) { | 812 | (pw->pw_uid != 0 && !use_privsep)) { |
785 | success = 0; | 813 | success = 0; |
786 | packet_send_debug("Server has disabled " | 814 | packet_send_debug("Server has disabled " |