1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdio.h> 18 #include <string.h> 19 #include <resolv.h> 20 #include <cutils/list.h> 21 #include <cutils/sockets.h> 22 23 #include "sysdeps.h" 24 #include "adb.h" 25 #include "adb_auth.h" 26 #include "fdevent.h" 27 #include "mincrypt/rsa.h" 28 29 #define TRACE_TAG TRACE_AUTH 30 31 32 struct adb_public_key { 33 struct listnode node; 34 RSAPublicKey key; 35 }; 36 37 static char *key_paths[] = { 38 "/adb_keys", 39 "/data/misc/adb/adb_keys", 40 NULL 41 }; 42 43 static fdevent listener_fde; 44 static int framework_fd = -1; 45 46 static void usb_disconnected(void* unused, atransport* t); 47 static struct adisconnect usb_disconnect = { usb_disconnected, 0, 0, 0 }; 48 static atransport* usb_transport; 49 static bool needs_retry = false; 50 51 static void read_keys(const char *file, struct listnode *list) 52 { 53 struct adb_public_key *key; 54 FILE *f; 55 char buf[MAX_PAYLOAD]; 56 char *sep; 57 int ret; 58 59 f = fopen(file, "r"); 60 if (!f) { 61 D("Can't open '%s'\n", file); 62 return; 63 } 64 65 while (fgets(buf, sizeof(buf), f)) { 66 /* Allocate 4 extra bytes to decode the base64 data in-place */ 67 key = calloc(1, sizeof(*key) + 4); 68 if (!key) { 69 D("Can't malloc key\n"); 70 break; 71 } 72 73 sep = strpbrk(buf, " \t"); 74 if (sep) 75 *sep = '\0'; 76 77 ret = __b64_pton(buf, (u_char *)&key->key, sizeof(key->key) + 4); 78 if (ret != sizeof(key->key)) { 79 D("%s: Invalid base64 data ret=%d\n", file, ret); 80 free(key); 81 continue; 82 } 83 84 if (key->key.len != RSANUMWORDS) { 85 D("%s: Invalid key len %d\n", file, key->key.len); 86 free(key); 87 continue; 88 } 89 90 list_add_tail(list, &key->node); 91 } 92 93 fclose(f); 94 } 95 96 static void free_keys(struct listnode *list) 97 { 98 struct listnode *item; 99 100 while (!list_empty(list)) { 101 item = list_head(list); 102 list_remove(item); 103 free(node_to_item(item, struct adb_public_key, node)); 104 } 105 } 106 107 static void load_keys(struct listnode *list) 108 { 109 char *path; 110 char **paths = key_paths; 111 struct stat buf; 112 113 list_init(list); 114 115 while ((path = *paths++)) { 116 if (!stat(path, &buf)) { 117 D("Loading keys from '%s'\n", path); 118 read_keys(path, list); 119 } 120 } 121 } 122 123 int adb_auth_generate_token(void *token, size_t token_size) 124 { 125 FILE *f; 126 int ret; 127 128 f = fopen("/dev/urandom", "r"); 129 if (!f) 130 return 0; 131 132 ret = fread(token, token_size, 1, f); 133 134 fclose(f); 135 return ret * token_size; 136 } 137 138 int adb_auth_verify(void *token, void *sig, int siglen) 139 { 140 struct listnode *item; 141 struct adb_public_key *key; 142 struct listnode key_list; 143 int ret = 0; 144 145 if (siglen != RSANUMBYTES) 146 return 0; 147 148 load_keys(&key_list); 149 150 list_for_each(item, &key_list) { 151 key = node_to_item(item, struct adb_public_key, node); 152 ret = RSA_verify(&key->key, sig, siglen, token); 153 if (ret) 154 break; 155 } 156 157 free_keys(&key_list); 158 159 return ret; 160 } 161 162 static void usb_disconnected(void* unused, atransport* t) 163 { 164 D("USB disconnect\n"); 165 remove_transport_disconnect(usb_transport, &usb_disconnect); 166 usb_transport = NULL; 167 needs_retry = false; 168 } 169 170 static void adb_auth_event(int fd, unsigned events, void *data) 171 { 172 char response[2]; 173 int ret; 174 175 if (events & FDE_READ) { 176 ret = unix_read(fd, response, sizeof(response)); 177 if (ret < 0) { 178 D("Framework disconnect\n"); 179 if (usb_transport) 180 fdevent_remove(&usb_transport->auth_fde); 181 framework_fd = -1; 182 } 183 else if (ret == 2 && response[0] == 'O' && response[1] == 'K') { 184 if (usb_transport) 185 adb_auth_verified(usb_transport); 186 } 187 } 188 } 189 190 void adb_auth_confirm_key(unsigned char *key, size_t len, atransport *t) 191 { 192 char msg[MAX_PAYLOAD]; 193 int ret; 194 195 if (!usb_transport) { 196 usb_transport = t; 197 add_transport_disconnect(t, &usb_disconnect); 198 } 199 200 if (framework_fd < 0) { 201 D("Client not connected\n"); 202 needs_retry = true; 203 return; 204 } 205 206 if (key[len - 1] != '\0') { 207 D("Key must be a null-terminated string\n"); 208 return; 209 } 210 211 ret = snprintf(msg, sizeof(msg), "PK%s", key); 212 if (ret >= (signed)sizeof(msg)) { 213 D("Key too long. ret=%d", ret); 214 return; 215 } 216 D("Sending '%s'\n", msg); 217 218 ret = unix_write(framework_fd, msg, ret); 219 if (ret < 0) { 220 D("Failed to write PK, errno=%d\n", errno); 221 return; 222 } 223 224 fdevent_install(&t->auth_fde, framework_fd, adb_auth_event, t); 225 fdevent_add(&t->auth_fde, FDE_READ); 226 } 227 228 static void adb_auth_listener(int fd, unsigned events, void *data) 229 { 230 struct sockaddr addr; 231 socklen_t alen; 232 int s; 233 234 alen = sizeof(addr); 235 236 s = adb_socket_accept(fd, &addr, &alen); 237 if (s < 0) { 238 D("Failed to accept: errno=%d\n", errno); 239 return; 240 } 241 242 framework_fd = s; 243 244 if (needs_retry) { 245 needs_retry = false; 246 send_auth_request(usb_transport); 247 } 248 } 249 250 void adb_auth_init(void) 251 { 252 int fd, ret; 253 254 fd = android_get_control_socket("adbd"); 255 if (fd < 0) { 256 D("Failed to get adbd socket\n"); 257 return; 258 } 259 260 ret = listen(fd, 4); 261 if (ret < 0) { 262 D("Failed to listen on '%d'\n", fd); 263 return; 264 } 265 266 fdevent_install(&listener_fde, fd, adb_auth_listener, NULL); 267 fdevent_add(&listener_fde, FDE_READ); 268 } 269