Exemple #1
0
int
ssh_remove_identity(AuthenticationConnection *auth, Key *key)
{
	Buffer msg;
	int type;
	u_char *blob;
	u_int blen;

	pamsshagentauth_buffer_init(&msg);

	if (key->type == KEY_RSA1) {
		pamsshagentauth_buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY);
		pamsshagentauth_buffer_put_int(&msg, BN_num_bits(key->rsa->n));
		pamsshagentauth_buffer_put_bignum(&msg, key->rsa->e);
		pamsshagentauth_buffer_put_bignum(&msg, key->rsa->n);
	} else if (key->type == KEY_DSA || key->type == KEY_RSA) {
		pamsshagentauth_key_to_blob(key, &blob, &blen);
		pamsshagentauth_buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
		pamsshagentauth_buffer_put_string(&msg, blob, blen);
		pamsshagentauth_xfree(blob);
	} else {
		pamsshagentauth_buffer_free(&msg);
		return 0;
	}
	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		pamsshagentauth_buffer_free(&msg);
		return 0;
	}
	type = pamsshagentauth_buffer_get_char(&msg);
	pamsshagentauth_buffer_free(&msg);
	return pamsshagentauth_decode_reply(type);
}
Exemple #2
0
/*
 * Add/remove an token-based identity from the authentication server.
 * This call is intended only for use by ssh-add(1) and like applications.
 */
int
ssh_update_card(int sock, int add, const char *reader_id, const char *pin,
    u_int life, u_int confirm)
{
	struct sshbuf *msg;
	int r, constrained = (life || confirm);
	u_char type;

	if (add) {
		type = constrained ?
		    SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED :
		    SSH_AGENTC_ADD_SMARTCARD_KEY;
	} else
		type = SSH_AGENTC_REMOVE_SMARTCARD_KEY;

	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshbuf_put_u8(msg, type)) != 0 ||
	    (r = sshbuf_put_cstring(msg, reader_id)) != 0 ||
	    (r = sshbuf_put_cstring(msg, pin)) != 0)
		goto out;
	if (constrained &&
	    (r = encode_constraints(msg, life, confirm)) != 0)
		goto out;
	if ((r = ssh_request_reply(sock, msg, msg)) != 0)
		goto out;
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	r = decode_reply(type);
 out:
	sshbuf_free(msg);
	return r;
}
Exemple #3
0
int
ssh_remove_identity(AuthenticationConnection *auth, Key *key)
{
	Buffer msg;
	int type;
	u_char *blob;
	u_int blen;

	buffer_init(&msg);

#ifdef WITH_SSH1
	if (key->type == KEY_RSA1) {
		buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY);
		buffer_put_int(&msg, BN_num_bits(key->rsa->n));
		buffer_put_bignum(&msg, key->rsa->e);
		buffer_put_bignum(&msg, key->rsa->n);
	} else
#endif
	if (key->type != KEY_UNSPEC) {
		key_to_blob(key, &blob, &blen);
		buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
		buffer_put_string(&msg, blob, blen);
		free(blob);
	} else {
		buffer_free(&msg);
		return 0;
	}
	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		buffer_free(&msg);
		return 0;
	}
	type = buffer_get_char(&msg);
	buffer_free(&msg);
	return decode_reply(type);
}
Exemple #4
0
/*
 * Adds an identity to the authentication server.
 * This call is intended only for use by ssh-add(1) and like applications.
 */
int
ssh_add_identity_constrained(int sock, struct sshkey *key, const char *comment,
    u_int life, u_int confirm)
{
	struct sshbuf *msg;
	int r, constrained = (life || confirm);
	u_char type;

	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;

	switch (key->type) {
#ifdef WITH_SSH1
	case KEY_RSA1:
		type = constrained ?
		    SSH_AGENTC_ADD_RSA_ID_CONSTRAINED :
		    SSH_AGENTC_ADD_RSA_IDENTITY;
		if ((r = sshbuf_put_u8(msg, type)) != 0 ||
		    (r = ssh_encode_identity_rsa1(msg, key->rsa, comment)) != 0)
			goto out;
		break;
#endif
#ifdef WITH_OPENSSL
	case KEY_RSA:
	case KEY_RSA_CERT:
	case KEY_RSA_CERT_V00:
	case KEY_DSA:
	case KEY_DSA_CERT:
	case KEY_DSA_CERT_V00:
	case KEY_ECDSA:
	case KEY_ECDSA_CERT:
#endif
	case KEY_ED25519:
	case KEY_ED25519_CERT:
		type = constrained ?
		    SSH2_AGENTC_ADD_ID_CONSTRAINED :
		    SSH2_AGENTC_ADD_IDENTITY;
		if ((r = sshbuf_put_u8(msg, type)) != 0 ||
		    (r = ssh_encode_identity_ssh2(msg, key, comment)) != 0)
			goto out;
		break;
	default:
		r = SSH_ERR_INVALID_ARGUMENT;
		goto out;
	}
	if (constrained &&
	    (r = encode_constraints(msg, life, confirm)) != 0)
		goto out;
	if ((r = ssh_request_reply(sock, msg, msg)) != 0)
		goto out;
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	r = decode_reply(type);
 out:
	sshbuf_free(msg);
	return r;
}
Exemple #5
0
int
ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
    const char *comment, u_int life, u_int confirm)
{
	Buffer msg;
	int type, constrained = (life || confirm);

	buffer_init(&msg);

	switch (key->type) {
#ifdef WITH_SSH1
	case KEY_RSA1:
		type = constrained ?
		    SSH_AGENTC_ADD_RSA_ID_CONSTRAINED :
		    SSH_AGENTC_ADD_RSA_IDENTITY;
		buffer_put_char(&msg, type);
		ssh_encode_identity_rsa1(&msg, key->rsa, comment);
		break;
#endif
#ifdef WITH_OPENSSL
	case KEY_RSA:
	case KEY_RSA_CERT:
	case KEY_RSA_CERT_V00:
	case KEY_DSA:
	case KEY_DSA_CERT:
	case KEY_DSA_CERT_V00:
	case KEY_ECDSA:
	case KEY_ECDSA_CERT:
#endif
	case KEY_ED25519:
	case KEY_ED25519_CERT:
		type = constrained ?
		    SSH2_AGENTC_ADD_ID_CONSTRAINED :
		    SSH2_AGENTC_ADD_IDENTITY;
		buffer_put_char(&msg, type);
		ssh_encode_identity_ssh2(&msg, key, comment);
		break;
	default:
		buffer_free(&msg);
		return 0;
	}
	if (constrained) {
		if (life != 0) {
			buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME);
			buffer_put_int(&msg, life);
		}
		if (confirm != 0)
			buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM);
	}
	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		buffer_free(&msg);
		return 0;
	}
	type = buffer_get_char(&msg);
	buffer_free(&msg);
	return decode_reply(type);
}
/* ask agent to sign data, returns err.h code on error, 0 on success */
int
ssh_agent_sign(int sock, struct sshkey *key,
    u_char **sigp, size_t *lenp,
    const u_char *data, size_t datalen, u_int compat)
{
	struct sshbuf *msg;
	u_char *blob = NULL, type;
	size_t blen = 0, len = 0;
	u_int flags = 0;
	int r = SSH_ERR_INTERNAL_ERROR;

	if (sigp != NULL)
		*sigp = NULL;
	if (lenp != NULL)
		*lenp = 0;

	if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
		return SSH_ERR_INVALID_ARGUMENT;
	if (compat & SSH_BUG_SIGBLOB)
		flags |= SSH_AGENT_OLD_SIGNATURE;
	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshkey_to_blob(key, &blob, &blen)) != 0)
		goto out;
	if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
	    (r = sshbuf_put_string(msg, blob, blen)) != 0 ||
	    (r = sshbuf_put_string(msg, data, datalen)) != 0 ||
	    (r = sshbuf_put_u32(msg, flags)) != 0)
		goto out;
	if ((r = ssh_request_reply(sock, msg, msg) != 0))
		goto out;
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	if (agent_failed(type)) {
		r = SSH_ERR_AGENT_FAILURE;
		goto out;
	} else if (type != SSH2_AGENT_SIGN_RESPONSE) {
		r = SSH_ERR_INVALID_FORMAT;
		goto out;
	}
	if ((r = sshbuf_get_string(msg, sigp, &len)) != 0)
		goto out;
	*lenp = len;
	r = 0;
 out:
	if (blob != NULL) {
		explicit_bzero(blob, blen);
		free(blob);
	}
	sshbuf_free(msg);
	return r;
}
Exemple #7
0
int
ssh_decrypt_challenge(AuthenticationConnection *auth,
    Key* key, BIGNUM *challenge,
    u_char session_id[16],
    u_int response_type,
    u_char response[16])
{
	Buffer buffer;
	int success = 0;
	int i;
	int type;

	if (key->type != KEY_RSA1)
		return 0;
	if (response_type == 0) {
		pamsshagentauth_logit("Compatibility with ssh protocol version 1.0 no longer supported.");
		return 0;
	}
	pamsshagentauth_buffer_init(&buffer);
	pamsshagentauth_buffer_put_char(&buffer, SSH_AGENTC_RSA_CHALLENGE);
	pamsshagentauth_buffer_put_int(&buffer, BN_num_bits(key->rsa->n));
	pamsshagentauth_buffer_put_bignum(&buffer, key->rsa->e);
	pamsshagentauth_buffer_put_bignum(&buffer, key->rsa->n);
	pamsshagentauth_buffer_put_bignum(&buffer, challenge);
	pamsshagentauth_buffer_append(&buffer, session_id, 16);
	pamsshagentauth_buffer_put_int(&buffer, response_type);

	if (ssh_request_reply(auth, &buffer, &buffer) == 0) {
		pamsshagentauth_buffer_free(&buffer);
		return 0;
	}
	type = pamsshagentauth_buffer_get_char(&buffer);

	if (agent_failed(type)) {
		pamsshagentauth_logit("Agent admitted failure to authenticate using the key.");
	} else if (type != SSH_AGENT_RSA_RESPONSE) {
		pamsshagentauth_fatal("Bad authentication response: %d", type);
	} else {
		success = 1;
		/*
		 * Get the response from the packet.  This will abort with a
		 * fatal error if the packet is corrupt.
		 */
		for (i = 0; i < 16; i++)
			response[i] = (u_char)pamsshagentauth_buffer_get_char(&buffer);
	}
	pamsshagentauth_buffer_free(&buffer);
	return success;
}
Exemple #8
0
int
ssh_get_num_identities(AuthenticationConnection *auth, int version)
{
	int type, code1 = 0, code2 = 0;
	Buffer request;

	switch (version) {
	case 1:
		code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
		code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER;
		break;
	case 2:
		code1 = SSH2_AGENTC_REQUEST_IDENTITIES;
		code2 = SSH2_AGENT_IDENTITIES_ANSWER;
		break;
	default:
		return 0;
	}

	/*
	 * Send a message to the agent requesting for a list of the
	 * identities it can represent.
	 */
	pamsshagentauth_buffer_init(&request);
	pamsshagentauth_buffer_put_char(&request, code1);

	pamsshagentauth_buffer_clear(&auth->identities);
	if (ssh_request_reply(auth, &request, &auth->identities) == 0) {
		pamsshagentauth_buffer_free(&request);
		return 0;
	}
	pamsshagentauth_buffer_free(&request);

	/* Get message type, and verify that we got a proper answer. */
	type = pamsshagentauth_buffer_get_char(&auth->identities);
	if (agent_failed(type)) {
		return 0;
	} else if (type != code2) {
		pamsshagentauth_fatal("Bad authentication reply message type: %d", type);
	}

	/* Get the number of entries in the response and check it for sanity. */
	auth->howmany = pamsshagentauth_buffer_get_int(&auth->identities);
	if ((u_int)auth->howmany > 1024)
		pamsshagentauth_fatal("Too many identities in authentication reply: %d",
		    auth->howmany);

	return auth->howmany;
}
Exemple #9
0
int
ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
    const char *comment, u_int life, u_int confirm)
{
	Buffer msg;
	int type, constrained = (life || confirm);

	pamsshagentauth_buffer_init(&msg);

	switch (key->type) {
	case KEY_RSA1:
		type = constrained ?
		    SSH_AGENTC_ADD_RSA_ID_CONSTRAINED :
		    SSH_AGENTC_ADD_RSA_IDENTITY;
		pamsshagentauth_buffer_put_char(&msg, type);
		ssh_encode_identity_rsa1(&msg, key->rsa, comment);
		break;
	case KEY_RSA:
	case KEY_DSA:
		type = constrained ?
		    SSH2_AGENTC_ADD_ID_CONSTRAINED :
		    SSH2_AGENTC_ADD_IDENTITY;
		pamsshagentauth_buffer_put_char(&msg, type);
		ssh_encode_identity_ssh2(&msg, key, comment);
		break;
	default:
		pamsshagentauth_buffer_free(&msg);
		return 0;
	}
	if (constrained) {
		if (life != 0) {
			pamsshagentauth_buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME);
			pamsshagentauth_buffer_put_int(&msg, life);
		}
		if (confirm != 0)
			pamsshagentauth_buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM);
	}
	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		pamsshagentauth_buffer_free(&msg);
		return 0;
	}
	type = pamsshagentauth_buffer_get_char(&msg);
	pamsshagentauth_buffer_free(&msg);
	return pamsshagentauth_decode_reply(type);
}
Exemple #10
0
/*
 * Removes an identity from the authentication server.
 * This call is intended only for use by ssh-add(1) and like applications.
 */
int
ssh_remove_identity(int sock, struct sshkey *key)
{
	struct sshbuf *msg;
	int r;
	u_char type, *blob = NULL;
	size_t blen;

	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;

#ifdef WITH_SSH1
	if (key->type == KEY_RSA1) {
		if ((r = sshbuf_put_u8(msg,
		    SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 ||
		    (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
		    (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
		    (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0)
			goto out;
	} else
#endif
	if (key->type != KEY_UNSPEC) {
		if ((r = sshkey_to_blob(key, &blob, &blen)) != 0)
			goto out;
		if ((r = sshbuf_put_u8(msg,
		    SSH2_AGENTC_REMOVE_IDENTITY)) != 0 ||
		    (r = sshbuf_put_string(msg, blob, blen)) != 0)
			goto out;
	} else {
		r = SSH_ERR_INVALID_ARGUMENT;
		goto out;
	}
	if ((r = ssh_request_reply(sock, msg, msg)) != 0)
		goto out;
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	r = decode_reply(type);
 out:
	if (blob != NULL) {
		explicit_bzero(blob, blen);
		free(blob);
	}
	sshbuf_free(msg);
	return r;
}
Exemple #11
0
/* Lock/unlock agent */
int
ssh_lock_agent(AuthenticationConnection *auth, int lock, const char *password)
{
	int type;
	Buffer msg;

	pamsshagentauth_buffer_init(&msg);
	pamsshagentauth_buffer_put_char(&msg, lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK);
	pamsshagentauth_buffer_put_cstring(&msg, password);

	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		pamsshagentauth_buffer_free(&msg);
		return 0;
	}
	type = pamsshagentauth_buffer_get_char(&msg);
	pamsshagentauth_buffer_free(&msg);
	return pamsshagentauth_decode_reply(type);
}
int
ssh_update_card(AuthenticationConnection *auth, int add, const char *reader_id, const char *pin)
{
	Buffer msg;
	int type;

	buffer_init(&msg);
	buffer_put_char(&msg, add ? SSH_AGENTC_ADD_SMARTCARD_KEY :
	    SSH_AGENTC_REMOVE_SMARTCARD_KEY);
	buffer_put_cstring(&msg, reader_id);
	buffer_put_cstring(&msg, pin);
	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		buffer_free(&msg);
		return 0;
	}
	type = buffer_get_char(&msg);
	buffer_free(&msg);
	return decode_reply(type);
}
Exemple #13
0
/* ask agent to sign data, returns -1 on error, 0 on success */
int
ssh_agent_sign(AuthenticationConnection *auth,
    Key *key,
    u_char **sigp, u_int *lenp,
    u_char *data, u_int datalen)
{
	extern int datafellows;
	Buffer msg;
	u_char *blob;
	u_int blen;
	int type, flags = 0;
	int ret = -1;

	if (pamsshagentauth_key_to_blob(key, &blob, &blen) == 0)
		return -1;

	if (datafellows & SSH_BUG_SIGBLOB)
		flags = SSH_AGENT_OLD_SIGNATURE;

	pamsshagentauth_buffer_init(&msg);
	pamsshagentauth_buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST);
	pamsshagentauth_buffer_put_string(&msg, blob, blen);
	pamsshagentauth_buffer_put_string(&msg, data, datalen);
	pamsshagentauth_buffer_put_int(&msg, flags);
	pamsshagentauth_xfree(blob);

	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		pamsshagentauth_buffer_free(&msg);
		return -1;
	}
	type = pamsshagentauth_buffer_get_char(&msg);
	if (agent_failed(type)) {
		pamsshagentauth_logit("Agent admitted failure to sign using the key.");
	} else if (type != SSH2_AGENT_SIGN_RESPONSE) {
		pamsshagentauth_fatal("Bad authentication response: %d", type);
	} else {
		ret = 0;
		*sigp = pamsshagentauth_buffer_get_string(&msg, lenp);
	}
	pamsshagentauth_buffer_free(&msg);
	return ret;
}
Exemple #14
0
int
ssh_remove_all_identities(AuthenticationConnection *auth, int version)
{
	Buffer msg;
	int type;
	int code = (version==1) ?
		SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES :
		SSH2_AGENTC_REMOVE_ALL_IDENTITIES;

	pamsshagentauth_buffer_init(&msg);
	pamsshagentauth_buffer_put_char(&msg, code);

	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		pamsshagentauth_buffer_free(&msg);
		return 0;
	}
	type = pamsshagentauth_buffer_get_char(&msg);
	pamsshagentauth_buffer_free(&msg);
	return pamsshagentauth_decode_reply(type);
}
Exemple #15
0
/* Lock/unlock agent */
int
ssh_lock_agent(int sock, int lock, const char *password)
{
	int r;
	u_char type = lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK;
	struct sshbuf *msg;

	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshbuf_put_u8(msg, type)) != 0 ||
	    (r = sshbuf_put_cstring(msg, password)) != 0)
		goto out;
	if ((r = ssh_request_reply(sock, msg, msg)) != 0)
		goto out;
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	r = decode_reply(type);
 out:
	sshbuf_free(msg);
	return r;
}
Exemple #16
0
/*
 * Removes all identities from the agent.
 * This call is intended only for use by ssh-add(1) and like applications.
 */
int
ssh_remove_all_identities(int sock, int version)
{
	struct sshbuf *msg;
	u_char type = (version == 1) ?
	    SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES :
	    SSH2_AGENTC_REMOVE_ALL_IDENTITIES;
	int r;

	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshbuf_put_u8(msg, type)) != 0)
		goto out;
	if ((r = ssh_request_reply(sock, msg, msg)) != 0)
		goto out;
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	r = decode_reply(type);
 out:
	sshbuf_free(msg);
	return r;
}
Exemple #17
0
int
ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
    u_char session_id[16], u_char response[16])
{
	struct sshbuf *msg;
	int r;
	u_char type;

	if (key->type != KEY_RSA1)
		return SSH_ERR_INVALID_ARGUMENT;
	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 ||
	    (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
	    (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
	    (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 ||
	    (r = sshbuf_put_bignum1(msg, challenge)) != 0 ||
	    (r = sshbuf_put(msg, session_id, 16)) != 0 ||
	    (r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */
		goto out;
	if ((r = ssh_request_reply(sock, msg, msg)) != 0)
		goto out;
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	if (agent_failed(type)) {
		r = SSH_ERR_AGENT_FAILURE;
		goto out;
	} else if (type != SSH_AGENT_RSA_RESPONSE) {
		r = SSH_ERR_INVALID_FORMAT;
		goto out;
	}
	if ((r = sshbuf_get(msg, response, 16)) != 0)
		goto out;
	r = 0;
 out:
	sshbuf_free(msg);
	return r;
}
Exemple #18
0
int
ssh_update_card(AuthenticationConnection *auth, int add,
    const char *reader_id, const char *pin, u_int life, u_int confirm)
{
	Buffer msg;
	int type, constrained = (life || confirm);

	if (add) {
		type = constrained ?
		    SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED :
		    SSH_AGENTC_ADD_SMARTCARD_KEY;
	} else
		type = SSH_AGENTC_REMOVE_SMARTCARD_KEY;

	pamsshagentauth_buffer_init(&msg);
	pamsshagentauth_buffer_put_char(&msg, type);
	pamsshagentauth_buffer_put_cstring(&msg, reader_id);
	pamsshagentauth_buffer_put_cstring(&msg, pin);

	if (constrained) {
		if (life != 0) {
			pamsshagentauth_buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME);
			pamsshagentauth_buffer_put_int(&msg, life);
		}
		if (confirm != 0)
			pamsshagentauth_buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM);
	}

	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		pamsshagentauth_buffer_free(&msg);
		return 0;
	}
	type = pamsshagentauth_buffer_get_char(&msg);
	pamsshagentauth_buffer_free(&msg);
	return pamsshagentauth_decode_reply(type);
}
Exemple #19
0
/*
 * Fetch list of identities held by the agent.
 */
int
ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp)
{
	u_char type, code1 = 0, code2 = 0;
	u_int32_t num, i;
	struct sshbuf *msg;
	struct ssh_identitylist *idl = NULL;
	int r;

	/* Determine request and expected response types */
	switch (version) {
	case 1:
		code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
		code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER;
		break;
	case 2:
		code1 = SSH2_AGENTC_REQUEST_IDENTITIES;
		code2 = SSH2_AGENT_IDENTITIES_ANSWER;
		break;
	default:
		return SSH_ERR_INVALID_ARGUMENT;
	}

	/*
	 * Send a message to the agent requesting for a list of the
	 * identities it can represent.
	 */
	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshbuf_put_u8(msg, code1)) != 0)
		goto out;

	if ((r = ssh_request_reply(sock, msg, msg)) != 0)
		goto out;

	/* Get message type, and verify that we got a proper answer. */
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	if (agent_failed(type)) {
		r = SSH_ERR_AGENT_FAILURE;
		goto out;
	} else if (type != code2) {
		r = SSH_ERR_INVALID_FORMAT;
		goto out;
	}

	/* Get the number of entries in the response and check it for sanity. */
	if ((r = sshbuf_get_u32(msg, &num)) != 0)
		goto out;
	if (num > MAX_AGENT_IDENTITIES) {
		r = SSH_ERR_INVALID_FORMAT;
		goto out;
	}
	if (num == 0) {
		r = SSH_ERR_AGENT_NO_IDENTITIES;
		goto out;
	}

	/* Deserialise the response into a list of keys/comments */
	if ((idl = calloc(1, sizeof(*idl))) == NULL ||
	    (idl->keys = calloc(num, sizeof(*idl->keys))) == NULL ||
	    (idl->comments = calloc(num, sizeof(*idl->comments))) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	for (i = 0; i < num;) {
		switch (version) {
		case 1:
#ifdef WITH_SSH1
			if ((r = deserialise_identity1(msg,
			    &(idl->keys[i]), &(idl->comments[i]))) != 0)
				goto out;
#endif
			break;
		case 2:
			if ((r = deserialise_identity2(msg,
			    &(idl->keys[i]), &(idl->comments[i]))) != 0) {
				if (r == SSH_ERR_KEY_TYPE_UNKNOWN) {
					/* Gracefully skip unknown key types */
					num--;
					continue;
				} else
					goto out;
			}
			break;
		}
		i++;
	}
	idl->nkeys = num;
	*idlp = idl;
	idl = NULL;
	r = 0;
 out:
	sshbuf_free(msg);
	if (idl != NULL)
		ssh_free_identitylist(idl);
	return r;
}