move dispatch to struct ssh; ok djm@
authormarkus <markus@openbsd.org>
Mon, 19 Jan 2015 20:07:45 +0000 (20:07 +0000)
committermarkus <markus@openbsd.org>
Mon, 19 Jan 2015 20:07:45 +0000 (20:07 +0000)
13 files changed:
usr.bin/ssh/auth2-chall.c
usr.bin/ssh/auth2-gss.c
usr.bin/ssh/auth2.c
usr.bin/ssh/channels.c
usr.bin/ssh/channels.h
usr.bin/ssh/clientloop.c
usr.bin/ssh/dispatch.c
usr.bin/ssh/dispatch.h
usr.bin/ssh/kex.c
usr.bin/ssh/kex.h
usr.bin/ssh/packet.h
usr.bin/ssh/serverloop.c
usr.bin/ssh/sshconnect2.c

index b3c1a2f..cb35dbe 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-chall.c,v 1.41 2014/02/02 03:44:31 djm Exp $ */
+/* $OpenBSD: auth2-chall.c,v 1.42 2015/01/19 20:07:45 markus Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2001 Per Allansson.  All rights reserved.
@@ -41,7 +41,7 @@
 
 static int auth2_challenge_start(Authctxt *);
 static int send_userauth_info_request(Authctxt *);
-static void input_userauth_info_response(int, u_int32_t, void *);
+static int input_userauth_info_response(int, u_int32_t, void *);
 
 extern KbdintDevice bsdauth_device;
 
@@ -233,7 +233,7 @@ send_userauth_info_request(Authctxt *authctxt)
        return 1;
 }
 
-static void
+static int
 input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -298,6 +298,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
        }
        userauth_finish(authctxt, authenticated, "keyboard-interactive",
            devicename);
+       return 0;
 }
 
 void
index 9933130..d003551 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-gss.c,v 1.21 2014/02/26 20:28:44 djm Exp $ */
+/* $OpenBSD: auth2-gss.c,v 1.22 2015/01/19 20:07:45 markus Exp $ */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
 
 extern ServerOptions options;
 
-static void input_gssapi_token(int type, u_int32_t plen, void *ctxt);
-static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt);
-static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
-static void input_gssapi_errtok(int, u_int32_t, void *);
+static int input_gssapi_token(int type, u_int32_t plen, void *ctxt);
+static int input_gssapi_mic(int type, u_int32_t plen, void *ctxt);
+static int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
+static int input_gssapi_errtok(int, u_int32_t, void *);
 
 /*
  * We only support those mechanisms that we know about (ie ones that we know
@@ -121,7 +121,7 @@ userauth_gssapi(Authctxt *authctxt)
        return (0);
 }
 
-static void
+static int
 input_gssapi_token(int type, u_int32_t plen, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -173,9 +173,10 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
        }
 
        gss_release_buffer(&min_status, &send_tok);
+       return 0;
 }
 
-static void
+static int
 input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -207,6 +208,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
        /* The client will have already moved on to the next auth */
 
        gss_release_buffer(&maj_status, &send_tok);
+       return 0;
 }
 
 /*
@@ -215,7 +217,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
  * which only enables it once the GSSAPI exchange is complete.
  */
 
-static void
+static int
 input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -239,9 +241,10 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
        userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
+       return 0;
 }
 
-static void
+static int
 input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -279,6 +282,7 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
        userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
+       return 0;
 }
 
 Authmethod method_gssapi = {
index 0ebe253..d77daa0 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2.c,v 1.134 2014/12/22 07:55:51 djm Exp $ */
+/* $OpenBSD: auth2.c,v 1.135 2015/01/19 20:07:45 markus Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -83,8 +83,8 @@ Authmethod *authmethods[] = {
 
 /* protocol */
 
-static void input_service_request(int, u_int32_t, void *);
-static void input_userauth_request(int, u_int32_t, void *);
+static int input_service_request(int, u_int32_t, void *);
+static int input_userauth_request(int, u_int32_t, void *);
 
 /* helper */
 static Authmethod *authmethod_lookup(Authctxt *, const char *);
@@ -161,7 +161,7 @@ do_authentication2(Authctxt *authctxt)
 }
 
 /*ARGSUSED*/
-static void
+static int
 input_service_request(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -192,10 +192,11 @@ input_service_request(int type, u_int32_t seq, void *ctxt)
                packet_disconnect("bad service request %s", service);
        }
        free(service);
+       return 0;
 }
 
 /*ARGSUSED*/
-static void
+static int
 input_userauth_request(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -264,6 +265,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
        free(service);
        free(user);
        free(method);
+       return 0;
 }
 
 void
index 4743423..b3b644d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.338 2014/12/11 08:20:09 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.339 2015/01/19 20:07:45 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2318,7 +2318,7 @@ channel_output_poll(void)
 /* -- protocol input */
 
 /* ARGSUSED */
-void
+int
 channel_input_data(int type, u_int32_t seq, void *ctxt)
 {
        int id;
@@ -2335,7 +2335,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
        /* Ignore any data for non-open channels (might happen on close) */
        if (c->type != SSH_CHANNEL_OPEN &&
            c->type != SSH_CHANNEL_X11_OPEN)
-               return;
+               return 0;
 
        /* Get the data. */
        data = packet_get_string_ptr(&data_len);
@@ -2355,7 +2355,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
                        c->local_window -= win_len;
                        c->local_consumed += win_len;
                }
-               return;
+               return 0;
        }
 
        if (compat20) {
@@ -2366,7 +2366,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
                if (win_len > c->local_window) {
                        logit("channel %d: rcvd too much data %d, win %d",
                            c->self, win_len, c->local_window);
-                       return;
+                       return 0;
                }
                c->local_window -= win_len;
        }
@@ -2375,10 +2375,11 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
        else
                buffer_append(&c->output, data, data_len);
        packet_check_eom();
+       return 0;
 }
 
 /* ARGSUSED */
-void
+int
 channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
 {
        int id;
@@ -2394,7 +2395,7 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
                packet_disconnect("Received extended_data for bad channel %d.", id);
        if (c->type != SSH_CHANNEL_OPEN) {
                logit("channel %d: ext data for non open", id);
-               return;
+               return 0;
        }
        if (c->flags & CHAN_EOF_RCVD) {
                if (datafellows & SSH_BUG_EXTEOF)
@@ -2408,7 +2409,7 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
            c->extended_usage != CHAN_EXTENDED_WRITE ||
            tcode != SSH2_EXTENDED_DATA_STDERR) {
                logit("channel %d: bad ext data", c->self);
-               return;
+               return 0;
        }
        data = packet_get_string(&data_len);
        packet_check_eom();
@@ -2416,16 +2417,17 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
                logit("channel %d: rcvd too much extended_data %d, win %d",
                    c->self, data_len, c->local_window);
                free(data);
-               return;
+               return 0;
        }
        debug2("channel %d: rcvd ext data %d", c->self, data_len);
        c->local_window -= data_len;
        buffer_append(&c->extended, data, data_len);
        free(data);
+       return 0;
 }
 
 /* ARGSUSED */
-void
+int
 channel_input_ieof(int type, u_int32_t seq, void *ctxt)
 {
        int id;
@@ -2445,11 +2447,11 @@ channel_input_ieof(int type, u_int32_t seq, void *ctxt)
                if (buffer_len(&c->input) == 0)
                        chan_ibuf_empty(c);
        }
-
+       return 0;
 }
 
 /* ARGSUSED */
-void
+int
 channel_input_close(int type, u_int32_t seq, void *ctxt)
 {
        int id;
@@ -2484,11 +2486,12 @@ channel_input_close(int type, u_int32_t seq, void *ctxt)
                buffer_clear(&c->input);
                c->type = SSH_CHANNEL_OUTPUT_DRAINING;
        }
+       return 0;
 }
 
 /* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
 /* ARGSUSED */
-void
+int
 channel_input_oclose(int type, u_int32_t seq, void *ctxt)
 {
        int id = packet_get_int();
@@ -2498,10 +2501,11 @@ channel_input_oclose(int type, u_int32_t seq, void *ctxt)
        if (c == NULL)
                packet_disconnect("Received oclose for nonexistent channel %d.", id);
        chan_rcvd_oclose(c);
+       return 0;
 }
 
 /* ARGSUSED */
-void
+int
 channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
 {
        int id = packet_get_int();
@@ -2515,10 +2519,11 @@ channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
                packet_disconnect("Received close confirmation for "
                    "non-closed channel %d (type %d).", id, c->type);
        channel_free(c);
+       return 0;
 }
 
 /* ARGSUSED */
-void
+int
 channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
 {
        int id, remote_id;
@@ -2547,6 +2552,7 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
                    c->remote_window, c->remote_maxpacket);
        }
        packet_check_eom();
+       return 0;
 }
 
 static char *
@@ -2566,7 +2572,7 @@ reason2txt(int reason)
 }
 
 /* ARGSUSED */
-void
+int
 channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
 {
        int id, reason;
@@ -2598,10 +2604,11 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
        packet_check_eom();
        /* Schedule the channel for cleanup/deletion. */
        chan_mark_dead(c);
+       return 0;
 }
 
 /* ARGSUSED */
-void
+int
 channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c;
@@ -2609,7 +2616,7 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
        u_int adjust;
 
        if (!compat20)
-               return;
+               return 0;
 
        /* Get the channel number and verify it. */
        id = packet_get_int();
@@ -2617,16 +2624,17 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
 
        if (c == NULL) {
                logit("Received window adjust for non-open channel %d.", id);
-               return;
+               return 0;
        }
        adjust = packet_get_int();
        packet_check_eom();
        debug2("channel %d: rcvd adjust %u", id, adjust);
        c->remote_window += adjust;
+       return 0;
 }
 
 /* ARGSUSED */
-void
+int
 channel_input_port_open(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
@@ -2654,10 +2662,11 @@ channel_input_port_open(int type, u_int32_t seq, void *ctxt)
                packet_send();
        } else
                c->remote_id = remote_id;
+       return 0;
 }
 
 /* ARGSUSED */
-void
+int
 channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c;
@@ -2674,15 +2683,15 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
 
        if ((c = channel_lookup(id)) == NULL) {
                logit("channel_input_status_confirm: %d: unknown", id);
-               return;
+               return 0;
        }       
-       ;
        if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL)
-               return;
+               return 0;
        cc->cb(type, c, cc->ctx);
        TAILQ_REMOVE(&c->status_confirms, cc, entry);
        explicit_bzero(cc, sizeof(*cc));
        free(cc);
+       return 0;
 }
 
 /* -- tcp forwarding */
@@ -4030,7 +4039,7 @@ x11_connect_display(void)
  */
 
 /* ARGSUSED */
-void
+int
 x11_input_open(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
@@ -4070,11 +4079,12 @@ x11_input_open(int type, u_int32_t seq, void *ctxt)
                packet_put_int(c->self);
        }
        packet_send();
+       return 0;
 }
 
 /* dummy protocol handler that denies SSH-1 requests (agent/x11) */
 /* ARGSUSED */
-void
+int
 deny_input_open(int type, u_int32_t seq, void *ctxt)
 {
        int rchan = packet_get_int();
@@ -4094,6 +4104,7 @@ deny_input_open(int type, u_int32_t seq, void *ctxt)
        packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
        packet_put_int(rchan);
        packet_send();
+       return 0;
 }
 
 /*
index e8662f5..6848078 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.115 2014/07/15 15:54:14 millert Exp $ */
+/* $OpenBSD: channels.h,v 1.116 2015/01/19 20:07:45 markus Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -227,17 +227,17 @@ void       channel_send_window_changes(void);
 
 /* protocol handler */
 
-void    channel_input_close(int, u_int32_t, void *);
-void    channel_input_close_confirmation(int, u_int32_t, void *);
-void    channel_input_data(int, u_int32_t, void *);
-void    channel_input_extended_data(int, u_int32_t, void *);
-void    channel_input_ieof(int, u_int32_t, void *);
-void    channel_input_oclose(int, u_int32_t, void *);
-void    channel_input_open_confirmation(int, u_int32_t, void *);
-void    channel_input_open_failure(int, u_int32_t, void *);
-void    channel_input_port_open(int, u_int32_t, void *);
-void    channel_input_window_adjust(int, u_int32_t, void *);
-void    channel_input_status_confirm(int, u_int32_t, void *);
+int     channel_input_close(int, u_int32_t, void *);
+int     channel_input_close_confirmation(int, u_int32_t, void *);
+int     channel_input_data(int, u_int32_t, void *);
+int     channel_input_extended_data(int, u_int32_t, void *);
+int     channel_input_ieof(int, u_int32_t, void *);
+int     channel_input_oclose(int, u_int32_t, void *);
+int     channel_input_open_confirmation(int, u_int32_t, void *);
+int     channel_input_open_failure(int, u_int32_t, void *);
+int     channel_input_port_open(int, u_int32_t, void *);
+int     channel_input_window_adjust(int, u_int32_t, void *);
+int     channel_input_status_confirm(int, u_int32_t, void *);
 
 /* file descriptor handling (read/write) */
 
@@ -283,10 +283,10 @@ int        permitopen_port(const char *);
 
 int     x11_connect_display(void);
 int     x11_create_display_inet(int, int, int, u_int *, int **);
-void     x11_input_open(int, u_int32_t, void *);
+int      x11_input_open(int, u_int32_t, void *);
 void    x11_request_forwarding_with_spoofing(int, const char *, const char *,
             const char *, int);
-void    deny_input_open(int, u_int32_t, void *);
+int     deny_input_open(int, u_int32_t, void *);
 
 /* agent forwarding */
 
index 96c12b3..58be15e 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.263 2015/01/19 19:52:16 markus Exp $ */
+/* $OpenBSD: clientloop.c,v 1.264 2015/01/19 20:07:45 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -528,13 +528,13 @@ client_check_window_change(void)
        }
 }
 
-static void
+static int
 client_global_request_reply(int type, u_int32_t seq, void *ctxt)
 {
        struct global_confirm *gc;
 
        if ((gc = TAILQ_FIRST(&global_confirms)) == NULL)
-               return;
+               return 0;
        if (gc->cb != NULL)
                gc->cb(type, seq, gc->ctx);
        if (--gc->ref_count <= 0) {
@@ -544,6 +544,7 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt)
        }
 
        packet_set_alive_timeouts(0);
+       return 0;
 }
 
 static void
@@ -1727,7 +1728,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
 
 /*********/
 
-static void
+static int
 client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
 {
        u_int data_len;
@@ -1736,8 +1737,9 @@ client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
        buffer_append(&stdout_buffer, data, data_len);
        explicit_bzero(data, data_len);
        free(data);
+       return 0;
 }
-static void
+static int
 client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
 {
        u_int data_len;
@@ -1746,8 +1748,9 @@ client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
        buffer_append(&stderr_buffer, data, data_len);
        explicit_bzero(data, data_len);
        free(data);
+       return 0;
 }
-static void
+static int
 client_input_exit_status(int type, u_int32_t seq, void *ctxt)
 {
        exit_status = packet_get_int();
@@ -1762,8 +1765,9 @@ client_input_exit_status(int type, u_int32_t seq, void *ctxt)
        packet_write_wait();
        /* Flag that we want to exit. */
        quit_pending = 1;
+       return 0;
 }
-static void
+static int
 client_input_agent_open(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
@@ -1806,6 +1810,7 @@ client_input_agent_open(int type, u_int32_t seq, void *ctxt)
                packet_put_int(c->self);
        }
        packet_send();
+       return 0;
 }
 
 static Channel *
@@ -1960,7 +1965,7 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
 }
 
 /* XXXX move to generic input handler */
-static void
+static int
 client_input_channel_open(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
@@ -2011,8 +2016,9 @@ client_input_channel_open(int type, u_int32_t seq, void *ctxt)
                packet_send();
        }
        free(ctype);
+       return 0;
 }
-static void
+static int
 client_input_channel_req(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
@@ -2057,8 +2063,9 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
                packet_send();
        }
        free(rtype);
+       return 0;
 }
-static void
+static int
 client_input_global_request(int type, u_int32_t seq, void *ctxt)
 {
        char *rtype;
@@ -2076,6 +2083,7 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt)
                packet_write_wait();
        }
        free(rtype);
+       return 0;
 }
 
 void
index 9fbd42a..d9b4591 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: dispatch.c,v 1.22 2008/10/31 15:05:34 stevesk Exp $ */
+/* $OpenBSD: dispatch.c,v 1.23 2015/01/19 20:07:45 markus Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
 #include "dispatch.h"
 #include "packet.h"
 #include "compat.h"
+#include "ssherr.h"
 
-#define DISPATCH_MAX   255
-
-dispatch_fn *dispatch[DISPATCH_MAX];
-
-void
-dispatch_protocol_error(int type, u_int32_t seq, void *ctxt)
+int
+dispatch_protocol_error(int type, u_int32_t seq, void *ctx)
 {
+       struct ssh *ssh = active_state; /* XXX */
+       int r;
+
        logit("dispatch_protocol_error: type %d seq %u", type, seq);
        if (!compat20)
                fatal("protocol error");
-       packet_start(SSH2_MSG_UNIMPLEMENTED);
-       packet_put_int(seq);
-       packet_send();
-       packet_write_wait();
+       if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
+           (r = sshpkt_put_u32(ssh, seq)) != 0 ||
+           (r = sshpkt_send(ssh)) != 0)
+               fatal("%s: %s", __func__, ssh_err(r));
+       ssh_packet_write_wait(ssh);
+       return 0;
 }
-void
-dispatch_protocol_ignore(int type, u_int32_t seq, void *ctxt)
+
+int
+dispatch_protocol_ignore(int type, u_int32_t seq, void *ssh)
 {
        logit("dispatch_protocol_ignore: type %d seq %u", type, seq);
+       return 0;
 }
+
 void
-dispatch_init(dispatch_fn *dflt)
+ssh_dispatch_init(struct ssh *ssh, dispatch_fn *dflt)
 {
        u_int i;
        for (i = 0; i < DISPATCH_MAX; i++)
-               dispatch[i] = dflt;
+               ssh->dispatch[i] = dflt;
 }
+
 void
-dispatch_range(u_int from, u_int to, dispatch_fn *fn)
+ssh_dispatch_range(struct ssh *ssh, u_int from, u_int to, dispatch_fn *fn)
 {
        u_int i;
 
        for (i = from; i <= to; i++) {
                if (i >= DISPATCH_MAX)
                        break;
-               dispatch[i] = fn;
+               ssh->dispatch[i] = fn;
        }
 }
+
 void
-dispatch_set(int type, dispatch_fn *fn)
+ssh_dispatch_set(struct ssh *ssh, int type, dispatch_fn *fn)
 {
-       dispatch[type] = fn;
+       ssh->dispatch[type] = fn;
 }
-void
-dispatch_run(int mode, volatile sig_atomic_t *done, void *ctxt)
+
+int
+ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done,
+    void *ctxt)
 {
-       for (;;) {
-               int type;
-               u_int32_t seqnr;
+       int r;
+       u_char type;
+       u_int32_t seqnr;
 
+       for (;;) {
                if (mode == DISPATCH_BLOCK) {
-                       type = packet_read_seqnr(&seqnr);
+                       r = ssh_packet_read_seqnr(ssh, &type, &seqnr);
+                       if (r != 0)
+                               return r;
                } else {
-                       type = packet_read_poll_seqnr(&seqnr);
+                       r = ssh_packet_read_poll_seqnr(ssh, &type, &seqnr);
+                       if (r != 0)
+                               return r;
                        if (type == SSH_MSG_NONE)
-                               return;
+                               return 0;
+               }
+               if (type > 0 && type < DISPATCH_MAX &&
+                   ssh->dispatch[type] != NULL) {
+                       if (ssh->dispatch_skip_packets) {
+                               debug2("skipped packet (type %u)", type);
+                               ssh->dispatch_skip_packets--;
+                               continue;
+                       }
+                       /* XXX 'ssh' will replace 'ctxt' later */
+                       r = (*ssh->dispatch[type])(type, seqnr, ctxt);
+                       if (r != 0)
+                               return r;
+               } else {
+                       r = sshpkt_disconnect(ssh,
+                           "protocol error: rcvd type %d", type);
+                       if (r != 0)
+                               return r;
+                       return SSH_ERR_DISCONNECTED;
                }
-               if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL)
-                       (*dispatch[type])(type, seqnr, ctxt);
-               else
-                       packet_disconnect("protocol error: rcvd type %d", type);
                if (done != NULL && *done)
-                       return;
+                       return 0;
        }
 }
+
+void
+ssh_dispatch_run_fatal(struct ssh *ssh, int mode, volatile sig_atomic_t *done,
+    void *ctxt)
+{
+       int r;
+
+       if ((r = ssh_dispatch_run(ssh, mode, done, ctxt)) != 0)
+               fatal("%s: %s", __func__, ssh_err(r));
+}
index 4bca8a5..cd51dbc 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: dispatch.h,v 1.11 2006/04/20 09:27:09 djm Exp $ */
+/* $OpenBSD: dispatch.h,v 1.12 2015/01/19 20:07:45 markus Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
+#ifndef DISPATCH_H
+#define DISPATCH_H
+
+#define DISPATCH_MAX   255
+
 enum {
        DISPATCH_BLOCK,
        DISPATCH_NONBLOCK
 };
 
-typedef void dispatch_fn(int, u_int32_t, void *);
+struct ssh;
+
+typedef int dispatch_fn(int, u_int32_t, void *);
+
+int    dispatch_protocol_error(int, u_int32_t, void *);
+int    dispatch_protocol_ignore(int, u_int32_t, void *);
+void   ssh_dispatch_init(struct ssh *, dispatch_fn *);
+void   ssh_dispatch_set(struct ssh *, int, dispatch_fn *);
+void   ssh_dispatch_range(struct ssh *, u_int, u_int, dispatch_fn *);
+int    ssh_dispatch_run(struct ssh *, int, volatile sig_atomic_t *, void *);
+void   ssh_dispatch_run_fatal(struct ssh *, int, volatile sig_atomic_t *, void *);
+
+#define dispatch_init(dflt) \
+       ssh_dispatch_init(active_state, (dflt))
+#define dispatch_range(from, to, fn) \
+       ssh_dispatch_range(active_state, (from), (to), (fn))
+#define dispatch_set(type, fn) \
+       ssh_dispatch_set(active_state, (type), (fn))
+#define dispatch_run(mode, done, ctxt) \
+       ssh_dispatch_run_fatal(active_state, (mode), (done), (ctxt))
 
-void    dispatch_init(dispatch_fn *);
-void    dispatch_set(int, dispatch_fn *);
-void    dispatch_range(u_int, u_int, dispatch_fn *);
-void    dispatch_run(int, volatile sig_atomic_t *, void *);
-void    dispatch_protocol_error(int, u_int32_t, void *);
-void    dispatch_protocol_ignore(int, u_int32_t, void *);
+#endif
index 653c460..8d4f8af 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.100 2015/01/19 19:52:16 markus Exp $ */
+/* $OpenBSD: kex.c,v 1.101 2015/01/19 20:07:45 markus Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
@@ -190,10 +190,11 @@ kex_prop_free(char **proposal)
 }
 
 /* ARGSUSED */
-static void
+static int
 kex_protocol_error(int type, u_int32_t seq, void *ctxt)
 {
        error("Hm, kex protocol error: type %d seq %u", type, seq);
+       return 0;
 }
 
 static void
@@ -262,7 +263,7 @@ kex_send_kexinit(Kex *kex)
 }
 
 /* ARGSUSED */
-void
+int
 kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
 {
        const char *ptr;
@@ -297,6 +298,7 @@ kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
        packet_check_eom();
 
        kex_kexinit_finish(kex);
+       return 0;
 }
 
 void
index 0a6aed7..abdbe4f 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.67 2015/01/19 19:52:16 markus Exp $ */
+/* $OpenBSD: kex.h,v 1.68 2015/01/19 20:07:45 markus Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -139,7 +139,7 @@ void         kex_finish(Kex *);
 void     kex_free_newkeys(struct newkeys *);
 
 void    kex_send_kexinit(Kex *);
-void    kex_input_kexinit(int, u_int32_t, void *);
+int     kex_input_kexinit(int, u_int32_t, void *);
 void    kex_derive_keys(Kex *, u_char *, u_int, const u_char *, u_int);
 void    kex_derive_keys_bn(Kex *, u_char *, u_int, const BIGNUM *);
 
index 46d15a1..2fa9009 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.h,v 1.62 2015/01/19 19:52:16 markus Exp $ */
+/* $OpenBSD: packet.h,v 1.63 2015/01/19 20:07:45 markus Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -28,6 +28,8 @@ struct sshkey;
 struct sshbuf;
 struct session_state;  /* private session data */
 
+#include "dispatch.h"  /* typedef, DISPATCH_MAX */
+
 struct ssh {
        /* Session state */
        struct session_state *state;
@@ -39,6 +41,11 @@ struct ssh {
        char *remote_ipaddr;
        int remote_port;
 
+       /* Dispatcher table */
+       dispatch_fn *dispatch[DISPATCH_MAX];
+       /* number of packets to ignore in the dispatcher */
+       int dispatch_skip_packets;
+
        /* datafellows */
        int compat;
 };
index a1f5166..418c928 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.173 2015/01/19 19:52:16 markus Exp $ */
+/* $OpenBSD: serverloop.c,v 1.174 2015/01/19 20:07:45 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -862,7 +862,7 @@ server_loop2(Authctxt *authctxt)
        session_destroy_all(NULL);
 }
 
-static void
+static int
 server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
 {
        debug("Got %d/%u for keepalive", type, seq);
@@ -872,9 +872,10 @@ server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
         * the bogus CHANNEL_REQUEST we send for keepalives.
         */
        packet_set_alive_timeouts(0);
+       return 0;
 }
 
-static void
+static int
 server_input_stdin_data(int type, u_int32_t seq, void *ctxt)
 {
        char *data;
@@ -883,15 +884,16 @@ server_input_stdin_data(int type, u_int32_t seq, void *ctxt)
        /* Stdin data from the client.  Append it to the buffer. */
        /* Ignore any data if the client has closed stdin. */
        if (fdin == -1)
-               return;
+               return 0;
        data = packet_get_string(&data_len);
        packet_check_eom();
        buffer_append(&stdin_buffer, data, data_len);
        explicit_bzero(data, data_len);
        free(data);
+       return 0;
 }
 
-static void
+static int
 server_input_eof(int type, u_int32_t seq, void *ctxt)
 {
        /*
@@ -902,9 +904,10 @@ server_input_eof(int type, u_int32_t seq, void *ctxt)
        debug("EOF received for stdin.");
        packet_check_eom();
        stdin_eof = 1;
+       return 0;
 }
 
-static void
+static int
 server_input_window_size(int type, u_int32_t seq, void *ctxt)
 {
        u_int row = packet_get_int();
@@ -916,6 +919,7 @@ server_input_window_size(int type, u_int32_t seq, void *ctxt)
        packet_check_eom();
        if (fdin != -1)
                pty_change_window_size(fdin, row, col, xpixel, ypixel);
+       return 0;
 }
 
 static Channel *
@@ -1055,7 +1059,7 @@ server_request_session(void)
        return c;
 }
 
-static void
+static int
 server_input_channel_open(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
@@ -1105,9 +1109,10 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt)
                packet_send();
        }
        free(ctype);
+       return 0;
 }
 
-static void
+static int
 server_input_global_request(int type, u_int32_t seq, void *ctxt)
 {
        char *rtype;
@@ -1199,9 +1204,10 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
                packet_write_wait();
        }
        free(rtype);
+       return 0;
 }
 
-static void
+static int
 server_input_channel_req(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c;
@@ -1231,6 +1237,7 @@ server_input_channel_req(int type, u_int32_t seq, void *ctxt)
                packet_send();
        }
        free(rtype);
+       return 0;
 }
 
 static void
index 5266e48..7949ed4 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.217 2015/01/19 19:52:16 markus Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.218 2015/01/19 20:07:45 markus Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Damien Miller.  All rights reserved.
@@ -279,14 +279,14 @@ struct cauthmethod {
        int     *batch_flag;    /* flag in option struct that disables method */
 };
 
-void   input_userauth_success(int, u_int32_t, void *);
-void   input_userauth_success_unexpected(int, u_int32_t, void *);
-void   input_userauth_failure(int, u_int32_t, void *);
-void   input_userauth_banner(int, u_int32_t, void *);
-void   input_userauth_error(int, u_int32_t, void *);
-void   input_userauth_info_req(int, u_int32_t, void *);
-void   input_userauth_pk_ok(int, u_int32_t, void *);
-void   input_userauth_passwd_changereq(int, u_int32_t, void *);
+int    input_userauth_success(int, u_int32_t, void *);
+int    input_userauth_success_unexpected(int, u_int32_t, void *);
+int    input_userauth_failure(int, u_int32_t, void *);
+int    input_userauth_banner(int, u_int32_t, void *);
+int    input_userauth_error(int, u_int32_t, void *);
+int    input_userauth_info_req(int, u_int32_t, void *);
+int    input_userauth_pk_ok(int, u_int32_t, void *);
+int    input_userauth_passwd_changereq(int, u_int32_t, void *);
 
 int    userauth_none(Authctxt *);
 int    userauth_pubkey(Authctxt *);
@@ -296,11 +296,11 @@ int       userauth_hostbased(Authctxt *);
 
 #ifdef GSSAPI
 int    userauth_gssapi(Authctxt *authctxt);
-void   input_gssapi_response(int type, u_int32_t, void *);
-void   input_gssapi_token(int type, u_int32_t, void *);
-void   input_gssapi_hash(int type, u_int32_t, void *);
-void   input_gssapi_error(int, u_int32_t, void *);
-void   input_gssapi_errtok(int, u_int32_t, void *);
+int    input_gssapi_response(int type, u_int32_t, void *);
+int    input_gssapi_token(int type, u_int32_t, void *);
+int    input_gssapi_hash(int type, u_int32_t, void *);
+int    input_gssapi_error(int, u_int32_t, void *);
+int    input_gssapi_errtok(int, u_int32_t, void *);
 #endif
 
 void   userauth(Authctxt *, char *);
@@ -449,15 +449,16 @@ userauth(Authctxt *authctxt, char *authlist)
 }
 
 /* ARGSUSED */
-void
+int
 input_userauth_error(int type, u_int32_t seq, void *ctxt)
 {
        fatal("input_userauth_error: bad message during authentication: "
            "type %d", type);
+       return 0;
 }
 
 /* ARGSUSED */
-void
+int
 input_userauth_banner(int type, u_int32_t seq, void *ctxt)
 {
        char *msg, *raw, *lang;
@@ -476,10 +477,11 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
        }
        free(raw);
        free(lang);
+       return 0;
 }
 
 /* ARGSUSED */
-void
+int
 input_userauth_success(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -493,9 +495,10 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
        free(authctxt->methoddata);
        authctxt->methoddata = NULL;
        authctxt->success = 1;                  /* break out */
+       return 0;
 }
 
-void
+int
 input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -505,10 +508,11 @@ input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt)
 
        fatal("Unexpected authentication success during %s.",
            authctxt->method->name);
+       return 0;
 }
 
 /* ARGSUSED */
-void
+int
 input_userauth_failure(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -531,10 +535,11 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt)
        debug("Authentications that can continue: %s", authlist);
 
        userauth(authctxt, authlist);
+       return 0;
 }
 
 /* ARGSUSED */
-void
+int
 input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -602,6 +607,7 @@ done:
        /* try another method if we did not send a packet */
        if (sent == 0)
                userauth(authctxt, NULL);
+       return 0;
 }
 
 #ifdef GSSAPI
@@ -885,7 +891,7 @@ userauth_passwd(Authctxt *authctxt)
  * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
  */
 /* ARGSUSED */
-void
+int
 input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -926,7 +932,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
                password = read_passphrase(prompt, RP_ALLOW_EOF);
                if (password == NULL) {
                        /* bail out */
-                       return;
+                       return 0;
                }
                snprintf(prompt, sizeof(prompt),
                    "Retype %.30s@%.128s's new password: ",
@@ -949,6 +955,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
 
        dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
            &input_userauth_passwd_changereq);
+       return 0;
 }
 
 static int
@@ -1373,7 +1380,7 @@ userauth_kbdint(Authctxt *authctxt)
 /*
  * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
  */
-void
+int
 input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
@@ -1425,6 +1432,7 @@ input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
 
        packet_add_padding(64);
        packet_send();
+       return 0;
 }
 
 static int