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