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

📄 pageant.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	}	attempts++;    } while (ret == -1);    /* if they typed in an ok passphrase, remember it */    if(original_pass && ret) {	char *pp = dupstr(passphrase);	addpos234(passphrases, pp, 0);    }    if (comment)	sfree(comment);    if (ret == 0) {	MessageBox(NULL, "Couldn't load private key.", APPNAME,		   MB_OK | MB_ICONERROR);	if (type == SSH_KEYTYPE_SSH1)	    sfree(rkey);	return;    }    if (type == SSH_KEYTYPE_SSH1) {	if (already_running) {	    unsigned char *request, *response;	    void *vresponse;	    int reqlen, clen, resplen, ret;	    clen = strlen(rkey->comment);	    reqlen = 4 + 1 +	       /* length, message type */		4 +		       /* bit count */		ssh1_bignum_length(rkey->modulus) +		ssh1_bignum_length(rkey->exponent) +		ssh1_bignum_length(rkey->private_exponent) +		ssh1_bignum_length(rkey->iqmp) +		ssh1_bignum_length(rkey->p) +		ssh1_bignum_length(rkey->q) + 4 + clen	/* comment */		;	    request = snewn(reqlen, unsigned char);	    request[4] = SSH1_AGENTC_ADD_RSA_IDENTITY;	    reqlen = 5;	    PUT_32BIT(request + reqlen, bignum_bitcount(rkey->modulus));	    reqlen += 4;	    reqlen += ssh1_write_bignum(request + reqlen, rkey->modulus);	    reqlen += ssh1_write_bignum(request + reqlen, rkey->exponent);	    reqlen +=		ssh1_write_bignum(request + reqlen,				  rkey->private_exponent);	    reqlen += ssh1_write_bignum(request + reqlen, rkey->iqmp);	    reqlen += ssh1_write_bignum(request + reqlen, rkey->p);	    reqlen += ssh1_write_bignum(request + reqlen, rkey->q);	    PUT_32BIT(request + reqlen, clen);	    memcpy(request + reqlen + 4, rkey->comment, clen);	    reqlen += 4 + clen;	    PUT_32BIT(request, reqlen - 4);	    ret = agent_query(request, reqlen, &vresponse, &resplen,			      NULL, NULL);	    assert(ret == 1);	    response = vresponse;	    if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS)		MessageBox(NULL, "The already running Pageant "			   "refused to add the key.", APPNAME,			   MB_OK | MB_ICONERROR);	    sfree(request);	    sfree(response);	} else {	    if (add234(rsakeys, rkey) != rkey)		sfree(rkey);	       /* already present, don't waste RAM */	}    } else {	if (already_running) {	    unsigned char *request, *response;	    void *vresponse;	    int reqlen, alglen, clen, keybloblen, resplen, ret;	    alglen = strlen(skey->alg->name);	    clen = strlen(skey->comment);	    keybloblen = skey->alg->openssh_fmtkey(skey->data, NULL, 0);	    reqlen = 4 + 1 +	       /* length, message type */		4 + alglen +	       /* algorithm name */		keybloblen +	       /* key data */		4 + clen	       /* comment */		;	    request = snewn(reqlen, unsigned char);	    request[4] = SSH2_AGENTC_ADD_IDENTITY;	    reqlen = 5;	    PUT_32BIT(request + reqlen, alglen);	    reqlen += 4;	    memcpy(request + reqlen, skey->alg->name, alglen);	    reqlen += alglen;	    reqlen += skey->alg->openssh_fmtkey(skey->data,						request + reqlen,						keybloblen);	    PUT_32BIT(request + reqlen, clen);	    memcpy(request + reqlen + 4, skey->comment, clen);	    reqlen += clen + 4;	    PUT_32BIT(request, reqlen - 4);	    ret = agent_query(request, reqlen, &vresponse, &resplen,			      NULL, NULL);	    assert(ret == 1);	    response = vresponse;	    if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS)		MessageBox(NULL, "The already running Pageant "			   "refused to add the key.", APPNAME,			   MB_OK | MB_ICONERROR);	    sfree(request);	    sfree(response);	} else {	    if (add234(ssh2keys, skey) != skey) {		skey->alg->freekey(skey->data);		sfree(skey);	       /* already present, don't waste RAM */	    }	}    }}/* * Create an SSH1 key list in a malloc'ed buffer; return its * length. */static void *make_keylist1(int *length){    int i, nkeys, len;    struct RSAKey *key;    unsigned char *blob, *p, *ret;    int bloblen;    /*     * Count up the number and length of keys we hold.     */    len = 4;    nkeys = 0;    for (i = 0; NULL != (key = index234(rsakeys, i)); i++) {	nkeys++;	blob = rsa_public_blob(key, &bloblen);	len += bloblen;	sfree(blob);	len += 4 + strlen(key->comment);    }    /* Allocate the buffer. */    p = ret = snewn(len, unsigned char);    if (length) *length = len;    PUT_32BIT(p, nkeys);    p += 4;    for (i = 0; NULL != (key = index234(rsakeys, i)); i++) {	blob = rsa_public_blob(key, &bloblen);	memcpy(p, blob, bloblen);	p += bloblen;	sfree(blob);	PUT_32BIT(p, strlen(key->comment));	memcpy(p + 4, key->comment, strlen(key->comment));	p += 4 + strlen(key->comment);    }    assert(p - ret == len);    return ret;}/* * Create an SSH2 key list in a malloc'ed buffer; return its * length. */static void *make_keylist2(int *length){    struct ssh2_userkey *key;    int i, len, nkeys;    unsigned char *blob, *p, *ret;    int bloblen;    /*     * Count up the number and length of keys we hold.     */    len = 4;    nkeys = 0;    for (i = 0; NULL != (key = index234(ssh2keys, i)); i++) {	nkeys++;	len += 4;	       /* length field */	blob = key->alg->public_blob(key->data, &bloblen);	len += bloblen;	sfree(blob);	len += 4 + strlen(key->comment);    }    /* Allocate the buffer. */    p = ret = snewn(len, unsigned char);    if (length) *length = len;    /*     * Packet header is the obvious five bytes, plus four     * bytes for the key count.     */    PUT_32BIT(p, nkeys);    p += 4;    for (i = 0; NULL != (key = index234(ssh2keys, i)); i++) {	blob = key->alg->public_blob(key->data, &bloblen);	PUT_32BIT(p, bloblen);	p += 4;	memcpy(p, blob, bloblen);	p += bloblen;	sfree(blob);	PUT_32BIT(p, strlen(key->comment));	memcpy(p + 4, key->comment, strlen(key->comment));	p += 4 + strlen(key->comment);    }    assert(p - ret == len);    return ret;}/* * Acquire a keylist1 from the primary Pageant; this means either * calling make_keylist1 (if that's us) or sending a message to the * primary Pageant (if it's not). */static void *get_keylist1(int *length){    void *ret;    if (already_running) {	unsigned char request[5], *response;	void *vresponse;	int resplen, retval;	request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES;	PUT_32BIT(request, 4);	retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL);	assert(retval == 1);	response = vresponse;	if (resplen < 5 || response[4] != SSH1_AGENT_RSA_IDENTITIES_ANSWER)	    return NULL;	ret = snewn(resplen-5, unsigned char);	memcpy(ret, response+5, resplen-5);	sfree(response);	if (length)	    *length = resplen-5;    } else {	ret = make_keylist1(length);    }    return ret;}/* * Acquire a keylist2 from the primary Pageant; this means either * calling make_keylist2 (if that's us) or sending a message to the * primary Pageant (if it's not). */static void *get_keylist2(int *length){    void *ret;    if (already_running) {	unsigned char request[5], *response;	void *vresponse;	int resplen, retval;	request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;	PUT_32BIT(request, 4);	retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL);	assert(retval == 1);	response = vresponse;	if (resplen < 5 || response[4] != SSH2_AGENT_IDENTITIES_ANSWER)	    return NULL;	ret = snewn(resplen-5, unsigned char);	memcpy(ret, response+5, resplen-5);	sfree(response);	if (length)	    *length = resplen-5;    } else {	ret = make_keylist2(length);    }    return ret;}/* * This is the main agent function that answers messages. */static void answer_msg(void *msg){    unsigned char *p = msg;    unsigned char *ret = msg;    unsigned char *msgend;    int type;    /*     * Get the message length.     */    msgend = p + 4 + GET_32BIT(p);    /*     * Get the message type.     */    if (msgend < p+5)	goto failure;    type = p[4];    p += 5;    switch (type) {      case SSH1_AGENTC_REQUEST_RSA_IDENTITIES:	/*	 * Reply with SSH1_AGENT_RSA_IDENTITIES_ANSWER.	 */	{	    int len;	    void *keylist;	    ret[4] = SSH1_AGENT_RSA_IDENTITIES_ANSWER;	    keylist = make_keylist1(&len);	    if (len + 5 > AGENT_MAX_MSGLEN) {		sfree(keylist);		goto failure;	    }	    PUT_32BIT(ret, len + 1);	    memcpy(ret + 5, keylist, len);	    sfree(keylist);	}	break;      case SSH2_AGENTC_REQUEST_IDENTITIES:	/*	 * Reply with SSH2_AGENT_IDENTITIES_ANSWER.	 */	{	    int len;	    void *keylist;	    ret[4] = SSH2_AGENT_IDENTITIES_ANSWER;	    keylist = make_keylist2(&len);	    if (len + 5 > AGENT_MAX_MSGLEN) {		sfree(keylist);		goto failure;	    }	    PUT_32BIT(ret, len + 1);	    memcpy(ret + 5, keylist, len);	    sfree(keylist);	}	break;      case SSH1_AGENTC_RSA_CHALLENGE:	/*	 * Reply with either SSH1_AGENT_RSA_RESPONSE or	 * SSH_AGENT_FAILURE, depending on whether we have that key	 * or not.	 */	{	    struct RSAKey reqkey, *key;	    Bignum challenge, response;	    unsigned char response_source[48], response_md5[16];	    struct MD5Context md5c;	    int i, len;	    p += 4;	    i = ssh1_read_bignum(p, msgend - p, &reqkey.exponent);	    if (i < 0)		goto failure;	    p += i;	    i = ssh1_read_bignum(p, msgend - p, &reqkey.modulus);	    if (i < 0)		goto failure;	    p += i;	    i = ssh1_read_bignum(p, msgend - p, &challenge);	    if (i < 0)		goto failure;	    p += i;	    if (msgend < p+16) {		freebn(reqkey.exponent);		freebn(reqkey.modulus);		freebn(challenge);		goto failure;	    }	    memcpy(response_source + 32, p, 16);	    p += 16;	    if (msgend < p+4 ||		GET_32BIT(p) != 1 ||		(key = find234(rsakeys, &reqkey, NULL)) == NULL) {		freebn(reqkey.exponent);		freebn(reqkey.modulus);		freebn(challenge);		goto failure;	    }	    response = rsadecrypt(challenge, key);	    for (i = 0; i < 32; i++)		response_source[i] = bignum_byte(response, 31 - i);	    MD5Init(&md5c);	    MD5Update(&md5c, response_source, 48);	    MD5Final(response_md5, &md5c);	    memset(response_source, 0, 48);	/* burn the evidence */	    freebn(response);	       /* and that evidence */	    freebn(challenge);	       /* yes, and that evidence */	    freebn(reqkey.exponent);   /* and free some memory ... */	    freebn(reqkey.modulus);    /* ... while we're at it. */	    /*	     * Packet is the obvious five byte header, plus sixteen	     * bytes of MD5.	     */	    len = 5 + 16;	    PUT_32BIT(ret, len - 4);	    ret[4] = SSH1_AGENT_RSA_RESPONSE;	    memcpy(ret + 5, response_md5, 16);	}	break;      case SSH2_AGENTC_SIGN_REQUEST:	/*	 * Reply with either SSH2_AGENT_SIGN_RESPONSE or	 * SSH_AGENT_FAILURE, depending on whether we have that key	 * or not.	 */	{	    struct ssh2_userkey *key;	    struct blob b;	    unsigned char *data, *signature;	    int datalen, siglen, len;	    if (msgend < p+4)		goto failure;	    b.len = GET_32BIT(p);	    p += 4;	    if (msgend < p+b.len)		goto failure;	    b.blob = p;	    p += b.len;	    if (msgend < p+4)		goto failure;	    datalen = GET_32BIT(p);	    p += 4;	    if (msgend < p+datalen)		goto failure;	    data = p;	    key = find234(ssh2keys, &b, cmpkeys_ssh2_asymm);	    if (!key)		goto failure;	    signature = key->alg->sign(key->data, data, datalen, &siglen);	    len = 5 + 4 + siglen;	    PUT_32BIT(ret, len - 4);	    ret[4] = SSH2_AGENT_SIGN_RESPONSE;	    PUT_32BIT(ret + 5, siglen);	    memcpy(ret + 5 + 4, signature, siglen);	    sfree(signature);	}	break;      case SSH1_AGENTC_ADD_RSA_IDENTITY:	/*	 * Add to the list and return SSH_AGENT_SUCCESS, or	 * SSH_AGENT_FAILURE if the key was malformed.	 */	{	    struct RSAKey *key;	    char *comment;            int n, commentlen;	    key = snew(struct RSAKey);	    memset(key, 0, sizeof(struct RSAKey));	    n = makekey(p, msgend - p, key, NULL, 1);	    if (n < 0) {		freersakey(key);		sfree(key);		goto failure;	    }	    p += n;	    n = makeprivate(p, msgend - p, key);	    if (n < 0) {		freersakey(key);		sfree(key);		goto failure;	    }	    p += n;	    n = ssh1_read_bignum(p, msgend - p, &key->iqmp);  /* p^-1 mod q */	    if (n < 0) {		freersakey(key);		sfree(key);		goto failure;	    }	    p += n;	    n = ssh1_read_bignum(p, msgend - p, &key->p);  /* p */	    if (n < 0) {		freersakey(key);		sfree(key);		goto failure;	    }	    p += n;	    n = ssh1_read_bignum(p, msgend - p, &key->q);  /* q */	    if (n < 0) {		freersakey(key);		sfree(key);		goto failure;	    }	    p += n;	    if (msgend < p+4) {		freersakey(key);		sfree(key);		goto failure;	    }            commentlen = GET_32BIT(p);	    if (msgend < p+commentlen) {		freersakey(key);		sfree(key);		goto failure;	    }	    comment = snewn(commentlen+1, char);	    if (comment) {		memcpy(comment, p + 4, commentlen);                comment[commentlen] = '\0';		key->comment = comment;	    }	    PUT_32BIT(ret, 1);	    ret[4] = SSH_AGENT_FAILURE;	    if (add234(rsakeys, key) == key) {		keylist_update();		ret[4] = SSH_AGENT_SUCCESS;	    } else {		freersakey(key);		sfree(key);	    }	}	break;      case SSH2_AGENTC_ADD_IDENTITY:	/*	 * Add to the list and return SSH_AGENT_SUCCESS, or	 * SSH_AGENT_FAILURE if the key was malformed.	 */	{	    struct ssh2_userkey *key;	    char *comment, *alg;	    int alglen, commlen;	    int bloblen;	    if (msgend < p+4)		goto failure;	    alglen = GET_32BIT(p);	    p += 4;	    if (msgend < p+alglen)		goto failure;

⌨️ 快捷键说明

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