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

📄 ssh.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	ssh->pktout.maxlen = biglen;#ifdef MSCRYPTOAPI	/* Allocate enough buffer space for extra block	 * for MS CryptEncrypt() */	ssh->pktout.data = sresize(ssh->pktout.data, biglen + 12,				   unsigned char);#else	ssh->pktout.data = sresize(ssh->pktout.data, biglen + 4,				   unsigned char);#endif    }    ssh->pktout.body = ssh->pktout.data + 4 + pad + 1;}static void s_wrpkt_start(Ssh ssh, int type, int len){    ssh1_pktout_size(ssh, len);    ssh->pktout.type = type;    /* Initialise log omission state */    ssh->pktout_nblanks = 0;    ssh->pktout_blanks = NULL;}static int s_wrpkt_prepare(Ssh ssh){    int pad, biglen, i;    unsigned long crc;#ifdef __SC__    /*     * XXX various versions of SC (including 8.8.4) screw up the     * register allocation in this function and use the same register     * (D6) for len and as a temporary, with predictable results.  The     * following sledgehammer prevents this.     */    volatile#endif    int len;    ssh->pktout.body[-1] = ssh->pktout.type;    if (ssh->logctx)	log_packet(ssh->logctx, PKT_OUTGOING, ssh->pktout.type,		   ssh1_pkt_type(ssh->pktout.type),		   ssh->pktout.body, ssh->pktout.length,		   ssh->pktout_nblanks, ssh->pktout_blanks);    sfree(ssh->pktout_blanks); ssh->pktout_blanks = NULL;    ssh->pktout_nblanks = 0;    if (ssh->v1_compressing) {	unsigned char *compblk;	int complen;	zlib_compress_block(ssh->cs_comp_ctx,			    ssh->pktout.body - 1, ssh->pktout.length + 1,			    &compblk, &complen);	ssh1_pktout_size(ssh, complen - 1);	memcpy(ssh->pktout.body - 1, compblk, complen);	sfree(compblk);    }    len = ssh->pktout.length + 5;	       /* type and CRC */    pad = 8 - (len % 8);    biglen = len + pad;    for (i = 0; i < pad; i++)	ssh->pktout.data[i + 4] = random_byte();    crc = crc32_compute(ssh->pktout.data + 4, biglen - 4);    PUT_32BIT(ssh->pktout.data + biglen, crc);    PUT_32BIT(ssh->pktout.data, len);    if (ssh->cipher)	ssh->cipher->encrypt(ssh->v1_cipher_ctx, ssh->pktout.data + 4, biglen);    return biglen + 4;}static void s_wrpkt(Ssh ssh){    int len, backlog;    len = s_wrpkt_prepare(ssh);    backlog = sk_write(ssh->s, (char *)ssh->pktout.data, len);    if (backlog > SSH_MAX_BACKLOG)	ssh_throttle_all(ssh, 1, backlog);}static void s_wrpkt_defer(Ssh ssh){    int len;    len = s_wrpkt_prepare(ssh);    if (ssh->deferred_len + len > ssh->deferred_size) {	ssh->deferred_size = ssh->deferred_len + len + 128;	ssh->deferred_send_data = sresize(ssh->deferred_send_data,					  ssh->deferred_size,					  unsigned char);    }    memcpy(ssh->deferred_send_data + ssh->deferred_len, ssh->pktout.data, len);    ssh->deferred_len += len;}/* * Construct a packet with the specified contents. */static void construct_packet(Ssh ssh, int pkttype, va_list ap1, va_list ap2){    unsigned char *p, *argp, argchar;    unsigned long argint;    int pktlen, argtype, arglen;    Bignum bn;    pktlen = 0;    while ((argtype = va_arg(ap1, int)) != PKT_END) {	switch (argtype) {	  case PKT_INT:	    (void) va_arg(ap1, int);	    pktlen += 4;	    break;	  case PKT_CHAR:	    (void) va_arg(ap1, int);	    pktlen++;	    break;	  case PKT_DATA:	    (void) va_arg(ap1, unsigned char *);	    arglen = va_arg(ap1, int);	    pktlen += arglen;	    break;	  case PKT_STR:	    argp = va_arg(ap1, unsigned char *);	    arglen = strlen((char *)argp);	    pktlen += 4 + arglen;	    break;	  case PKT_BIGNUM:	    bn = va_arg(ap1, Bignum);	    pktlen += ssh1_bignum_length(bn);	    break;	  case PKTT_PASSWORD:	  case PKTT_DATA:	  case PKTT_OTHER:	    /* ignore this pass */	    break;	  default:	    assert(0);	}    }    s_wrpkt_start(ssh, pkttype, pktlen);    p = ssh->pktout.body;    while ((argtype = va_arg(ap2, int)) != PKT_END) {	int offset = p - ssh->pktout.body, len = 0;	switch (argtype) {	  /* Actual fields in the packet */	  case PKT_INT:	    argint = va_arg(ap2, int);	    PUT_32BIT(p, argint);	    len = 4;	    break;	  case PKT_CHAR:	    argchar = (unsigned char) va_arg(ap2, int);	    *p = argchar;	    len = 1;	    break;	  case PKT_DATA:	    argp = va_arg(ap2, unsigned char *);	    arglen = va_arg(ap2, int);	    memcpy(p, argp, arglen);	    len = arglen;	    break;	  case PKT_STR:	    argp = va_arg(ap2, unsigned char *);	    arglen = strlen((char *)argp);	    PUT_32BIT(p, arglen);	    memcpy(p + 4, argp, arglen);	    len = arglen + 4;	    break;	  case PKT_BIGNUM:	    bn = va_arg(ap2, Bignum);	    len = ssh1_write_bignum(p, bn);	    break;	  /* Tokens for modifications to packet logging */	  case PKTT_PASSWORD:	    dont_log_password(ssh, PKTLOG_BLANK);	    break;	  case PKTT_DATA:	    dont_log_data(ssh, PKTLOG_OMIT);	    break;	  case PKTT_OTHER:	    end_log_omission(ssh);	    break;	}	p += len;	/* Deal with logfile omission, if required. */	if (len && (ssh->pktout_logmode != PKTLOG_EMIT)) {	    ssh->pktout_nblanks++;	    ssh->pktout_blanks = sresize(ssh->pktout_blanks,					 ssh->pktout_nblanks,					 struct logblank_t);	    ssh->pktout_blanks[ssh->pktout_nblanks-1].offset = offset;	    ssh->pktout_blanks[ssh->pktout_nblanks-1].len    = len;	    ssh->pktout_blanks[ssh->pktout_nblanks-1].type   =		ssh->pktout_logmode;	}    }}static void send_packet(Ssh ssh, int pkttype, ...){    va_list ap1, ap2;    va_start(ap1, pkttype);    va_start(ap2, pkttype);    construct_packet(ssh, pkttype, ap1, ap2);    s_wrpkt(ssh);}static void defer_packet(Ssh ssh, int pkttype, ...){    va_list ap1, ap2;    va_start(ap1, pkttype);    va_start(ap2, pkttype);    construct_packet(ssh, pkttype, ap1, ap2);    s_wrpkt_defer(ssh);}static int ssh_versioncmp(char *a, char *b){    char *ae, *be;    unsigned long av, bv;    av = strtoul(a, &ae, 10);    bv = strtoul(b, &be, 10);    if (av != bv)	return (av < bv ? -1 : +1);    if (*ae == '.')	ae++;    if (*be == '.')	be++;    av = strtoul(ae, &ae, 10);    bv = strtoul(be, &be, 10);    if (av != bv)	return (av < bv ? -1 : +1);    return 0;}/* * Utility routines for putting an SSH-protocol `string' and * `uint32' into a SHA state. */#include <stdio.h>static void sha_string(SHA_State * s, void *str, int len){    unsigned char lenblk[4];    PUT_32BIT(lenblk, len);    SHA_Bytes(s, lenblk, 4);    SHA_Bytes(s, str, len);}static void sha_uint32(SHA_State * s, unsigned i){    unsigned char intblk[4];    PUT_32BIT(intblk, i);    SHA_Bytes(s, intblk, 4);}/* * SSH2 packet construction functions. */static void ssh2_pkt_ensure(Ssh ssh, int length){    if (ssh->pktout.maxlen < length) {	ssh->pktout.maxlen = length + 256;	ssh->pktout.data = sresize(ssh->pktout.data,				   ssh->pktout.maxlen + APIEXTRA,				   unsigned char);	if (!ssh->pktout.data)	    fatalbox("Out of memory");    }}static void ssh2_pkt_adddata(Ssh ssh, void *data, int len){    if (ssh->pktout_logmode != PKTLOG_EMIT) {	ssh->pktout_nblanks++;	ssh->pktout_blanks = sresize(ssh->pktout_blanks, ssh->pktout_nblanks,				     struct logblank_t);	ssh->pktout_blanks[ssh->pktout_nblanks-1].offset =	    ssh->pktout.length - 6;	ssh->pktout_blanks[ssh->pktout_nblanks-1].len = len;	ssh->pktout_blanks[ssh->pktout_nblanks-1].type = ssh->pktout_logmode;    }    ssh->pktout.length += len;    ssh2_pkt_ensure(ssh, ssh->pktout.length);    memcpy(ssh->pktout.data + ssh->pktout.length - len, data, len);}static void ssh2_pkt_addbyte(Ssh ssh, unsigned char byte){    ssh2_pkt_adddata(ssh, &byte, 1);}static void ssh2_pkt_init(Ssh ssh, int pkt_type){    ssh->pktout.length = 5;    ssh->pktout_nblanks = 0; ssh->pktout_blanks = NULL;    ssh2_pkt_addbyte(ssh, (unsigned char) pkt_type);}static void ssh2_pkt_addbool(Ssh ssh, unsigned char value){    ssh2_pkt_adddata(ssh, &value, 1);}static void ssh2_pkt_adduint32(Ssh ssh, unsigned long value){    unsigned char x[4];    PUT_32BIT(x, value);    ssh2_pkt_adddata(ssh, x, 4);}static void ssh2_pkt_addstring_start(Ssh ssh){    ssh2_pkt_adduint32(ssh, 0);    ssh->pktout.savedpos = ssh->pktout.length;}static void ssh2_pkt_addstring_str(Ssh ssh, char *data){    ssh2_pkt_adddata(ssh, data, strlen(data));    PUT_32BIT(ssh->pktout.data + ssh->pktout.savedpos - 4,	      ssh->pktout.length - ssh->pktout.savedpos);}static void ssh2_pkt_addstring_data(Ssh ssh, char *data, int len){    ssh2_pkt_adddata(ssh, data, len);    PUT_32BIT(ssh->pktout.data + ssh->pktout.savedpos - 4,	      ssh->pktout.length - ssh->pktout.savedpos);}static void ssh2_pkt_addstring(Ssh ssh, char *data){    ssh2_pkt_addstring_start(ssh);    ssh2_pkt_addstring_str(ssh, data);}static unsigned char *ssh2_mpint_fmt(Bignum b, int *len){    unsigned char *p;    int i, n = (bignum_bitcount(b) + 7) / 8;    p = snewn(n + 1, unsigned char);    if (!p)	fatalbox("out of memory");    p[0] = 0;    for (i = 1; i <= n; i++)	p[i] = bignum_byte(b, n - i);    i = 0;    while (i <= n && p[i] == 0 && (p[i + 1] & 0x80) == 0)	i++;    memmove(p, p + i, n + 1 - i);    *len = n + 1 - i;    return p;}static void ssh2_pkt_addmp(Ssh ssh, Bignum b){    unsigned char *p;    int len;    p = ssh2_mpint_fmt(b, &len);    ssh2_pkt_addstring_start(ssh);    ssh2_pkt_addstring_data(ssh, (char *)p, len);    sfree(p);}/* * Construct an SSH2 final-form packet: compress it, encrypt it, * put the MAC on it. Final packet, ready to be sent, is stored in * ssh->pktout.data. Total length is returned. */static int ssh2_pkt_construct(Ssh ssh){    int cipherblk, maclen, padding, i;    if (ssh->logctx)	log_packet(ssh->logctx, PKT_OUTGOING, ssh->pktout.data[5],		   ssh2_pkt_type(ssh->pkt_ctx, ssh->pktout.data[5]),		   ssh->pktout.data + 6, ssh->pktout.length - 6,		   ssh->pktout_nblanks, ssh->pktout_blanks);    sfree(ssh->pktout_blanks); ssh->pktout_blanks = NULL;    ssh->pktout_nblanks = 0;    /*     * Compress packet payload.     */    {	unsigned char *newpayload;	int newlen;	if (ssh->cscomp &&	    ssh->cscomp->compress(ssh->cs_comp_ctx, ssh->pktout.data + 5,				  ssh->pktout.length - 5,				  &newpayload, &newlen)) {	    ssh->pktout.length = 5;	    ssh2_pkt_adddata(ssh, newpayload, newlen);	    sfree(newpayload);	}    }    /*     * Add padding. At least four bytes, and must also bring total     * length (minus MAC) up to a multiple of the block size.     */    cipherblk = ssh->cscipher ? ssh->cscipher->blksize : 8;  /* block size */    cipherblk = cipherblk < 8 ? 8 : cipherblk;	/* or 8 if blksize < 8 */    padding = 4;    padding +=	(cipherblk - (ssh->pktout.length + padding) % cipherblk) % cipherblk;    maclen = ssh->csmac ? ssh->csmac->len : 0;    ssh2_pkt_ensure(ssh, ssh->pktout.length + padding + maclen);    ssh->pktout.data[4] = padding;    for (i = 0; i < padding; i++)	ssh->pktout.data[ssh->pktout.length + i] = random_byte();    PUT_32BIT(ssh->pktout.data, ssh->pktout.length + padding - 4);    if (ssh->csmac)	ssh->csmac->generate(ssh->cs_mac_ctx, ssh->pktout.data,			     ssh->pktout.length + padding,			     ssh->v2_outgoing_sequence);    ssh->v2_outgoing_sequence++;       /* whether or not we MACed */    if (ssh->cscipher)	ssh->cscipher->encrypt(ssh->cs_cipher_ctx,			       ssh->pktout.data, ssh->pktout.length + padding);    /* Ready-to-send packet starts at ssh->pktout.data. We return length. */    return ssh->pktout.length + padding + maclen;}/* * Construct and send an SSH2 packet immediately. */static void ssh2_pkt_send(Ssh ssh){    int len;    int backlog;    len = ssh2_pkt_construct(ssh);    backlog = sk_write(ssh->s, (char *)ssh->pktout.data, len);    if (backlog > SSH_MAX_BACKLOG)	ssh_throttle_all(ssh, 1, backlog);

⌨️ 快捷键说明

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