- Client auth using an agent's key works. Still need to implement client

agent forwarding.

--HG--
branch : agent-client
extra : convert_revision : 276cf5e82276b6c879d246ba64739ec6868f5150
This commit is contained in:
Matt Johnston 2009-07-06 14:02:45 +00:00
parent c742137dc8
commit 8a19a049b2
5 changed files with 89 additions and 13 deletions

1
auth.h
View File

@ -74,6 +74,7 @@ void cli_auth_password();
int cli_auth_pubkey();
void cli_auth_interactive();
char* getpass_or_cancel(char* prompt);
void cli_auth_pubkey_cleanup();
#define MAX_USERNAME_LEN 25 /* arbitrary for the moment */

View File

@ -102,17 +102,26 @@ static int new_agent_chan(struct Channel * channel) {
data Any data, depending on packet type. Encoding as in the ssh packet
protocol.
*/
static buffer * agent_request(int fd, unsigned char type) {
static buffer * agent_request(unsigned char type, buffer *data) {
buffer * payload = NULL;
buffer * inbuf = NULL;
size_t readlen = 0;
ssize_t ret;
const int fd = cli_opts.agent_fd;
unsigned int data_len = 0;
if (data)
{
data_len = data->len;
}
payload = buf_new(4 + 1);
payload = buf_new(4 + 1 + data_len);
buf_putint(payload, 1);
buf_putint(payload, 1 + data_len);
buf_putbyte(payload, type);
if (data) {
buf_putbytes(payload, data->data, data->len);
}
buf_setpos(payload, 0);
ret = atomicio(write, fd, buf_getptr(payload, payload->len), payload->len);
@ -160,7 +169,7 @@ out:
return inbuf;
}
static void agent_get_key_list(int fd, m_list * ret_list)
static void agent_get_key_list(m_list * ret_list)
{
buffer * inbuf = NULL;
unsigned int num = 0;
@ -168,9 +177,9 @@ static void agent_get_key_list(int fd, m_list * ret_list)
unsigned int i;
int ret;
inbuf = agent_request(fd, SSH2_AGENTC_REQUEST_IDENTITIES);
inbuf = agent_request(SSH2_AGENTC_REQUEST_IDENTITIES, NULL);
if (!inbuf) {
TRACE(("agent_request returned no identities"))
TRACE(("agent_request failed returning identities"))
goto out;
}
@ -191,7 +200,6 @@ static void agent_get_key_list(int fd, m_list * ret_list)
sign_key * pubkey = NULL;
int key_type = DROPBEAR_SIGNKEY_ANY;
buffer * key_buf;
struct SignKeyList *nextkey = NULL;
/* each public key is encoded as a string */
key_buf = buf_getstringbuf(inbuf);
@ -222,19 +230,66 @@ out:
be updated. */
void load_agent_keys(m_list *ret_list)
{
int fd;
fd = connect_agent();
if (fd < 0) {
/* agent_fd will be closed after successful auth */
cli_opts.agent_fd = connect_agent();
if (cli_opts.agent_fd < 0) {
dropbear_log(LOG_INFO, "Failed to connect to agent");
return;
}
agent_get_key_list(fd, ret_list);
close(fd);
agent_get_key_list(ret_list);
}
void agent_buf_sign(buffer *sigblob, sign_key *key,
const unsigned char *data, unsigned int len) {
buffer *request_data = buf_new(MAX_PUBKEY_SIZE + len + 12);
buffer *response;
unsigned int keylen, siglen;
int packet_type;
/* Request format
byte SSH2_AGENTC_SIGN_REQUEST
string key_blob
string data
uint32 flags
*/
/* We write the key, then figure how long it was and write that */
//buf_putint(request_data, 0);
buf_put_pub_key(request_data, key, key->type);
keylen = request_data->len - 4;
//buf_setpos(request_data, 0);
//buf_putint(request_data, keylen);
//buf_setpos(request_data, request_data->len);
buf_putstring(request_data, data, len);
buf_putint(request_data, 0);
response = agent_request(SSH2_AGENTC_SIGN_REQUEST, request_data);
buf_free(request_data);
if (!response) {
goto fail;
}
packet_type = buf_getbyte(response);
if (packet_type != SSH2_AGENT_SIGN_RESPONSE) {
goto fail;
}
/* Response format
byte SSH2_AGENT_SIGN_RESPONSE
string signature_blob
*/
siglen = buf_getint(response);
buf_putbytes(sigblob, buf_getptr(response, siglen), siglen);
buf_free(response);
return;
fail:
/* XXX don't fail badly here. instead propagate a failure code back up to
the cli auth pubkey code, and just remove this key from the list of
ones to try. */
dropbear_exit("Agent failed signing key");
}
#endif

View File

@ -234,6 +234,10 @@ void recv_msg_userauth_success() {
ses.authstate.authdone = 1;
cli_ses.state = USERAUTH_SUCCESS_RCVD;
cli_ses.lastauthtype = AUTH_TYPE_NONE;
#ifdef ENABLE_CLI_PUBKEY_AUTH
cli_auth_pubkey_cleanup();
#endif
}
void cli_auth_try() {

View File

@ -174,7 +174,7 @@ static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) {
sigbuf = buf_new(4 + SHA1_HASH_SIZE + ses.writepayload->len);
buf_putstring(sigbuf, ses.session_id, SHA1_HASH_SIZE);
buf_putbytes(sigbuf, ses.writepayload->data, ses.writepayload->len);
buf_put_sign(ses.writepayload, key, type, sigbuf->data, sigbuf->len);
cli_buf_put_sign(ses.writepayload, key, type, sigbuf->data, sigbuf->len);
buf_free(sigbuf); /* Nothing confidential in the buffer */
}
@ -202,8 +202,22 @@ int cli_auth_pubkey() {
TRACE(("leave cli_auth_pubkey-success"))
return 1;
} else {
/* no more keys left */
TRACE(("leave cli_auth_pubkey-failure"))
return 0;
}
}
void cli_auth_pubkey_cleanup() {
#ifdef ENABLE_CLI_AGENTFWD
m_close(cli_opts.agent_fd);
cli_opts.agent_fd = -1;
#endif
while (cli_opts.privkeys->first) {
sign_key * key = list_remove(cli_opts.privkeys->first);
sign_key_free(key);
}
}
#endif /* Pubkey auth */

View File

@ -124,6 +124,8 @@ typedef struct cli_runopts {
int agent_fwd;
int agent_keys_loaded; /* whether pubkeys has been populated with a
list of keys held by the agent */
int agent_fd; /* The agent fd is only set during authentication. Forwarded
agent sessions have their own file descriptors */
#endif
#ifdef ENABLE_CLI_NETCAT