logevent(buf); strcpy(buf, "Disconnection message text: "); nowlen = strlen(buf); if (msglen > sizeof(buf) - nowlen - 1) msglen = sizeof(buf) - nowlen - 1; memcpy(buf + nowlen, pktin.data + 14, msglen); buf[nowlen + msglen] = '\0'; 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)); crReturn(0);
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: ssh2_pkt_init(SSH2_MSG_UNIMPLEMENTED); ssh2_pkt_adduint32(st->incoming_sequence - 1); ssh2_pkt_send(); break;
static int ssh2_rdpkt(unsigned char **data, int *datalen){    struct rdpkt2_state_tag *st = &rdpkt2_state;    crBegin;  next_packet:    pktin.type = 0;    pktin.length = 0;    if (sccipher)	st->cipherblk = sccipher->blksize;    else	st->cipherblk = 8;    if (st->cipherblk < 8)	st->cipherblk = 8;    if (pktin.maxlen < st->cipherblk) {	pktin.maxlen = st->cipherblk;	pktin.data =	    (pktin.data ==	     NULL ? smalloc(st->cipherblk +			    APIEXTRA) : srealloc(pktin.data,						 st->cipherblk +						 APIEXTRA));	if (!pktin.data)	    fatalbox("Out of memory");    }    /*     * 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(st->cipherblk - st->i);	pktin.data[st->i] = *(*data)++;	(*datalen)--;    }    if (sccipher)	sccipher->decrypt(pktin.data, st->cipherblk);    /*     * Now get the length and padding figures.     */    st->len = GET_32BIT(pktin.data);    st->pad = pktin.data[4];    /*     * This enables us to deduce the payload length.     */    st->payload = st->len - st->pad - 1;    pktin.length = st->payload + 5;    /*     * So now we can work out the total packet length.     */    st->packetlen = st->len + 4;    st->maclen = scmac ? scmac->len : 0;    /*     * Adjust memory allocation if packet is too big.     */    if (pktin.maxlen < st->packetlen + st->maclen) {	pktin.maxlen = st->packetlen + st->maclen;	pktin.data =	    (pktin.data ==	     NULL ? smalloc(pktin.maxlen + APIEXTRA) : srealloc(pktin.data,								pktin.maxlen								+								APIEXTRA));	if (!pktin.data)	    fatalbox("Out of memory");    }    /*     * 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(st->packetlen + st->maclen - st->i);	pktin.data[st->i] = *(*data)++;	(*datalen)--;    }    /* Decrypt everything _except_ the MAC. */    if (sccipher)	sccipher->decrypt(pktin.data + st->cipherblk,			  st->packetlen - st->cipherblk);    /*     * Check the MAC.     */    if (scmac	&& !scmac->verify(pktin.data, st->len + 4,			  st->incoming_sequence)) {	bombout(("Incorrect MAC received on packet"));	crReturn(0);    }    st->incoming_sequence++;	       /* whether or not we MACed */    /*     * Decompress packet payload.     */    {	unsigned char *newpayload;	int newlen;	if (sccomp && sccomp->decompress(pktin.data + 5, pktin.length - 5,					 &newpayload, &newlen)) {	    if (pktin.maxlen < newlen + 5) {		pktin.maxlen = newlen + 5;		pktin.data =		    (pktin.data ==		     NULL ? smalloc(pktin.maxlen +				    APIEXTRA) : srealloc(pktin.data,							 pktin.maxlen +							 APIEXTRA));		if (!pktin.data)		    fatalbox("Out of memory");	    }	    pktin.length = 5 + newlen;	    memcpy(pktin.data + 5, newpayload, newlen);	    sfree(newpayload);	}    }    pktin.savedpos = 6;    pktin.type = pktin.data[5];    log_packet(PKT_INCOMING, pktin.type, ssh2_pkt_type(pktin.type),	       pktin.data+6, pktin.length-6);    if (pktin.type == SSH2_MSG_IGNORE || pktin.type == SSH2_MSG_DEBUG)	goto next_packet;	       /* FIXME: print DEBUG message */    if (pktin.type == SSH2_MSG_DISCONNECT) {	/* log reason code in disconnect message */	char buf[256];	int reason = GET_32BIT(pktin.data + 6);	unsigned msglen = GET_32BIT(pktin.data + 10);	unsigned nowlen;	if (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) {	    sprintf(buf, "Received disconnect message (%s)",		    ssh2_disconnect_reasons[reason]);	} else {	    sprintf(buf, "Received disconnect message (unknown type %d)",		    reason);	}	logevent(buf);	strcpy(buf, "Disconnection message text: ");	nowlen = strlen(buf);	if (msglen > sizeof(buf) - nowlen - 1)	    msglen = sizeof(buf) - nowlen - 1;	memcpy(buf + nowlen, pktin.data + 14, msglen);	buf[nowlen + msglen] = '\0';	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));	crReturn(0);    }    crFinish(0);}