int agent_is_running(ssh_session session) { if (session == NULL || session->agent == NULL) { return 0; } if (ssh_socket_is_open(session->agent->sock)) { return 1; } else { if (agent_connect(session) < 0) { return 0; } else { return 1; } } return 0; }
const unsigned char *sftp_agent_sign_data(pool *p, const char *agent_path, const unsigned char *key_data, uint32_t key_datalen, const unsigned char *data, uint32_t datalen, uint32_t *sig_datalen) { int fd; unsigned char *buf, *req, *resp, *sig_data; uint32_t buflen, flags, reqlen, reqsz, resplen; char resp_status; fd = agent_connect(agent_path); if (fd < 0) { return NULL; } /* XXX When to set flags to OLD_SIGNATURE? */ flags = 0; /* Write out the request for signing the given data. */ reqsz = buflen = 1 + key_datalen + 4 + datalen + 4 + 4; req = buf = palloc(p, reqsz); sftp_msg_write_byte(&buf, &buflen, SFTP_SSH_AGENT_REQ_SIGN_DATA); sftp_msg_write_data(&buf, &buflen, key_data, key_datalen, TRUE); sftp_msg_write_data(&buf, &buflen, data, datalen, TRUE); sftp_msg_write_int(&buf, &buflen, flags); reqlen = reqsz - buflen; resp = agent_request(p, fd, agent_path, req, reqlen, &resplen); if (resp == NULL) { int xerrno = errno; (void) close(fd); errno = xerrno; return NULL; } (void) close(fd); /* Read the response from the agent. */ resp_status = sftp_msg_read_byte(p, &resp, &resplen); if (agent_failure(resp_status) == TRUE) { pr_trace_msg(trace_channel, 5, "SSH agent at '%s' indicated failure (%d) for data signing request", agent_path, resp_status); errno = EPERM; return NULL; } if (resp_status != SFTP_SSH_AGENT_RESP_SIGN_DATA) { pr_trace_msg(trace_channel, 5, "unknown response type %d from SSH agent at '%s'", resp_status, agent_path); errno = EACCES; return NULL; } *sig_datalen = sftp_msg_read_int(p, &resp, &resplen); sig_data = sftp_msg_read_data(p, &resp, &resplen, *sig_datalen); return sig_data; }
int sftp_agent_get_keys(pool *p, const char *agent_path, array_header *key_list) { register unsigned int i; int fd; unsigned char *buf, *req, *resp; uint32_t buflen, key_count, reqlen, reqsz, resplen; char resp_status; fd = agent_connect(agent_path); if (fd < 0) { return -1; } /* Write out the request for the identities (i.e. the public keys). */ reqsz = buflen = 64; req = buf = palloc(p, reqsz); sftp_msg_write_byte(&buf, &buflen, SFTP_SSH_AGENT_REQ_IDS); reqlen = reqsz - buflen; resp = agent_request(p, fd, agent_path, req, reqlen, &resplen); if (resp == NULL) { int xerrno = errno; (void) close(fd); errno = xerrno; return -1; } (void) close(fd); /* Read the response from the agent. */ resp_status = sftp_msg_read_byte(p, &resp, &resplen); if (agent_failure(resp_status) == TRUE) { pr_trace_msg(trace_channel, 5, "SSH agent at '%s' indicated failure (%d) for identities request", agent_path, resp_status); errno = EPERM; return -1; } if (resp_status != SFTP_SSH_AGENT_RESP_IDS) { pr_trace_msg(trace_channel, 5, "unknown response type %d from SSH agent at '%s'", resp_status, agent_path); errno = EACCES; return -1; } key_count = sftp_msg_read_int(p, &resp, &resplen); if (key_count > AGENT_MAX_KEYS) { (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "SSH agent at '%s' returned too many keys (%lu, max %lu)", agent_path, (unsigned long) key_count, (unsigned long) AGENT_MAX_KEYS); errno = EPERM; return -1; } for (i = 0; i < key_count; i++) { unsigned char *key_data; uint32_t key_datalen; char *key_comment; struct agent_key *key; key_datalen = sftp_msg_read_int(p, &resp, &resplen); key_data = sftp_msg_read_data(p, &resp, &resplen, key_datalen); key_comment = sftp_msg_read_string(p, &resp, &resplen); if (key_comment != NULL) { pr_trace_msg(trace_channel, 9, "SSH agent at '%s' provided comment '%s' for key #%u", agent_path, key_comment, (i + 1)); } key = pcalloc(p, sizeof(struct agent_key)); key->key_data = key_data; key->key_datalen = key_datalen; key->agent_path = pstrdup(p, agent_path); *((struct agent_key **) push_array(key_list)) = key; } pr_trace_msg(trace_channel, 9, "SSH agent at '%s' provided %lu %s", agent_path, (unsigned long) key_count, key_count != 1 ? "keys" : "key"); return 0; }