* Database for Edit and Continue'.
*/
#define crBegin(v) { int *crLine = &v; switch(v) { case 0:;
-#define crState(t) \
- struct t *s; \
- if (!ssh->t) ssh->t = snew(struct t); \
- s = ssh->t;
+#define crBeginState crBegin(s->crLine)
+#define crStateP(t, v) \
+ struct t *s; \
+ if (!(v)) { s = (v) = snew(struct t); s->crLine = 0; } \
+ s = (v);
+#define crState(t) crStateP(t, ssh->t)
#define crFinish(z) } *crLine = 0; return (z); }
#define crFinishV } *crLine = 0; return; }
#define crReturn(z) \
int ssh1_rdpkt_crstate;
int ssh2_rdpkt_crstate;
- int do_ssh_init_crstate;
int ssh_gotdata_crstate;
- int do_ssh1_login_crstate;
int do_ssh1_connection_crstate;
- int do_ssh2_transport_crstate;
- int do_ssh2_authconn_crstate;
void *do_ssh_init_state;
void *do_ssh1_login_state;
* indications from a request.
*/
struct queued_handler *qhead, *qtail;
+ handler_fn_t q_saved_handler1, q_saved_handler2;
/*
* This module deals with sending keepalives.
static int do_ssh_init(Ssh ssh, unsigned char c)
{
struct do_ssh_init_state {
+ int crLine;
int vslen;
char version[10];
char *vstring;
int proto1, proto2;
};
crState(do_ssh_init_state);
-
- crBegin(ssh->do_ssh_init_crstate);
+
+ crBeginState;
/* Search for a line beginning with the string "SSH-" in the input. */
for (;;) {
struct RSAKey servkey, hostkey;
struct MD5Context md5c;
struct do_ssh1_login_state {
+ int crLine;
int len;
unsigned char *rsabuf, *keystr1, *keystr2;
unsigned long supported_ciphers_mask, supported_auths_mask;
};
crState(do_ssh1_login_state);
- crBegin(ssh->do_ssh1_login_crstate);
+ crBeginState;
if (!pktin)
crWaitUntil(pktin);
if (qh->msg1 > 0) {
assert(ssh->packet_dispatch[qh->msg1] == ssh_queueing_handler);
- ssh->packet_dispatch[qh->msg1] = NULL;
+ ssh->packet_dispatch[qh->msg1] = ssh->q_saved_handler1;
}
if (qh->msg2 > 0) {
assert(ssh->packet_dispatch[qh->msg2] == ssh_queueing_handler);
- ssh->packet_dispatch[qh->msg2] = NULL;
+ ssh->packet_dispatch[qh->msg2] = ssh->q_saved_handler2;
}
if (qh->next) {
ssh->qhead = qh->next;
if (ssh->qhead->msg1 > 0) {
- assert(ssh->packet_dispatch[ssh->qhead->msg1] == NULL);
+ ssh->q_saved_handler1 = ssh->packet_dispatch[ssh->qhead->msg1];
ssh->packet_dispatch[ssh->qhead->msg1] = ssh_queueing_handler;
}
if (ssh->qhead->msg2 > 0) {
- assert(ssh->packet_dispatch[ssh->qhead->msg2] == NULL);
+ ssh->q_saved_handler2 = ssh->packet_dispatch[ssh->qhead->msg2];
ssh->packet_dispatch[ssh->qhead->msg2] = ssh_queueing_handler;
}
} else {
ssh->qhead = ssh->qtail = NULL;
- ssh->packet_dispatch[pktin->type] = NULL;
}
qh->handler(ssh, pktin, qh->ctx);
ssh->qhead = qh;
if (qh->msg1 > 0) {
- assert(ssh->packet_dispatch[qh->msg1] == NULL);
+ ssh->q_saved_handler1 = ssh->packet_dispatch[ssh->qhead->msg1];
ssh->packet_dispatch[qh->msg1] = ssh_queueing_handler;
}
if (qh->msg2 > 0) {
- assert(ssh->packet_dispatch[qh->msg2] == NULL);
+ ssh->q_saved_handler2 = ssh->packet_dispatch[ssh->qhead->msg2];
ssh->packet_dispatch[qh->msg2] = ssh_queueing_handler;
}
} else {
x11_send_eof(c->u.x11.s);
else
send_close = TRUE;
+ break;
case CHAN_SOCKDATA:
if (c->u.pfd.s)
- x11_send_eof(c->u.pfd.s);
+ pfd_send_eof(c->u.pfd.s);
else
send_close = TRUE;
+ break;
case CHAN_AGENT:
send_close = TRUE;
+ break;
}
if (send_close && !(c->closes & CLOSES_SENT_EOF)) {
{
unsigned char *in = (unsigned char *)vin;
struct do_ssh2_transport_state {
+ int crLine;
int nbits, pbits, warn_kex, warn_cscipher, warn_sccipher;
Bignum p, g, e, f, K;
void *our_kexinit;
};
crState(do_ssh2_transport_state);
- crBegin(ssh->do_ssh2_transport_crstate);
+ crBeginState;
s->cscipher_tobe = s->sccipher_tobe = NULL;
s->csmac_tobe = s->scmac_tobe = NULL;
ssh2_timer, ssh);
/*
- * If this is the first key exchange phase, we must pass the
- * SSH2_MSG_NEWKEYS packet to the next layer, not because it
- * wants to see it but because it will need time to initialise
- * itself before it sees an actual packet. In subsequent key
- * exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because
- * it would only confuse the layer above.
- */
- if (s->activated_authconn) {
- crReturn(0);
- }
- s->activated_authconn = TRUE;
-
- /*
* Now we're encrypting. Begin returning 1 to the protocol main
* function so that other things can run on top of the
* transport. If we ever see a KEXINIT, we must go back to the
while (!((pktin && pktin->type == SSH2_MSG_KEXINIT) ||
(!pktin && inlen < 0))) {
wait_for_rekey:
+ if (!ssh->protocol_initial_phase_done) {
+ ssh->protocol_initial_phase_done = TRUE;
+ /*
+ * Allow authconn to initialise itself.
+ */
+ do_ssh2_authconn(ssh, NULL, 0, NULL);
+ }
crReturn(1);
}
if (pktin) {
/*
* Handle the SSH-2 userauth and connection layers.
*/
+static void ssh2_msg_authconn(Ssh ssh, struct Packet *pktin)
+{
+ do_ssh2_authconn(ssh, NULL, 0, pktin);
+}
+
static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
struct Packet *pktin)
{
struct do_ssh2_authconn_state {
+ int crLine;
enum {
AUTH_TYPE_NONE,
AUTH_TYPE_PUBLICKEY,
int siglen, retlen, len;
char *q, *agentreq, *ret;
int try_send;
+ int requested_x11;
+ int requested_agent;
+ int requested_tty;
int num_env, env_left, env_ok;
struct Packet *pktout;
Filename *keyfile;
};
crState(do_ssh2_authconn_state);
- crBegin(ssh->do_ssh2_authconn_crstate);
-
+ crBeginState;
+
+ /* Register as a handler for all the messages this coroutine handles. */
+ ssh->packet_dispatch[SSH2_MSG_SERVICE_ACCEPT] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_USERAUTH_REQUEST] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_USERAUTH_FAILURE] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_USERAUTH_SUCCESS] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_USERAUTH_PK_OK] = ssh2_msg_authconn;
+ /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ] = ssh2_msg_authconn; duplicate case value */
+ /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_REQUEST] = ssh2_msg_authconn; duplicate case value */
+ ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_RESPONSE] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_REQUEST_SUCCESS] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_REQUEST_FAILURE] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = ssh2_msg_authconn;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = ssh2_msg_authconn;
+
s->done_service_req = FALSE;
s->we_are_in = s->userauth_success = FALSE;
#ifndef NO_GSSAPI
}
/*
+ * Enable port forwardings.
+ */
+ ssh_setup_portfwd(ssh, ssh->conf);
+
+ /*
+ * Send the CHANNEL_REQUESTS for the main channel. We send them all
+ * and then start looking for responses, so it's important that the
+ * sending and receiving code below it is kept in sync.
+ */
+
+ /*
* Potentially enable X11 forwarding.
*/
if (ssh->mainchan && !ssh->ncmode && conf_get_int(ssh->conf, CONF_x11_forward) &&
end_log_omission(ssh, s->pktout);
ssh2_pkt_adduint32(s->pktout, ssh->x11disp->screennum);
ssh2_pkt_send(ssh, s->pktout);
-
- crWaitUntilV(pktin);
-
- if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
- if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
- bombout(("Unexpected response to X11 forwarding request:"
- " packet type %d", pktin->type));
- crStopV;
- }
- logevent("X11 forwarding refused");
- } else {
- logevent("X11 forwarding enabled");
- ssh->X11_fwd_enabled = TRUE;
- }
- }
-
- /*
- * Enable port forwardings.
- */
- ssh_setup_portfwd(ssh, ssh->conf);
+ s->requested_x11 = TRUE;
+ } else
+ s->requested_x11 = FALSE;
/*
* Potentially enable agent forwarding.
ssh2_pkt_addstring(s->pktout, "auth-agent-req@openssh.com");
ssh2_pkt_addbool(s->pktout, 1); /* want reply */
ssh2_pkt_send(ssh, s->pktout);
-
- crWaitUntilV(pktin);
-
- if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
- if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
- bombout(("Unexpected response to agent forwarding request:"
- " packet type %d", pktin->type));
- crStopV;
- }
- logevent("Agent forwarding refused");
- } else {
- logevent("Agent forwarding enabled");
- ssh->agentfwd_enabled = TRUE;
- }
- }
+ s->requested_agent = TRUE;
+ } else
+ s->requested_agent = FALSE;
/*
* Now allocate a pty for the session.
ssh2_pkt_addstring_data(s->pktout, "\0", 1); /* TTY_OP_END */
ssh2_pkt_send(ssh, s->pktout);
ssh->state = SSH_STATE_INTERMED;
-
- crWaitUntilV(pktin);
-
- if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
- if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
- bombout(("Unexpected response to pty request:"
- " packet type %d", pktin->type));
- crStopV;
- }
- c_write_str(ssh, "Server refused to allocate pty\r\n");
- ssh->editing = ssh->echoing = 1;
- } else {
- logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
- ssh->ospeed, ssh->ispeed);
- ssh->got_pty = TRUE;
- }
- } else {
- ssh->editing = ssh->echoing = 1;
- }
+ s->requested_tty = TRUE;
+ } else
+ s->requested_tty = FALSE;
/*
* Send environment variables.
* Simplest thing here is to send all the requests at once, and
* then wait for a whole bunch of successes or failures.
*/
+ s->num_env = 0;
if (ssh->mainchan && !ssh->ncmode) {
char *key, *val;
- s->num_env = 0;
-
for (val = conf_get_str_strs(ssh->conf, CONF_environmt, NULL, &key);
val != NULL;
val = conf_get_str_strs(ssh->conf, CONF_environmt, key, &key)) {
s->num_env++;
}
-
- if (s->num_env) {
+ if (s->num_env)
logeventf(ssh, "Sent %d environment variables", s->num_env);
+ }
- s->env_ok = 0;
- s->env_left = s->num_env;
+ /*
+ * All CHANNEL_REQUESTs sent. Now collect up the replies. These
+ * must be in precisely the same order as the requests.
+ */
- while (s->env_left > 0) {
- crWaitUntilV(pktin);
+ if (s->requested_x11) {
+ crWaitUntilV(pktin);
- if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
- if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
- bombout(("Unexpected response to environment request:"
- " packet type %d", pktin->type));
- crStopV;
- }
- } else {
- s->env_ok++;
- }
+ if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
+ if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
+ bombout(("Unexpected response to X11 forwarding request:"
+ " packet type %d", pktin->type));
+ crStopV;
+ }
+ logevent("X11 forwarding refused");
+ } else {
+ logevent("X11 forwarding enabled");
+ ssh->X11_fwd_enabled = TRUE;
+ }
+ }
- s->env_left--;
+ if (s->requested_agent) {
+ crWaitUntilV(pktin);
+
+ if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
+ if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
+ bombout(("Unexpected response to agent forwarding request:"
+ " packet type %d", pktin->type));
+ crStopV;
}
+ logevent("Agent forwarding refused");
+ } else {
+ logevent("Agent forwarding enabled");
+ ssh->agentfwd_enabled = TRUE;
+ }
+ }
- if (s->env_ok == s->num_env) {
- logevent("All environment variables successfully set");
- } else if (s->env_ok == 0) {
- logevent("All environment variables refused");
- c_write_str(ssh, "Server refused to set environment variables\r\n");
+ if (s->requested_tty) {
+ crWaitUntilV(pktin);
+
+ if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
+ if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
+ bombout(("Unexpected response to pty request:"
+ " packet type %d", pktin->type));
+ crStopV;
+ }
+ c_write_str(ssh, "Server refused to allocate pty\r\n");
+ ssh->editing = ssh->echoing = 1;
+ } else {
+ logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
+ ssh->ospeed, ssh->ispeed);
+ ssh->got_pty = TRUE;
+ }
+ } else {
+ ssh->editing = ssh->echoing = 1;
+ }
+
+ if (s->num_env) {
+ s->env_ok = 0;
+ s->env_left = s->num_env;
+
+ while (s->env_left > 0) {
+ crWaitUntilV(pktin);
+
+ if (pktin->type != SSH2_MSG_CHANNEL_SUCCESS) {
+ if (pktin->type != SSH2_MSG_CHANNEL_FAILURE) {
+ bombout(("Unexpected response to environment request:"
+ " packet type %d", pktin->type));
+ crStopV;
+ }
} else {
- logeventf(ssh, "%d environment variables refused",
- s->num_env - s->env_ok);
- c_write_str(ssh, "Server refused to set all environment variables\r\n");
+ s->env_ok++;
}
+
+ s->env_left--;
+ }
+
+ if (s->env_ok == s->num_env) {
+ logevent("All environment variables successfully set");
+ } else if (s->env_ok == 0) {
+ logevent("All environment variables refused");
+ c_write_str(ssh, "Server refused to set environment variables\r\n");
+ } else {
+ logeventf(ssh, "%d environment variables refused",
+ s->num_env - s->env_ok);
+ c_write_str(ssh, "Server refused to set all environment variables\r\n");
}
}
logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
}
+static void ssh2_msg_transport(Ssh ssh, struct Packet *pktin)
+{
+ do_ssh2_transport(ssh, NULL, 0, pktin);
+}
+
+/*
+ * Called if we receive a packet that isn't allowed by the protocol.
+ * This only applies to packets whose meaning PuTTY understands.
+ * Entirely unknown packets are handled below.
+ */
+static void ssh2_msg_unexpected(Ssh ssh, struct Packet *pktin)
+{
+ char *buf = dupprintf("Server protocol violation: unexpected %s packet",
+ ssh2_pkt_type(ssh->pkt_kctx, ssh->pkt_actx,
+ pktin->type));
+ ssh_disconnect(ssh, NULL, buf, SSH2_DISCONNECT_PROTOCOL_ERROR, FALSE);
+}
+
static void ssh2_msg_something_unimplemented(Ssh ssh, struct Packet *pktin)
{
struct Packet *pktout;
ssh->packet_dispatch[i] = ssh2_msg_something_unimplemented;
/*
- * Any message we actually understand, we set to NULL so that
- * the coroutines will get it.
+ * Initially, we only accept transport messages (and a few generic
+ * ones). do_ssh2_authconn will add more when it starts.
+ * Messages that are understood but not currently acceptable go to
+ * ssh2_msg_unexpected.
*/
- ssh->packet_dispatch[SSH2_MSG_UNIMPLEMENTED] = NULL;
- ssh->packet_dispatch[SSH2_MSG_SERVICE_REQUEST] = NULL;
- ssh->packet_dispatch[SSH2_MSG_SERVICE_ACCEPT] = NULL;
- ssh->packet_dispatch[SSH2_MSG_KEXINIT] = NULL;
- ssh->packet_dispatch[SSH2_MSG_NEWKEYS] = NULL;
- ssh->packet_dispatch[SSH2_MSG_KEXDH_INIT] = NULL;
- ssh->packet_dispatch[SSH2_MSG_KEXDH_REPLY] = NULL;
- /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REQUEST] = NULL; duplicate case value */
- /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_GROUP] = NULL; duplicate case value */
- ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_INIT] = NULL;
- ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REPLY] = NULL;
- ssh->packet_dispatch[SSH2_MSG_USERAUTH_REQUEST] = NULL;
- ssh->packet_dispatch[SSH2_MSG_USERAUTH_FAILURE] = NULL;
- ssh->packet_dispatch[SSH2_MSG_USERAUTH_SUCCESS] = NULL;
- ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = NULL;
- ssh->packet_dispatch[SSH2_MSG_USERAUTH_PK_OK] = NULL;
- /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ] = NULL; duplicate case value */
- /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_REQUEST] = NULL; duplicate case value */
- ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_RESPONSE] = NULL;
- ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] = NULL;
- ssh->packet_dispatch[SSH2_MSG_REQUEST_SUCCESS] = NULL;
- ssh->packet_dispatch[SSH2_MSG_REQUEST_FAILURE] = NULL;
- ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] = NULL;
- ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] = NULL;
- ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] = NULL;
- ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] = NULL;
- ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] = NULL;
- ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] = NULL;
- ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = NULL;
- ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = NULL;
- ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] = NULL;
- ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = NULL;
- ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = NULL;
+ ssh->packet_dispatch[SSH2_MSG_UNIMPLEMENTED] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_SERVICE_REQUEST] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_SERVICE_ACCEPT] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_KEXINIT] = ssh2_msg_transport;
+ ssh->packet_dispatch[SSH2_MSG_NEWKEYS] = ssh2_msg_transport;
+ ssh->packet_dispatch[SSH2_MSG_KEXDH_INIT] = ssh2_msg_transport;
+ ssh->packet_dispatch[SSH2_MSG_KEXDH_REPLY] = ssh2_msg_transport;
+ /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REQUEST] = ssh2_msg_transport; duplicate case value */
+ /* ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_GROUP] = ssh2_msg_transport; duplicate case value */
+ ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_INIT] = ssh2_msg_transport;
+ ssh->packet_dispatch[SSH2_MSG_KEX_DH_GEX_REPLY] = ssh2_msg_transport;
+ ssh->packet_dispatch[SSH2_MSG_USERAUTH_REQUEST] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_USERAUTH_FAILURE] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_USERAUTH_SUCCESS] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_USERAUTH_BANNER] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_USERAUTH_PK_OK] = ssh2_msg_unexpected;
+ /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ] = ssh2_msg_unexpected; duplicate case value */
+ /* ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_REQUEST] = ssh2_msg_unexpected; duplicate case value */
+ ssh->packet_dispatch[SSH2_MSG_USERAUTH_INFO_RESPONSE] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_GLOBAL_REQUEST] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_REQUEST_SUCCESS] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_REQUEST_FAILURE] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_CONFIRMATION] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_OPEN_FAILURE] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_WINDOW_ADJUST] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_DATA] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_EXTENDED_DATA] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_EOF] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_CLOSE] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_REQUEST] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_SUCCESS] = ssh2_msg_unexpected;
+ ssh->packet_dispatch[SSH2_MSG_CHANNEL_FAILURE] = ssh2_msg_unexpected;
/*
- * These special message types we install handlers for.
+ * These messages have a special handler from the start.
*/
ssh->packet_dispatch[SSH2_MSG_DISCONNECT] = ssh2_msg_disconnect;
ssh->packet_dispatch[SSH2_MSG_IGNORE] = ssh_msg_ignore; /* shared with SSH-1 */
do_ssh2_transport(ssh, "too much data received", -1, NULL);
}
- if (pktin && ssh->packet_dispatch[pktin->type]) {
+ if (pktin)
ssh->packet_dispatch[pktin->type](ssh, pktin);
- return;
- }
-
- if (!ssh->protocol_initial_phase_done ||
- (pktin && pktin->type >= 20 && pktin->type < 50)) {
- if (do_ssh2_transport(ssh, in, inlen, pktin) &&
- !ssh->protocol_initial_phase_done) {
- ssh->protocol_initial_phase_done = TRUE;
- /*
- * Allow authconn to initialise itself.
- */
- do_ssh2_authconn(ssh, NULL, 0, NULL);
- }
- } else {
+ else if (!ssh->protocol_initial_phase_done)
+ do_ssh2_transport(ssh, in, inlen, pktin);
+ else
do_ssh2_authconn(ssh, in, inlen, pktin);
- }
}
static void ssh_cache_conf_values(Ssh ssh)
ssh->v2_outgoing_sequence = 0;
ssh->ssh1_rdpkt_crstate = 0;
ssh->ssh2_rdpkt_crstate = 0;
- ssh->do_ssh_init_crstate = 0;
ssh->ssh_gotdata_crstate = 0;
ssh->do_ssh1_connection_crstate = 0;
- ssh->do_ssh1_login_crstate = 0;
- ssh->do_ssh2_transport_crstate = 0;
- ssh->do_ssh2_authconn_crstate = 0;
ssh->do_ssh_init_state = NULL;
ssh->do_ssh1_login_state = NULL;
ssh->do_ssh2_transport_state = NULL;