Home | History | Annotate | Download | only in adb
      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, "re");
     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", "re");
    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     fcntl(fd, F_SETFD, FD_CLOEXEC);
    261 
    262     ret = listen(fd, 4);
    263     if (ret < 0) {
    264         D("Failed to listen on '%d'\n", fd);
    265         return;
    266     }
    267 
    268     fdevent_install(&listener_fde, fd, adb_auth_listener, NULL);
    269     fdevent_add(&listener_fde, FDE_READ);
    270 }
    271