119261079SEd Maste /* $OpenBSD: dispatch.c,v 1.32 2019/01/19 21:33:13 djm Exp $ */ 2a04a10f8SKris Kennaway /* 3a04a10f8SKris Kennaway * Copyright (c) 2000 Markus Friedl. All rights reserved. 4a04a10f8SKris Kennaway * 5a04a10f8SKris Kennaway * Redistribution and use in source and binary forms, with or without 6a04a10f8SKris Kennaway * modification, are permitted provided that the following conditions 7a04a10f8SKris Kennaway * are met: 8a04a10f8SKris Kennaway * 1. Redistributions of source code must retain the above copyright 9a04a10f8SKris Kennaway * notice, this list of conditions and the following disclaimer. 10a04a10f8SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 11a04a10f8SKris Kennaway * notice, this list of conditions and the following disclaimer in the 12a04a10f8SKris Kennaway * documentation and/or other materials provided with the distribution. 13a04a10f8SKris Kennaway * 14a04a10f8SKris Kennaway * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15a04a10f8SKris Kennaway * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16a04a10f8SKris Kennaway * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17a04a10f8SKris Kennaway * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18a04a10f8SKris Kennaway * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19a04a10f8SKris Kennaway * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20a04a10f8SKris Kennaway * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21a04a10f8SKris Kennaway * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22a04a10f8SKris Kennaway * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23a04a10f8SKris Kennaway * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24a04a10f8SKris Kennaway */ 25761efaa7SDag-Erling Smørgrav 26a04a10f8SKris Kennaway #include "includes.h" 27761efaa7SDag-Erling Smørgrav 28761efaa7SDag-Erling Smørgrav #include <sys/types.h> 29761efaa7SDag-Erling Smørgrav 30761efaa7SDag-Erling Smørgrav #include <signal.h> 31761efaa7SDag-Erling Smørgrav #include <stdarg.h> 321e8db6e2SBrian Feldman 331e8db6e2SBrian Feldman #include "ssh2.h" 341e8db6e2SBrian Feldman #include "log.h" 35a04a10f8SKris Kennaway #include "dispatch.h" 36a04a10f8SKris Kennaway #include "packet.h" 371e8db6e2SBrian Feldman #include "compat.h" 38bc5531deSDag-Erling Smørgrav #include "ssherr.h" 39a04a10f8SKris Kennaway 40bc5531deSDag-Erling Smørgrav int 414f52dfbbSDag-Erling Smørgrav dispatch_protocol_error(int type, u_int32_t seq, struct ssh *ssh) 42a04a10f8SKris Kennaway { 43bc5531deSDag-Erling Smørgrav int r; 44bc5531deSDag-Erling Smørgrav 45d95e11bfSDag-Erling Smørgrav logit("dispatch_protocol_error: type %d seq %u", type, seq); 46bc5531deSDag-Erling Smørgrav if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || 47bc5531deSDag-Erling Smørgrav (r = sshpkt_put_u32(ssh, seq)) != 0 || 48bc5531deSDag-Erling Smørgrav (r = sshpkt_send(ssh)) != 0 || 49bc5531deSDag-Erling Smørgrav (r = ssh_packet_write_wait(ssh)) != 0) 5019261079SEd Maste sshpkt_fatal(ssh, r, "%s", __func__); 51bc5531deSDag-Erling Smørgrav return 0; 52ae1f160dSDag-Erling Smørgrav } 53bc5531deSDag-Erling Smørgrav 54bc5531deSDag-Erling Smørgrav int 554f52dfbbSDag-Erling Smørgrav dispatch_protocol_ignore(int type, u_int32_t seq, struct ssh *ssh) 56ae1f160dSDag-Erling Smørgrav { 57d95e11bfSDag-Erling Smørgrav logit("dispatch_protocol_ignore: type %d seq %u", type, seq); 58bc5531deSDag-Erling Smørgrav return 0; 59a04a10f8SKris Kennaway } 60bc5531deSDag-Erling Smørgrav 61a04a10f8SKris Kennaway void 62bc5531deSDag-Erling Smørgrav ssh_dispatch_init(struct ssh *ssh, dispatch_fn *dflt) 63a04a10f8SKris Kennaway { 64ae1f160dSDag-Erling Smørgrav u_int i; 65a04a10f8SKris Kennaway for (i = 0; i < DISPATCH_MAX; i++) 66bc5531deSDag-Erling Smørgrav ssh->dispatch[i] = dflt; 67a04a10f8SKris Kennaway } 68bc5531deSDag-Erling Smørgrav 69a04a10f8SKris Kennaway void 70bc5531deSDag-Erling Smørgrav ssh_dispatch_range(struct ssh *ssh, u_int from, u_int to, dispatch_fn *fn) 71ae1f160dSDag-Erling Smørgrav { 72ae1f160dSDag-Erling Smørgrav u_int i; 73ae1f160dSDag-Erling Smørgrav 74ae1f160dSDag-Erling Smørgrav for (i = from; i <= to; i++) { 75ae1f160dSDag-Erling Smørgrav if (i >= DISPATCH_MAX) 76ae1f160dSDag-Erling Smørgrav break; 77bc5531deSDag-Erling Smørgrav ssh->dispatch[i] = fn; 78ae1f160dSDag-Erling Smørgrav } 79ae1f160dSDag-Erling Smørgrav } 80bc5531deSDag-Erling Smørgrav 81ae1f160dSDag-Erling Smørgrav void 82bc5531deSDag-Erling Smørgrav ssh_dispatch_set(struct ssh *ssh, int type, dispatch_fn *fn) 83a04a10f8SKris Kennaway { 84bc5531deSDag-Erling Smørgrav ssh->dispatch[type] = fn; 85a04a10f8SKris Kennaway } 86bc5531deSDag-Erling Smørgrav 87bc5531deSDag-Erling Smørgrav int 884f52dfbbSDag-Erling Smørgrav ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done) 89a04a10f8SKris Kennaway { 90bc5531deSDag-Erling Smørgrav int r; 91bc5531deSDag-Erling Smørgrav u_char type; 92ae1f160dSDag-Erling Smørgrav u_int32_t seqnr; 93a04a10f8SKris Kennaway 94bc5531deSDag-Erling Smørgrav for (;;) { 95a04a10f8SKris Kennaway if (mode == DISPATCH_BLOCK) { 96bc5531deSDag-Erling Smørgrav r = ssh_packet_read_seqnr(ssh, &type, &seqnr); 97bc5531deSDag-Erling Smørgrav if (r != 0) 98bc5531deSDag-Erling Smørgrav return r; 99a04a10f8SKris Kennaway } else { 100bc5531deSDag-Erling Smørgrav r = ssh_packet_read_poll_seqnr(ssh, &type, &seqnr); 101bc5531deSDag-Erling Smørgrav if (r != 0) 102bc5531deSDag-Erling Smørgrav return r; 103a04a10f8SKris Kennaway if (type == SSH_MSG_NONE) 104bc5531deSDag-Erling Smørgrav return 0; 105a04a10f8SKris Kennaway } 106bc5531deSDag-Erling Smørgrav if (type > 0 && type < DISPATCH_MAX && 107bc5531deSDag-Erling Smørgrav ssh->dispatch[type] != NULL) { 108bc5531deSDag-Erling Smørgrav if (ssh->dispatch_skip_packets) { 109bc5531deSDag-Erling Smørgrav debug2("skipped packet (type %u)", type); 110bc5531deSDag-Erling Smørgrav ssh->dispatch_skip_packets--; 111bc5531deSDag-Erling Smørgrav continue; 112bc5531deSDag-Erling Smørgrav } 1134f52dfbbSDag-Erling Smørgrav r = (*ssh->dispatch[type])(type, seqnr, ssh); 114bc5531deSDag-Erling Smørgrav if (r != 0) 115bc5531deSDag-Erling Smørgrav return r; 116bc5531deSDag-Erling Smørgrav } else { 117bc5531deSDag-Erling Smørgrav r = sshpkt_disconnect(ssh, 118bc5531deSDag-Erling Smørgrav "protocol error: rcvd type %d", type); 119bc5531deSDag-Erling Smørgrav if (r != 0) 120bc5531deSDag-Erling Smørgrav return r; 121bc5531deSDag-Erling Smørgrav return SSH_ERR_DISCONNECTED; 122bc5531deSDag-Erling Smørgrav } 123a04a10f8SKris Kennaway if (done != NULL && *done) 124bc5531deSDag-Erling Smørgrav return 0; 125bc5531deSDag-Erling Smørgrav } 126bc5531deSDag-Erling Smørgrav } 127bc5531deSDag-Erling Smørgrav 128bc5531deSDag-Erling Smørgrav void 1294f52dfbbSDag-Erling Smørgrav ssh_dispatch_run_fatal(struct ssh *ssh, int mode, volatile sig_atomic_t *done) 130bc5531deSDag-Erling Smørgrav { 131bc5531deSDag-Erling Smørgrav int r; 132bc5531deSDag-Erling Smørgrav 1334f52dfbbSDag-Erling Smørgrav if ((r = ssh_dispatch_run(ssh, mode, done)) != 0) 13419261079SEd Maste sshpkt_fatal(ssh, r, "%s", __func__); 135a04a10f8SKris Kennaway } 136