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