From: markus Date: Mon, 19 Jan 2015 20:07:45 +0000 (+0000) Subject: move dispatch to struct ssh; ok djm@ X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=b4c826f7ae17701924be9a4cadbb4788e3600d8e;p=openbsd move dispatch to struct ssh; ok djm@ --- diff --git a/usr.bin/ssh/auth2-chall.c b/usr.bin/ssh/auth2-chall.c index b3c1a2f8750..cb35dbe135c 100644 --- a/usr.bin/ssh/auth2-chall.c +++ b/usr.bin/ssh/auth2-chall.c @@ -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 diff --git a/usr.bin/ssh/auth2-gss.c b/usr.bin/ssh/auth2-gss.c index 99331306ef9..d003551ce83 100644 --- a/usr.bin/ssh/auth2-gss.c +++ b/usr.bin/ssh/auth2-gss.c @@ -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. @@ -43,10 +43,10 @@ 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 = { diff --git a/usr.bin/ssh/auth2.c b/usr.bin/ssh/auth2.c index 0ebe253267f..d77daa010b3 100644 --- a/usr.bin/ssh/auth2.c +++ b/usr.bin/ssh/auth2.c @@ -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 diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c index 47434233385..b3b644d0333 100644 --- a/usr.bin/ssh/channels.c +++ b/usr.bin/ssh/channels.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , 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; } /* diff --git a/usr.bin/ssh/channels.h b/usr.bin/ssh/channels.h index e8662f529d8..6848078547e 100644 --- a/usr.bin/ssh/channels.h +++ b/usr.bin/ssh/channels.h @@ -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 @@ -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 */ diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c index 96c12b39ed8..58be15ec425 100644 --- a/usr.bin/ssh/clientloop.c +++ b/usr.bin/ssh/clientloop.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , 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 diff --git a/usr.bin/ssh/dispatch.c b/usr.bin/ssh/dispatch.c index 9fbd42a96ab..d9b4591765e 100644 --- a/usr.bin/ssh/dispatch.c +++ b/usr.bin/ssh/dispatch.c @@ -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. * @@ -34,69 +34,107 @@ #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)); +} diff --git a/usr.bin/ssh/dispatch.h b/usr.bin/ssh/dispatch.h index 4bca8a5a0f3..cd51dbc0b66 100644 --- a/usr.bin/ssh/dispatch.h +++ b/usr.bin/ssh/dispatch.h @@ -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. @@ -23,16 +23,36 @@ * (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 diff --git a/usr.bin/ssh/kex.c b/usr.bin/ssh/kex.c index 653c4602f0f..8d4f8affab0 100644 --- a/usr.bin/ssh/kex.c +++ b/usr.bin/ssh/kex.c @@ -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 diff --git a/usr.bin/ssh/kex.h b/usr.bin/ssh/kex.h index 0a6aed706cf..abdbe4fdb55 100644 --- a/usr.bin/ssh/kex.h +++ b/usr.bin/ssh/kex.h @@ -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 *); diff --git a/usr.bin/ssh/packet.h b/usr.bin/ssh/packet.h index 46d15a17d33..2fa9009c5ba 100644 --- a/usr.bin/ssh/packet.h +++ b/usr.bin/ssh/packet.h @@ -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 @@ -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; }; diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c index a1f51664a66..418c9282460 100644 --- a/usr.bin/ssh/serverloop.c +++ b/usr.bin/ssh/serverloop.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , 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 diff --git a/usr.bin/ssh/sshconnect2.c b/usr.bin/ssh/sshconnect2.c index 5266e487d5c..7949ed4fd2a 100644 --- a/usr.bin/ssh/sshconnect2.c +++ b/usr.bin/ssh/sshconnect2.c @@ -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