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