Mercurial > dropbear
diff cli-authpubkey.c @ 551:c3f2ec71e3d4 agent-client
New standard linked list to use, rather than adhoc SignKeyList or TCPFwdList
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 06 Jul 2009 12:59:13 +0000 |
parents | 61c3513825b0 |
children | de3653483ac0 |
line wrap: on
line diff
--- a/cli-authpubkey.c Wed Jul 01 06:27:27 2009 +0000 +++ b/cli-authpubkey.c Mon Jul 06 12:59:13 2009 +0000 @@ -30,6 +30,7 @@ #include "ssh.h" #include "runopts.h" #include "auth.h" +#include "agentfwd.h" #ifdef ENABLE_CLI_PUBKEY_AUTH static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign); @@ -37,31 +38,23 @@ /* Called when we receive a SSH_MSG_USERAUTH_FAILURE for a pubkey request. * We use it to remove the key we tried from the list */ void cli_pubkeyfail() { - - struct SignKeyList *keyitem; - struct SignKeyList **previtem; - - TRACE(("enter cli_pubkeyfail")) - previtem = &cli_opts.privkeys; - - /* Find the key we failed with, and remove it */ - for (keyitem = cli_opts.privkeys; keyitem != NULL; keyitem = keyitem->next) { - if (keyitem == cli_ses.lastprivkey) { - *previtem = keyitem->next; + m_list_elem *iter; + for (iter = cli_opts.privkeys->first; iter; iter = iter->next) { + sign_key *iter_key = (sign_key*)iter->item; + + if (iter_key == cli_ses.lastprivkey) + { + /* found the failing key */ + list_remove(iter); + sign_key_free(iter_key); + cli_ses.lastprivkey = NULL; + return; } - previtem = &keyitem; } - - sign_key_free(cli_ses.lastprivkey->key); /* It won't be used again */ - m_free(cli_ses.lastprivkey->filename); - m_free(cli_ses.lastprivkey); - - TRACE(("leave cli_pubkeyfail")) } void recv_msg_userauth_pk_ok() { - - struct SignKeyList *keyitem = NULL; + m_list_elem *iter; buffer* keybuf = NULL; char* algotype = NULL; unsigned int algolen; @@ -81,9 +74,9 @@ /* Iterate through our keys, find which one it was that matched, and * send a real request with that key */ - for (keyitem = cli_opts.privkeys; keyitem != NULL; keyitem = keyitem->next) { - - if (keyitem->type != keytype) { + for (iter = cli_opts.privkeys->first; iter; iter = iter->next) { + sign_key *key = (sign_key*)iter->item; + if (key->type != keytype) { /* Types differed */ TRACE(("types differed")) continue; @@ -91,7 +84,7 @@ /* Now we compare the contents of the key */ keybuf->pos = keybuf->len = 0; - buf_put_pub_key(keybuf, keyitem->key, keytype); + buf_put_pub_key(keybuf, key, keytype); buf_setpos(keybuf, 0); buf_incrpos(keybuf, 4); /* first int is the length of the remainder (ie remotelen) which has already been taken from @@ -115,11 +108,11 @@ } buf_free(keybuf); - if (keyitem != NULL) { + if (iter != NULL) { TRACE(("matching key")) /* XXX TODO: if it's an encrypted key, here we ask for their * password */ - send_msg_userauth_pubkey(keyitem->key, keytype, 1); + send_msg_userauth_pubkey((sign_key*)iter->item, keytype, 1); } else { TRACE(("That was whacky. We got told that a key was valid, but it didn't match our list. Sounds like dodgy code on Dropbear's part")) } @@ -127,6 +120,25 @@ TRACE(("leave recv_msg_userauth_pk_ok")) } +void cli_buf_put_sign(buffer* buf, sign_key *key, int type, + const unsigned char *data, unsigned int len) +{ + if (key->source == SIGNKEY_SOURCE_AGENT) { + /* Format the agent signature ourselves, as buf_put_sign would. */ + buffer *sigblob; + sigblob = buf_new(MAX_PUBKEY_SIZE); + agent_buf_sign(sigblob, key, data, len); + buf_setpos(sigblob, 0); + buf_putstring(buf, buf_getptr(sigblob, sigblob->len), + sigblob->len); + + buf_free(sigblob); + } else { + buf_put_sign(buf, key, type, data, len); + } + +} + /* TODO: make it take an agent reference to use as well */ static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) { @@ -170,6 +182,7 @@ TRACE(("leave send_msg_userauth_pubkey")) } +/* Returns 1 if a key was tried */ int cli_auth_pubkey() { TRACE(("enter cli_auth_pubkey")) @@ -177,15 +190,15 @@ if (cli_opts.agent_fwd && !cli_opts.agent_keys_loaded) { /* get the list of available keys from the agent */ - load_agent_keys(&cli_opts.privkeys); + load_agent_keys(cli_opts.privkeys); cli_opts.agent_keys_loaded = 1; } - if (cli_opts.privkeys != NULL) { + if (cli_opts.privkeys->first) { + sign_key * key = (sign_key*)cli_opts.privkeys->first->item; /* Send a trial request */ - send_msg_userauth_pubkey(cli_opts.privkeys->key, - cli_opts.privkeys->type, 0); - cli_ses.lastprivkey = cli_opts.privkeys; + send_msg_userauth_pubkey(key, key->type, 0); + cli_ses.lastprivkey = key; TRACE(("leave cli_auth_pubkey-success")) return 1; } else {