summaryrefslogtreecommitdiffstats
path: root/adb/adb_auth_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'adb/adb_auth_client.c')
-rw-r--r--adb/adb_auth_client.c53
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");