1 /*
2  * Copyright (C) 2016 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 "socket_spec.h"
18 
19 #include <limits>
20 #include <string>
21 #include <string_view>
22 #include <unordered_map>
23 #include <vector>
24 
25 #include <android-base/parseint.h>
26 #include <android-base/parsenetaddress.h>
27 #include <android-base/stringprintf.h>
28 #include <android-base/strings.h>
29 #include <cutils/sockets.h>
30 
31 #include "adb.h"
32 #include "adb_auth.h"
33 #include "adb_mdns.h"
34 #include "adb_utils.h"
35 #include "sysdeps.h"
36 
37 using namespace std::string_literals;
38 
39 using android::base::ConsumePrefix;
40 using android::base::StringPrintf;
41 
42 #if defined(__linux__)
43 #define ADB_LINUX 1
44 #else
45 #define ADB_LINUX 0
46 #endif
47 
48 #if defined(_WIN32)
49 #define ADB_WINDOWS 1
50 #else
51 #define ADB_WINDOWS 0
52 #endif
53 
54 #if ADB_LINUX
55 #include <sys/socket.h>
56 #include "sysdeps/vm_sockets.h"
57 #endif
58 
59 // Not static because it is used in commandline.c.
60 int gListenAll = 0;
61 
62 struct LocalSocketType {
63     int socket_namespace;
64     bool available;
65 };
66 
67 static auto& kLocalSocketTypes = *new std::unordered_map<std::string, LocalSocketType>({
68 #if ADB_HOST
69     { "local", { ANDROID_SOCKET_NAMESPACE_FILESYSTEM, !ADB_WINDOWS } },
70 #else
71     { "local", { ANDROID_SOCKET_NAMESPACE_RESERVED, !ADB_WINDOWS } },
72 #endif
73 
74     { "localreserved", { ANDROID_SOCKET_NAMESPACE_RESERVED, !ADB_HOST } },
75     { "localabstract", { ANDROID_SOCKET_NAMESPACE_ABSTRACT, ADB_LINUX } },
76     { "localfilesystem", { ANDROID_SOCKET_NAMESPACE_FILESYSTEM, !ADB_WINDOWS } },
77 });
78 
79 bool parse_tcp_socket_spec(std::string_view spec, std::string* hostname, int* port,
80                            std::string* serial, std::string* error) {
81     if (!spec.starts_with("tcp:")) {
82         *error = "specification is not tcp: ";
83         *error += spec;
84         return false;
85     }
86 
87     std::string hostname_value;
88     int port_value;
89 
90     // If the spec is tcp:<port>, parse it ourselves.
91     // Otherwise, delegate to android::base::ParseNetAddress.
92     if (android::base::ParseInt(&spec[4], &port_value)) {
93         // Do the range checking ourselves, because ParseInt rejects 'tcp:65536' and 'tcp:foo:1234'
94         // identically.
95         if (port_value < 0 || port_value > 65535) {
96             *error = StringPrintf("bad port number '%d'", port_value);
97             return false;
98         }
99     } else {
100         std::string addr(spec.substr(4));
101         port_value = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
102 
103         // FIXME: ParseNetAddress rejects port 0. This currently doesn't hurt, because listening
104         //        on an address that isn't 'localhost' is unsupported.
105         if (!android::base::ParseNetAddress(addr, &hostname_value, &port_value, serial, error)) {
106             return false;
107         }
108     }
109 
110     if (hostname) {
111         *hostname = std::move(hostname_value);
112     }
113 
114     if (port) {
115         *port = port_value;
116     }
117 
118     return true;
119 }
120 
121 int get_host_socket_spec_port(std::string_view spec, std::string* error) {
122     int port;
123     if (spec.starts_with("tcp:")) {
124         if (!parse_tcp_socket_spec(spec, nullptr, &port, nullptr, error)) {
125             return -1;
126         }
127     } else if (spec.starts_with("vsock:")) {
128 #if ADB_LINUX
129         std::string spec_str(spec);
130         std::vector<std::string> fragments = android::base::Split(spec_str, ":");
131         if (fragments.size() != 2) {
132             *error = "given vsock server socket string was invalid";
133             return -1;
134         }
135         if (!android::base::ParseInt(fragments[1], &port)) {
136             *error = "could not parse vsock port";
137             errno = EINVAL;
138             return -1;
139         }
140         if (port < 0) {
141             *error = "vsock port was negative.";
142             errno = EINVAL;
143             return -1;
144         }
145 #else   // ADB_LINUX
146         *error = "vsock is only supported on linux";
147         return -1;
148 #endif  // ADB_LINUX
149     } else {
150         *error = "given socket spec string was invalid";
151         return -1;
152     }
153     return port;
154 }
155 
156 static bool tcp_host_is_local(std::string_view hostname) {
157     // FIXME
158     return hostname.empty() || hostname == "localhost";
159 }
160 
161 bool is_socket_spec(std::string_view spec) {
162     for (const auto& it : kLocalSocketTypes) {
163         std::string prefix = it.first + ":";
164         if (spec.starts_with(prefix)) {
165             return true;
166         }
167     }
168     return spec.starts_with("tcp:") || spec.starts_with("acceptfd:") || spec.starts_with("vsock:");
169 }
170 
171 bool is_local_socket_spec(std::string_view spec) {
172     for (const auto& it : kLocalSocketTypes) {
173         std::string prefix = it.first + ":";
174         if (spec.starts_with(prefix)) {
175             return true;
176         }
177     }
178 
179     std::string error;
180     std::string hostname;
181     if (!parse_tcp_socket_spec(spec, &hostname, nullptr, nullptr, &error)) {
182         return false;
183     }
184     return tcp_host_is_local(hostname);
185 }
186 
187 bool socket_spec_connect(unique_fd* fd, std::string_view address, int* port, std::string* serial,
188                          std::string* error) {
189 #if !ADB_HOST
190     if (!socket_access_allowed) {  // Check whether this security suppression is
191         // active (initiated from minadbd), and if so disable socket communications
192         // for the (min)deamon.
193         *error = "Suppressing minadbd socket communications";
194         return false;
195     }
196 #endif
197 
198     if (address.starts_with("tcp:")) {
199         std::string hostname;
200         int port_value = port ? *port : 0;
201         if (!parse_tcp_socket_spec(address, &hostname, &port_value, serial, error)) {
202             return false;
203         }
204 
205         if (tcp_host_is_local(hostname)) {
206             fd->reset(network_loopback_client(port_value, SOCK_STREAM, error));
207         } else {
208 #if ADB_HOST
209             // Check if the address is an mdns service we can connect to.
210             if (auto mdns_info = mdns_get_connect_service_info(std::string(address.substr(4)));
211                 mdns_info != std::nullopt) {
212                 fd->reset(network_connect(mdns_info->addr, mdns_info->port, SOCK_STREAM, 0, error));
213                 if (fd->get() != -1) {
214                     // TODO(joshuaduong): We still show the ip address for the serial. Change it to
215                     // use the mdns instance name, so we can adjust to address changes on
216                     // reconnects.
217                     port_value = mdns_info->port;
218                     if (serial) {
219                         *serial = android::base::StringPrintf("%s.%s",
220                                                               mdns_info->service_name.c_str(),
221                                                               mdns_info->service_type.c_str());
222                     }
223                 }
224             } else {
225                 fd->reset(network_connect(hostname, port_value, SOCK_STREAM, 0, error));
226             }
227 #else
228             // Disallow arbitrary connections in adbd.
229             *error = "adbd does not support arbitrary tcp connections";
230             return false;
231 #endif
232         }
233 
234         if (fd->get() > 0) {
235             int keepalive_interval = 1;
236             if (const char* keepalive_env = getenv("ADB_TCP_KEEPALIVE_INTERVAL")) {
237                 android::base::ParseInt(keepalive_env, &keepalive_interval, 0);
238             }
239 
240             set_tcp_keepalive(fd->get(), keepalive_interval);
241             disable_tcp_nagle(fd->get());
242             if (port) {
243                 *port = port_value;
244             }
245             return true;
246         }
247         return false;
248     } else if (address.starts_with("vsock:")) {
249 #if ADB_LINUX
250         std::string spec_str(address);
251         std::vector<std::string> fragments = android::base::Split(spec_str, ":");
252         unsigned int port_value = port ? *port : 0;
253         if (fragments.size() != 2 && fragments.size() != 3) {
254             *error = android::base::StringPrintf("expected vsock:cid or vsock:cid:port in '%s'",
255                                                  spec_str.c_str());
256             errno = EINVAL;
257             return false;
258         }
259         unsigned int cid = 0;
260         if (!android::base::ParseUint(fragments[1], &cid)) {
261             *error = android::base::StringPrintf("could not parse vsock cid in '%s'",
262                                                  spec_str.c_str());
263             errno = EINVAL;
264             return false;
265         }
266         if (fragments.size() == 3 && !android::base::ParseUint(fragments[2], &port_value)) {
267             *error = android::base::StringPrintf("could not parse vsock port in '%s'",
268                                                  spec_str.c_str());
269             errno = EINVAL;
270             return false;
271         }
272         if (port_value == 0) {
273             *error = android::base::StringPrintf("vsock port was not provided.");
274             errno = EINVAL;
275             return false;
276         }
277         fd->reset(socket(AF_VSOCK, SOCK_STREAM, 0));
278         if (fd->get() == -1) {
279             *error = "could not open vsock socket";
280             return false;
281         }
282         sockaddr_vm addr{};
283         addr.svm_family = AF_VSOCK;
284         addr.svm_port = port_value;
285         addr.svm_cid = cid;
286         if (serial) {
287             *serial = android::base::StringPrintf("vsock:%u:%d", cid, port_value);
288         }
289         if (connect(fd->get(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr))) {
290             int error_num = errno;
291             *error = android::base::StringPrintf("could not connect to vsock address '%s'",
292                                                  spec_str.c_str());
293             errno = error_num;
294             return false;
295         }
296         if (port) {
297             *port = port_value;
298         }
299         return true;
300 #else   // ADB_LINUX
301         *error = "vsock is only supported on Linux";
302         return false;
303 #endif  // ADB_LINUX
304     } else if (address.starts_with("acceptfd:")) {
305         *error = "cannot connect to acceptfd";
306         return false;
307     }
308 
309     for (const auto& it : kLocalSocketTypes) {
310         std::string prefix = it.first + ":";
311         if (address.starts_with(prefix)) {
312             if (!it.second.available) {
313                 *error = StringPrintf("socket type %s is unavailable on this platform",
314                                       it.first.c_str());
315                 return false;
316             }
317 
318             fd->reset(network_local_client(&address[prefix.length()], it.second.socket_namespace,
319                                            SOCK_STREAM, error));
320 
321             if (fd->get() < 0) {
322                 *error =
323                         android::base::StringPrintf("could not connect to %s address '%s'",
324                                                     it.first.c_str(), std::string(address).c_str());
325                 return false;
326             }
327 
328             if (serial) {
329                 *serial = address;
330             }
331             return true;
332         }
333     }
334 
335     *error = "unknown socket specification: ";
336     *error += address;
337     return false;
338 }
339 
340 int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_port) {
341     if (spec.starts_with("tcp:")) {
342         std::string hostname;
343         int port;
344         if (!parse_tcp_socket_spec(spec, &hostname, &port, nullptr, error)) {
345             return -1;
346         }
347 
348         int result;
349 #if ADB_HOST
350         if (hostname.empty() && gListenAll) {
351 #else
352         if (hostname.empty()) {
353 #endif
354             result = network_inaddr_any_server(port, SOCK_STREAM, error);
355         } else if (tcp_host_is_local(hostname)) {
356             result = network_loopback_server(port, SOCK_STREAM, error, true);
357         } else if (hostname == "::1") {
358             result = network_loopback_server(port, SOCK_STREAM, error, false);
359         } else {
360             // TODO: Implement me.
361             *error = "listening on specified hostname currently unsupported";
362             return -1;
363         }
364 
365         if (result >= 0 && resolved_port) {
366             *resolved_port = adb_socket_get_local_port(result);
367         }
368         return result;
369     } else if (spec.starts_with("vsock:")) {
370 #if ADB_LINUX
371         std::string spec_str(spec);
372         std::vector<std::string> fragments = android::base::Split(spec_str, ":");
373         if (fragments.size() != 2) {
374             *error = "given vsock server socket string was invalid";
375             return -1;
376         }
377         int port;
378         if (!android::base::ParseInt(fragments[1], &port)) {
379             *error = "could not parse vsock port";
380             errno = EINVAL;
381             return -1;
382         } else if (port < 0) {
383             *error = "vsock port was negative.";
384             errno = EINVAL;
385             return -1;
386         }
387         unique_fd serverfd(socket(AF_VSOCK, SOCK_STREAM, 0));
388         if (serverfd == -1) {
389             int error_num = errno;
390             *error = android::base::StringPrintf("could not create vsock server: '%s'",
391                                                  strerror(error_num));
392             errno = error_num;
393             return -1;
394         }
395         sockaddr_vm addr{};
396         addr.svm_family = AF_VSOCK;
397         addr.svm_port = port == 0 ? VMADDR_PORT_ANY : port;
398         addr.svm_cid = VMADDR_CID_ANY;
399         socklen_t addr_len = sizeof(addr);
400         if (bind(serverfd.get(), reinterpret_cast<struct sockaddr*>(&addr), addr_len)) {
401             return -1;
402         }
403         if (listen(serverfd.get(), 4)) {
404             return -1;
405         }
406         if (serverfd >= 0 && resolved_port) {
407             if (getsockname(serverfd.get(), reinterpret_cast<sockaddr*>(&addr), &addr_len) == 0) {
408                 *resolved_port = addr.svm_port;
409             } else {
410                 return -1;
411             }
412         }
413         return serverfd.release();
414 #else   // ADB_LINUX
415         *error = "vsock is only supported on linux";
416         return -1;
417 #endif  // ADB_LINUX
418     } else if (ConsumePrefix(&spec, "acceptfd:")) {
419 #if ADB_WINDOWS
420         *error = "socket activation not supported under Windows";
421         return -1;
422 #else
423         // We inherited the socket from some kind of launcher. It's already bound and
424         // listening. Return a copy of the FD instead of the FD itself so we implement the
425         // normal "listen" contract and can succeed more than once.
426         unsigned int fd_u;
427         if (!ParseUint(&fd_u, spec) || fd_u > std::numeric_limits<int>::max()) {
428             *error = "invalid fd";
429             return -1;
430         }
431         int fd = static_cast<int>(fd_u);
432         int flags = get_fd_flags(fd);
433         if (flags < 0) {
434             *error = android::base::StringPrintf("could not get flags of inherited fd %d: '%s'", fd,
435                                                  strerror(errno));
436             return -1;
437         }
438         if (flags & FD_CLOEXEC) {
439             *error = android::base::StringPrintf("fd %d was not inherited from parent", fd);
440             return -1;
441         }
442 
443         int dummy_sock_type;
444         socklen_t dummy_sock_type_size = sizeof(dummy_sock_type);
445         if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &dummy_sock_type, &dummy_sock_type_size)) {
446             *error = android::base::StringPrintf("fd %d does not refer to a socket", fd);
447             return -1;
448         }
449 
450         int new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
451         if (new_fd < 0) {
452             *error = android::base::StringPrintf("could not dup inherited fd %d: '%s'", fd,
453                                                  strerror(errno));
454             return -1;
455         }
456         return new_fd;
457 #endif
458     }
459 
460     for (const auto& it : kLocalSocketTypes) {
461         std::string prefix = it.first + ":";
462         if (spec.starts_with(prefix)) {
463             if (!it.second.available) {
464                 *error = "attempted to listen on unavailable socket type: ";
465                 *error += spec;
466                 return -1;
467             }
468 
469             return network_local_server(&spec[prefix.length()], it.second.socket_namespace,
470                                         SOCK_STREAM, error);
471         }
472     }
473 
474     *error = "unknown socket specification:";
475     *error += spec;
476     return -1;
477 }
478