int ssh_agent_present(void) { int authfd; if (agent_present) return 1; if ((authfd = ssh_get_authentication_socket()) == -1) return 0; else { ssh_close_authentication_socket(authfd); return 1; } }
AuthenticationConnection * ssh_get_authentication_connection(uid_t uid) { AuthenticationConnection *auth; int sock; sock = ssh_get_authentication_socket(uid); /* * Fail if we couldn't obtain a connection. This happens if we * exited due to a timeout. */ if (sock < 0) return NULL; auth = pamsshagentauth_xmalloc(sizeof(*auth)); auth->fd = sock; pamsshagentauth_buffer_init(&auth->identities); auth->howmany = 0; return auth; }
/* * Checks if the user has an authentication agent, and if so, tries to * authenticate using the agent. */ static int try_agent_authentication(struct ssh *ssh) { int r, type, agent_fd, ret = 0; u_char response[16]; size_t i; BIGNUM *challenge; struct ssh_identitylist *idlist = NULL; /* Get connection to the agent. */ if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) { if (r != SSH_ERR_AGENT_NOT_PRESENT) debug("%s: ssh_get_authentication_socket: %s", __func__, ssh_err(r)); return 0; } if ((challenge = BN_new()) == NULL) fatal("try_agent_authentication: BN_new failed"); /* Loop through identities served by the agent. */ if ((r = ssh_fetch_identitylist(agent_fd, 1, &idlist)) != 0) { if (r != SSH_ERR_AGENT_NO_IDENTITIES) debug("%s: ssh_fetch_identitylist: %s", __func__, ssh_err(r)); goto out; } for (i = 0; i < idlist->nkeys; i++) { /* Try this identity. */ debug("Trying RSA authentication via agent with '%.100s'", idlist->comments[i]); /* * Tell the server that we are willing to authenticate * using this key. */ if ((r = sshpkt_start(ssh, SSH_CMSG_AUTH_RSA)) != 0 || (r = sshpkt_put_bignum1(ssh, idlist->keys[i]->rsa->n)) != 0 || (r = sshpkt_send(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); ssh_packet_write_wait(ssh); /* Wait for server's response. */ type = ssh_packet_read(ssh); /* The server sends failure if it doesn't like our key or does not support RSA authentication. */ if (type == SSH_SMSG_FAILURE) { debug("Server refused our key."); continue; } /* Otherwise it should have sent a challenge. */ if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) ssh_packet_disconnect(ssh, "Protocol error during RSA " "authentication: %d", type); if ((r = sshpkt_get_bignum1(ssh, challenge)) != 0 || (r = sshpkt_get_end(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); debug("Received RSA challenge from server."); /* Ask the agent to decrypt the challenge. */ if ((r = ssh_decrypt_challenge(agent_fd, idlist->keys[i], challenge, session_id, response)) != 0) { /* * The agent failed to authenticate this identifier * although it advertised it supports this. Just * return a wrong value. */ logit("Authentication agent failed to decrypt " "challenge: %s", ssh_err(r)); memset(response, 0, sizeof(response)); } debug("Sending response to RSA challenge."); /* Send the decrypted challenge back to the server. */ if ((r = sshpkt_start(ssh, SSH_CMSG_AUTH_RSA_RESPONSE)) != 0 || (r = sshpkt_put(ssh, &response, sizeof(response))) != 0 || (r = sshpkt_send(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); ssh_packet_write_wait(ssh); /* Wait for response from the server. */ type = ssh_packet_read(ssh); /* * The server returns success if it accepted the * authentication. */ if (type == SSH_SMSG_SUCCESS) { debug("RSA authentication accepted by server."); ret = 1; break; } else if (type != SSH_SMSG_FAILURE) ssh_packet_disconnect(ssh, "Protocol error waiting RSA auth " "response: %d", type); } if (ret != 1) debug("RSA authentication using agent refused."); out: ssh_free_identitylist(idlist); ssh_close_authentication_socket(agent_fd); BN_clear_free(challenge); return ret; }