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