⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssh.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 5 页
字号:
static int ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen){    struct rdpkt1_state_tag *st = &ssh->rdpkt1_state;    crBegin(ssh->ssh1_rdpkt_crstate);  next_packet:    ssh->pktin.type = 0;    ssh->pktin.length = 0;    for (st->i = st->len = 0; st->i < 4; st->i++) {	while ((*datalen) == 0)	    crReturn(4 - st->i);	st->len = (st->len << 8) + **data;	(*data)++, (*datalen)--;    }    st->pad = 8 - (st->len % 8);    st->biglen = st->len + st->pad;    ssh->pktin.length = st->len - 5;    if (st->biglen < 0) {        bombout(("Extremely large packet length from server suggests"		 " data stream corruption"));        crStop(0);    }    if (ssh->pktin.maxlen < st->biglen) {	ssh->pktin.maxlen = st->biglen;	ssh->pktin.data = sresize(ssh->pktin.data, st->biglen + APIEXTRA,				  unsigned char);    }    st->to_read = st->biglen;    st->p = ssh->pktin.data;    while (st->to_read > 0) {	st->chunk = st->to_read;	while ((*datalen) == 0)	    crReturn(st->to_read);	if (st->chunk > (*datalen))	    st->chunk = (*datalen);	memcpy(st->p, *data, st->chunk);	*data += st->chunk;	*datalen -= st->chunk;	st->p += st->chunk;	st->to_read -= st->chunk;    }    if (ssh->cipher && detect_attack(ssh->crcda_ctx, ssh->pktin.data,				     st->biglen, NULL)) {        bombout(("Network attack (CRC compensation) detected!"));        crStop(0);    }    if (ssh->cipher)	ssh->cipher->decrypt(ssh->v1_cipher_ctx, ssh->pktin.data, st->biglen);    st->realcrc = crc32_compute(ssh->pktin.data, st->biglen - 4);    st->gotcrc = GET_32BIT(ssh->pktin.data + st->biglen - 4);    if (st->gotcrc != st->realcrc) {	bombout(("Incorrect CRC received on packet"));	crStop(0);    }    ssh->pktin.body = ssh->pktin.data + st->pad + 1;    ssh->pktin.savedpos = 0;    if (ssh->v1_compressing) {	unsigned char *decompblk;	int decomplen;	if (!zlib_decompress_block(ssh->sc_comp_ctx,				   ssh->pktin.body - 1, ssh->pktin.length + 1,				   &decompblk, &decomplen)) {	    bombout(("Zlib decompression encountered invalid data"));	    crStop(0);	}	if (ssh->pktin.maxlen < st->pad + decomplen) {	    ssh->pktin.maxlen = st->pad + decomplen;	    ssh->pktin.data = sresize(ssh->pktin.data,				      ssh->pktin.maxlen + APIEXTRA,				      unsigned char);	    ssh->pktin.body = ssh->pktin.data + st->pad + 1;	}	memcpy(ssh->pktin.body - 1, decompblk, decomplen);	sfree(decompblk);	ssh->pktin.length = decomplen - 1;    }    ssh->pktin.type = ssh->pktin.body[-1];    /*     * 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 ((ssh->pktin.type == SSH1_SMSG_STDOUT_DATA) ||		(ssh->pktin.type == SSH1_SMSG_STDERR_DATA)) {		do_blank = TRUE; blank_prefix = 0;	    } else if (ssh->pktin.type == SSH1_MSG_CHANNEL_DATA) {		do_blank = TRUE; blank_prefix = 4;	    }	    if (do_blank) {		blank.offset = blank_prefix;		blank.len = ssh->pktin.length;		blank.type = PKTLOG_OMIT;		nblanks = 1;	    }	}	log_packet(ssh->logctx,		   PKT_INCOMING, ssh->pktin.type,		   ssh1_pkt_type(ssh->pktin.type),		   ssh->pktin.body, ssh->pktin.length,		   nblanks, &blank);    }    if (ssh->pktin.type == SSH1_SMSG_STDOUT_DATA ||	ssh->pktin.type == SSH1_SMSG_STDERR_DATA ||	ssh->pktin.type == SSH1_MSG_DEBUG ||	ssh->pktin.type == SSH1_SMSG_AUTH_TIS_CHALLENGE ||	ssh->pktin.type == SSH1_SMSG_AUTH_CCARD_CHALLENGE) {	long stringlen = GET_32BIT(ssh->pktin.body);	if (stringlen + 4 != ssh->pktin.length) {	    bombout(("Received data packet with bogus string length"));	    crStop(0);	}    }    if (ssh->pktin.type == SSH1_MSG_DEBUG) {        char *buf, *msg;        int msglen;        ssh_pkt_getstring(ssh, &msg, &msglen);        buf = dupprintf("Remote debug message: %.*s", msglen, msg);	logevent(buf);        sfree(buf);	goto next_packet;    } else if (ssh->pktin.type == SSH1_MSG_IGNORE) {	/* do nothing */	goto next_packet;    }    if (ssh->pktin.type == SSH1_MSG_DISCONNECT) {	/* log reason code in disconnect message */	char *msg;	int msglen;        ssh_pkt_getstring(ssh, &msg, &msglen);	bombout(("Server sent disconnect message:\n\"%.*s\"", msglen, msg));	crStop(0);    }    crFinish(0);}static int ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen){    struct rdpkt2_state_tag *st = &ssh->rdpkt2_state;    crBegin(ssh->ssh2_rdpkt_crstate);  next_packet:    ssh->pktin.type = 0;    ssh->pktin.length = 0;    if (ssh->sccipher)	st->cipherblk = ssh->sccipher->blksize;    else	st->cipherblk = 8;    if (st->cipherblk < 8)	st->cipherblk = 8;    if (ssh->pktin.maxlen < st->cipherblk) {	ssh->pktin.maxlen = st->cipherblk;	ssh->pktin.data = sresize(ssh->pktin.data, 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(st->cipherblk - st->i);	ssh->pktin.data[st->i] = *(*data)++;	(*datalen)--;    }    if (ssh->sccipher)	ssh->sccipher->decrypt(ssh->sc_cipher_ctx,			       ssh->pktin.data, st->cipherblk);    /*     * Now get the length and padding figures.     */    st->len = GET_32BIT(ssh->pktin.data);    st->pad = ssh->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"));	crStop(0);    }    /*     * This enables us to deduce the payload length.     */    st->payload = st->len - st->pad - 1;    ssh->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;    /*     * Adjust memory allocation if packet is too big.     */    if (ssh->pktin.maxlen < st->packetlen + st->maclen) {	ssh->pktin.maxlen = st->packetlen + st->maclen;	ssh->pktin.data = sresize(ssh->pktin.data,				  ssh->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(st->packetlen + st->maclen - st->i);	ssh->pktin.data[st->i] = *(*data)++;	(*datalen)--;    }    /* Decrypt everything _except_ the MAC. */    if (ssh->sccipher)	ssh->sccipher->decrypt(ssh->sc_cipher_ctx,			       ssh->pktin.data + st->cipherblk,			       st->packetlen - st->cipherblk);    /*     * Check the MAC.     */    if (ssh->scmac	&& !ssh->scmac->verify(ssh->sc_mac_ctx, ssh->pktin.data, st->len + 4,			       st->incoming_sequence)) {	bombout(("Incorrect MAC received on packet"));	crStop(0);    }    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,				    ssh->pktin.data + 5, ssh->pktin.length - 5,				    &newpayload, &newlen)) {	    if (ssh->pktin.maxlen < newlen + 5) {		ssh->pktin.maxlen = newlen + 5;		ssh->pktin.data = sresize(ssh->pktin.data,					  ssh->pktin.maxlen + APIEXTRA,					  unsigned char);	    }	    ssh->pktin.length = 5 + newlen;	    memcpy(ssh->pktin.data + 5, newpayload, newlen);	    sfree(newpayload);	}    }    ssh->pktin.savedpos = 6;    ssh->pktin.body = ssh->pktin.data;    ssh->pktin.type = ssh->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 (ssh->pktin.type == SSH2_MSG_CHANNEL_DATA) {		do_blank = TRUE; blank_prefix = 4;	    } else if (ssh->pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {		do_blank = TRUE; blank_prefix = 8;	    }	    if (do_blank) {		blank.offset = blank_prefix;		blank.len = (ssh->pktin.length-6) - blank_prefix;		blank.type = PKTLOG_OMIT;		nblanks = 1;	    }	}	log_packet(ssh->logctx, PKT_INCOMING, ssh->pktin.type,		   ssh2_pkt_type(ssh->pkt_ctx, ssh->pktin.type),		   ssh->pktin.data+6, ssh->pktin.length-6,		   nblanks, &blank);    }    switch (ssh->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(ssh);            ssh_pkt_getstring(ssh, &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);            crStop(0);        }        break;      case SSH2_MSG_IGNORE:	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(ssh);            ssh_pkt_getstring(ssh, &msg, &msglen);            buf = dupprintf("Remote debug message: %.*s", msglen, msg);	    logevent(buf);            sfree(buf);	}        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:	ssh2_pkt_init(ssh, SSH2_MSG_UNIMPLEMENTED);	ssh2_pkt_adduint32(ssh, st->incoming_sequence - 1);	ssh2_pkt_send(ssh);        break;    }    crFinish(0);}static void ssh1_pktout_size(Ssh ssh, int len){    int pad, biglen;    len += 5;			       /* type and CRC */    pad = 8 - (len % 8);    biglen = len + pad;    ssh->pktout.length = len - 5;    if (ssh->pktout.maxlen < biglen) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -