switch (st->pktin->type) {  case SSH2_MSG_DISCONNECT: {  char *buf, *msg; int nowlen, reason, msglen;  reason = ssh_pkt_getuint32(st->pktin); ssh_pkt_getstring(st->pktin, &msg, &msglen);  if (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) { buf = dupprintf("Received disconnect message (%s)", ssh2_disconnect_reasons[reason]); } else { buf = dupprintf("Received disconnect message (unknown" " type %d)", reason); } logevent(buf); sfree(buf); buf = dupprintf("Disconnection message text: %n%.*s", &nowlen, msglen, msg); logevent(buf); bombout(("Server sent disconnect message\ntype %d (%s):\n\"%s\"", reason, (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ? ssh2_disconnect_reasons[reason] : "unknown", buf+nowlen)); sfree(buf); ssh_free_packet(st->pktin); crStop(NULL); } break; case SSH2_MSG_IGNORE: ssh_free_packet(st->pktin); goto next_packet; case SSH2_MSG_DEBUG: {  char *buf, *msg; int msglen; int always_display;   always_display = ssh2_pkt_getbool(st->pktin); ssh_pkt_getstring(st->pktin, &msg, &msglen);  buf = dupprintf("Remote debug message: %.*s", msglen, msg); logevent(buf); sfree(buf); } ssh_free_packet(st->pktin); goto next_packet;   case SSH2_MSG_UNIMPLEMENTED: case SSH2_MSG_SERVICE_REQUEST: case SSH2_MSG_SERVICE_ACCEPT: case SSH2_MSG_KEXINIT: case SSH2_MSG_NEWKEYS: case SSH2_MSG_KEXDH_INIT: case SSH2_MSG_KEXDH_REPLY:   case SSH2_MSG_KEX_DH_GEX_INIT: case SSH2_MSG_KEX_DH_GEX_REPLY: case SSH2_MSG_USERAUTH_REQUEST: case SSH2_MSG_USERAUTH_FAILURE: case SSH2_MSG_USERAUTH_SUCCESS: case SSH2_MSG_USERAUTH_BANNER: case SSH2_MSG_USERAUTH_PK_OK:   case SSH2_MSG_USERAUTH_INFO_RESPONSE: case SSH2_MSG_GLOBAL_REQUEST: case SSH2_MSG_REQUEST_SUCCESS: case SSH2_MSG_REQUEST_FAILURE: case SSH2_MSG_CHANNEL_OPEN: case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: case SSH2_MSG_CHANNEL_OPEN_FAILURE: case SSH2_MSG_CHANNEL_WINDOW_ADJUST: case SSH2_MSG_CHANNEL_DATA: case SSH2_MSG_CHANNEL_EXTENDED_DATA: case SSH2_MSG_CHANNEL_EOF: case SSH2_MSG_CHANNEL_CLOSE: case SSH2_MSG_CHANNEL_REQUEST: case SSH2_MSG_CHANNEL_SUCCESS: case SSH2_MSG_CHANNEL_FAILURE: break;   default: { struct Packet *pktout; pktout = ssh2_pkt_init(SSH2_MSG_UNIMPLEMENTED); ssh2_pkt_adduint32(pktout, st->incoming_sequence - 1);  ssh2_pkt_send_noqueue(ssh, pktout); } break; }
static struct Packet *ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen){    struct rdpkt2_state_tag *st = &ssh->rdpkt2_state;    crBegin(ssh->ssh2_rdpkt_crstate);  next_packet:    st->pktin = ssh_new_packet();    st->pktin->type = 0;    st->pktin->length = 0;    if (ssh->sccipher)	st->cipherblk = ssh->sccipher->blksize;    else	st->cipherblk = 8;    if (st->cipherblk < 8)	st->cipherblk = 8;    st->pktin->data = snewn(st->cipherblk + APIEXTRA, unsigned char);    /*     * Acquire and decrypt the first block of the packet. This will     * contain the length and padding details.     */    for (st->i = st->len = 0; st->i < st->cipherblk; st->i++) {	while ((*datalen) == 0)	    crReturn(NULL);	st->pktin->data[st->i] = *(*data)++;	(*datalen)--;    }    if (ssh->sccipher)	ssh->sccipher->decrypt(ssh->sc_cipher_ctx,			       st->pktin->data, st->cipherblk);    /*     * Now get the length and padding figures.     */    st->len = GET_32BIT(st->pktin->data);    st->pad = st->pktin->data[4];    /*     * _Completely_ silly lengths should be stomped on before they     * do us any more damage.     */    if (st->len < 0 || st->pad < 0 || st->len + st->pad < 0) {	bombout(("Incoming packet was garbled on decryption"));	ssh_free_packet(st->pktin);	crStop(NULL);    }    /*     * This enables us to deduce the payload length.     */    st->payload = st->len - st->pad - 1;    st->pktin->length = st->payload + 5;    /*     * So now we can work out the total packet length.     */    st->packetlen = st->len + 4;    st->maclen = ssh->scmac ? ssh->scmac->len : 0;    /*     * Allocate memory for the rest of the packet.     */    st->pktin->maxlen = st->packetlen + st->maclen;    st->pktin->data = sresize(st->pktin->data,			      st->pktin->maxlen + APIEXTRA,			      unsigned char);    /*     * Read and decrypt the remainder of the packet.     */    for (st->i = st->cipherblk; st->i < st->packetlen + st->maclen;	 st->i++) {	while ((*datalen) == 0)	    crReturn(NULL);	st->pktin->data[st->i] = *(*data)++;	(*datalen)--;    }    /* Decrypt everything _except_ the MAC. */    if (ssh->sccipher)	ssh->sccipher->decrypt(ssh->sc_cipher_ctx,			       st->pktin->data + st->cipherblk,			       st->packetlen - st->cipherblk);    /*     * Check the MAC.     */    if (ssh->scmac	&& !ssh->scmac->verify(ssh->sc_mac_ctx, st->pktin->data, st->len + 4,			       st->incoming_sequence)) {	bombout(("Incorrect MAC received on packet"));	ssh_free_packet(st->pktin);	crStop(NULL);    }    st->incoming_sequence++;	       /* whether or not we MACed */    /*     * Decompress packet payload.     */    {	unsigned char *newpayload;	int newlen;	if (ssh->sccomp &&	    ssh->sccomp->decompress(ssh->sc_comp_ctx,				    st->pktin->data + 5, st->pktin->length - 5,				    &newpayload, &newlen)) {	    if (st->pktin->maxlen < newlen + 5) {		st->pktin->maxlen = newlen + 5;		st->pktin->data = sresize(st->pktin->data,					  st->pktin->maxlen + APIEXTRA,					  unsigned char);	    }	    st->pktin->length = 5 + newlen;	    memcpy(st->pktin->data + 5, newpayload, newlen);	    sfree(newpayload);	}    }    st->pktin->savedpos = 6;    st->pktin->body = st->pktin->data;    st->pktin->type = st->pktin->data[5];    /*     * Log incoming packet, possibly omitting sensitive fields.     */    if (ssh->logctx) {	int nblanks = 0;	struct logblank_t blank;	if (ssh->cfg.logomitdata) {	    int do_blank = FALSE, blank_prefix = 0;	    /* "Session data" packets - omit the data field */	    if (st->pktin->type == SSH2_MSG_CHANNEL_DATA) {		do_blank = TRUE; blank_prefix = 4;	    } else if (st->pktin->type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {		do_blank = TRUE; blank_prefix = 8;	    }	    if (do_blank) {		blank.offset = blank_prefix;		blank.len = (st->pktin->length-6) - blank_prefix;		blank.type = PKTLOG_OMIT;		nblanks = 1;	    }	}	log_packet(ssh->logctx, PKT_INCOMING, st->pktin->type,		   ssh2_pkt_type(ssh->pkt_ctx, st->pktin->type),		   st->pktin->data+6, st->pktin->length-6,		   nblanks, &blank);    }    switch (st->pktin->type) {        /*         * These packets we must handle instantly.         */      case SSH2_MSG_DISCONNECT:        {            /* log reason code in disconnect message */            char *buf, *msg;            int nowlen, reason, msglen;            reason = ssh_pkt_getuint32(st->pktin);            ssh_pkt_getstring(st->pktin, &msg, &msglen);            if (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) {                buf = dupprintf("Received disconnect message (%s)",				ssh2_disconnect_reasons[reason]);            } else {                buf = dupprintf("Received disconnect message (unknown"				" type %d)", reason);            }            logevent(buf);	    sfree(buf);            buf = dupprintf("Disconnection message text: %n%.*s",			    &nowlen, msglen, msg);            logevent(buf);            bombout(("Server sent disconnect message\ntype %d (%s):\n\"%s\"",                     reason,                     (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ?                     ssh2_disconnect_reasons[reason] : "unknown",                     buf+nowlen));	    sfree(buf);	    ssh_free_packet(st->pktin);            crStop(NULL);        }        break;      case SSH2_MSG_IGNORE:	ssh_free_packet(st->pktin);	goto next_packet;      case SSH2_MSG_DEBUG:	{	    /* log the debug message */	    char *buf, *msg;	    int msglen;	    int always_display;	    /* XXX maybe we should actually take notice of this */            always_display = ssh2_pkt_getbool(st->pktin);            ssh_pkt_getstring(st->pktin, &msg, &msglen);            buf = dupprintf("Remote debug message: %.*s", msglen, msg);	    logevent(buf);            sfree(buf);	}	ssh_free_packet(st->pktin);        goto next_packet;        /*         * These packets we need do nothing about here.         */      case SSH2_MSG_UNIMPLEMENTED:      case SSH2_MSG_SERVICE_REQUEST:      case SSH2_MSG_SERVICE_ACCEPT:      case SSH2_MSG_KEXINIT:      case SSH2_MSG_NEWKEYS:      case SSH2_MSG_KEXDH_INIT:      case SSH2_MSG_KEXDH_REPLY:      /* case SSH2_MSG_KEX_DH_GEX_REQUEST: duplicate case value */      /* case SSH2_MSG_KEX_DH_GEX_GROUP: duplicate case value */      case SSH2_MSG_KEX_DH_GEX_INIT:      case SSH2_MSG_KEX_DH_GEX_REPLY:      case SSH2_MSG_USERAUTH_REQUEST:      case SSH2_MSG_USERAUTH_FAILURE:      case SSH2_MSG_USERAUTH_SUCCESS:      case SSH2_MSG_USERAUTH_BANNER:      case SSH2_MSG_USERAUTH_PK_OK:      /* case SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: duplicate case value */      /* case SSH2_MSG_USERAUTH_INFO_REQUEST: duplicate case value */      case SSH2_MSG_USERAUTH_INFO_RESPONSE:      case SSH2_MSG_GLOBAL_REQUEST:      case SSH2_MSG_REQUEST_SUCCESS:      case SSH2_MSG_REQUEST_FAILURE:      case SSH2_MSG_CHANNEL_OPEN:      case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:      case SSH2_MSG_CHANNEL_OPEN_FAILURE:      case SSH2_MSG_CHANNEL_WINDOW_ADJUST:      case SSH2_MSG_CHANNEL_DATA:      case SSH2_MSG_CHANNEL_EXTENDED_DATA:      case SSH2_MSG_CHANNEL_EOF:      case SSH2_MSG_CHANNEL_CLOSE:      case SSH2_MSG_CHANNEL_REQUEST:      case SSH2_MSG_CHANNEL_SUCCESS:      case SSH2_MSG_CHANNEL_FAILURE:        break;        /*         * For anything else we send SSH2_MSG_UNIMPLEMENTED.         */      default:	{	    struct Packet *pktout;	    pktout = ssh2_pkt_init(SSH2_MSG_UNIMPLEMENTED);	    ssh2_pkt_adduint32(pktout, st->incoming_sequence - 1);	    /* UNIMPLEMENTED messages MUST appear in the same order as	     * the messages they respond to. Hence, never queue them. */	    ssh2_pkt_send_noqueue(ssh, pktout);	}        break;    }    crFinish(st->pktin);}