diff options
Diffstat (limited to 'adb/adb_auth_client.c')
-rw-r--r-- | adb/adb_auth_client.c | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/adb/adb_auth_client.c b/adb/adb_auth_client.c index 0b4913e..efc49eb 100644 --- a/adb/adb_auth_client.c +++ b/adb/adb_auth_client.c @@ -34,8 +34,6 @@ struct adb_public_key { RSAPublicKey key; }; -static struct listnode key_list; - static char *key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", @@ -45,6 +43,10 @@ static char *key_paths[] = { static fdevent listener_fde; static int framework_fd = -1; +static void usb_disconnected(void* unused, atransport* t); +static struct adisconnect usb_disconnect = { usb_disconnected, 0, 0, 0 }; +static atransport* usb_transport; +static bool needs_retry = false; static void read_keys(const char *file, struct listnode *list) { @@ -102,18 +104,18 @@ static void free_keys(struct listnode *list) } } -void adb_auth_reload_keys(void) +static void load_keys(struct listnode *list) { char *path; char **paths = key_paths; struct stat buf; - free_keys(&key_list); + list_init(list); while ((path = *paths++)) { if (!stat(path, &buf)) { D("Loading keys from '%s'\n", path); - read_keys(path, &key_list); + read_keys(path, list); } } } @@ -137,37 +139,50 @@ int adb_auth_verify(void *token, void *sig, int siglen) { struct listnode *item; struct adb_public_key *key; - int ret; + struct listnode key_list; + int ret = 0; if (siglen != RSANUMBYTES) return 0; + load_keys(&key_list); + list_for_each(item, &key_list) { key = node_to_item(item, struct adb_public_key, node); ret = RSA_verify(&key->key, sig, siglen, token); if (ret) - return 1; + break; } - return 0; + free_keys(&key_list); + + return ret; +} + +static void usb_disconnected(void* unused, atransport* t) +{ + D("USB disconnect"); + remove_transport_disconnect(usb_transport, &usb_disconnect); + usb_transport = NULL; + needs_retry = false; } static void adb_auth_event(int fd, unsigned events, void *data) { - atransport *t = data; char response[2]; int ret; if (events & FDE_READ) { ret = unix_read(fd, response, sizeof(response)); if (ret < 0) { - D("Disconnect"); - fdevent_remove(&t->auth_fde); + D("Framework disconnect"); + if (usb_transport) + fdevent_remove(&usb_transport->auth_fde); framework_fd = -1; } else if (ret == 2 && response[0] == 'O' && response[1] == 'K') { - adb_auth_reload_keys(); - adb_auth_verified(t); + if (usb_transport) + adb_auth_verified(usb_transport); } } } @@ -177,8 +192,12 @@ void adb_auth_confirm_key(unsigned char *key, size_t len, atransport *t) char msg[MAX_PAYLOAD]; int ret; + usb_transport = t; + add_transport_disconnect(t, &usb_disconnect); + if (framework_fd < 0) { D("Client not connected\n"); + needs_retry = true; return; } @@ -219,15 +238,17 @@ static void adb_auth_listener(int fd, unsigned events, void *data) } framework_fd = s; + + if (needs_retry) { + needs_retry = false; + send_auth_request(usb_transport); + } } void adb_auth_init(void) { int fd, ret; - list_init(&key_list); - adb_auth_reload_keys(); - fd = android_get_control_socket("adbd"); if (fd < 0) { D("Failed to get adbd socket\n"); |