1 /*
2  * Copyright (C) 2015 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 "adb_listeners.h"
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 
22 #include <android-base/stringprintf.h>
23 #include <cutils/sockets.h>
24 
25 #include "sysdeps.h"
26 #include "transport.h"
27 
28 int gListenAll = 0; /* Not static because it is used in commandline.c. */
29 
30 static alistener listener_list = {
31     .next = &listener_list,
32     .prev = &listener_list,
33 };
34 
ss_listener_event_func(int _fd,unsigned ev,void * _l)35 static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
36     if (ev & FDE_READ) {
37         sockaddr_storage ss;
38         sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss);
39         socklen_t alen = sizeof(ss);
40         int fd = adb_socket_accept(_fd, addrp, &alen);
41         if (fd < 0) return;
42 
43         int rcv_buf_size = CHUNK_SIZE;
44         adb_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size));
45 
46         asocket* s = create_local_socket(fd);
47         if (s) {
48             connect_to_smartsocket(s);
49             return;
50         }
51 
52         adb_close(fd);
53     }
54 }
55 
listener_event_func(int _fd,unsigned ev,void * _l)56 static void listener_event_func(int _fd, unsigned ev, void* _l)
57 {
58     alistener* listener = reinterpret_cast<alistener*>(_l);
59     asocket *s;
60 
61     if (ev & FDE_READ) {
62         sockaddr_storage ss;
63         sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss);
64         socklen_t alen;
65         int fd;
66 
67         alen = sizeof(ss);
68         fd = adb_socket_accept(_fd, addrp, &alen);
69         if (fd < 0) {
70             return;
71         }
72 
73         s = create_local_socket(fd);
74         if (s) {
75             s->transport = listener->transport;
76             connect_to_remote(s, listener->connect_to);
77             return;
78         }
79 
80         adb_close(fd);
81     }
82 }
83 
free_listener(alistener * l)84 static void free_listener(alistener*  l)
85 {
86     if (l->next) {
87         l->next->prev = l->prev;
88         l->prev->next = l->next;
89         l->next = l->prev = l;
90     }
91 
92     // closes the corresponding fd
93     fdevent_remove(&l->fde);
94 
95     if (l->local_name)
96         free((char*)l->local_name);
97 
98     if (l->connect_to)
99         free((char*)l->connect_to);
100 
101     if (l->transport) {
102         l->transport->RemoveDisconnect(&l->disconnect);
103     }
104     free(l);
105 }
106 
listener_disconnect(void * arg,atransport *)107 static void listener_disconnect(void* arg, atransport*) {
108     alistener* listener = reinterpret_cast<alistener*>(arg);
109     listener->transport = nullptr;
110     free_listener(listener);
111 }
112 
local_name_to_fd(const char * name,std::string * error)113 static int local_name_to_fd(const char* name, std::string* error) {
114     if (!strncmp("tcp:", name, 4)) {
115         int port = atoi(name + 4);
116         if (gListenAll > 0) {
117             return network_inaddr_any_server(port, SOCK_STREAM, error);
118         } else {
119             return network_loopback_server(port, SOCK_STREAM, error);
120         }
121     }
122 #if !defined(_WIN32)  // No Unix-domain sockets on Windows.
123     // It's nonsensical to support the "reserved" space on the adb host side
124     if (!strncmp(name, "local:", 6)) {
125         return network_local_server(name + 6,
126                 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM, error);
127     } else if (!strncmp(name, "localabstract:", 14)) {
128         return network_local_server(name + 14,
129                 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM, error);
130     } else if (!strncmp(name, "localfilesystem:", 16)) {
131         return network_local_server(name + 16,
132                 ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM, error);
133     }
134 
135 #endif
136     *error = android::base::StringPrintf("unknown local portname '%s'", name);
137     return -1;
138 }
139 
140 // Write the list of current listeners (network redirections) into a string.
format_listeners()141 std::string format_listeners() {
142     std::string result;
143     for (alistener* l = listener_list.next; l != &listener_list; l = l->next) {
144         // Ignore special listeners like those for *smartsocket*
145         if (l->connect_to[0] == '*') {
146             continue;
147         }
148         //  <device-serial> " " <local-name> " " <remote-name> "\n"
149         // Entries from "adb reverse" have no serial.
150         android::base::StringAppendF(&result, "%s %s %s\n",
151                                      l->transport->serial ? l->transport->serial : "(reverse)",
152                                      l->local_name, l->connect_to);
153     }
154     return result;
155 }
156 
remove_listener(const char * local_name,atransport * transport)157 InstallStatus remove_listener(const char *local_name, atransport* transport) {
158     alistener *l;
159 
160     for (l = listener_list.next; l != &listener_list; l = l->next) {
161         if (!strcmp(local_name, l->local_name)) {
162             free_listener(l);
163             return INSTALL_STATUS_OK;
164         }
165     }
166     return INSTALL_STATUS_LISTENER_NOT_FOUND;
167 }
168 
remove_all_listeners(void)169 void remove_all_listeners(void)
170 {
171     alistener *l, *l_next;
172     for (l = listener_list.next; l != &listener_list; l = l_next) {
173         l_next = l->next;
174         // Never remove smart sockets.
175         if (l->connect_to[0] == '*')
176             continue;
177         free_listener(l);
178     }
179 }
180 
install_listener(const std::string & local_name,const char * connect_to,atransport * transport,int no_rebind,std::string * error)181 InstallStatus install_listener(const std::string& local_name,
182                                   const char *connect_to,
183                                   atransport* transport,
184                                   int no_rebind,
185                                   std::string* error)
186 {
187     for (alistener* l = listener_list.next; l != &listener_list; l = l->next) {
188         if (local_name == l->local_name) {
189             char* cto;
190 
191             /* can't repurpose a smartsocket */
192             if(l->connect_to[0] == '*') {
193                 *error = "cannot repurpose smartsocket";
194                 return INSTALL_STATUS_INTERNAL_ERROR;
195             }
196 
197             /* can't repurpose a listener if 'no_rebind' is true */
198             if (no_rebind) {
199                 *error = "cannot rebind";
200                 return INSTALL_STATUS_CANNOT_REBIND;
201             }
202 
203             cto = strdup(connect_to);
204             if(cto == 0) {
205                 *error = "cannot duplicate string";
206                 return INSTALL_STATUS_INTERNAL_ERROR;
207             }
208 
209             free((void*) l->connect_to);
210             l->connect_to = cto;
211             if (l->transport != transport) {
212                 l->transport->RemoveDisconnect(&l->disconnect);
213                 l->transport = transport;
214                 l->transport->AddDisconnect(&l->disconnect);
215             }
216             return INSTALL_STATUS_OK;
217         }
218     }
219 
220     alistener* listener = reinterpret_cast<alistener*>(
221         calloc(1, sizeof(alistener)));
222     if (listener == nullptr) {
223         goto nomem;
224     }
225 
226     listener->local_name = strdup(local_name.c_str());
227     if (listener->local_name == nullptr) {
228         goto nomem;
229     }
230 
231     listener->connect_to = strdup(connect_to);
232     if (listener->connect_to == nullptr) {
233         goto nomem;
234     }
235 
236     listener->fd = local_name_to_fd(listener->local_name, error);
237     if (listener->fd < 0) {
238         free(listener->local_name);
239         free(listener->connect_to);
240         free(listener);
241         return INSTALL_STATUS_CANNOT_BIND;
242     }
243 
244     close_on_exec(listener->fd);
245     if (!strcmp(listener->connect_to, "*smartsocket*")) {
246         fdevent_install(&listener->fde, listener->fd, ss_listener_event_func,
247                         listener);
248     } else {
249         fdevent_install(&listener->fde, listener->fd, listener_event_func,
250                         listener);
251     }
252     fdevent_set(&listener->fde, FDE_READ);
253 
254     listener->next = &listener_list;
255     listener->prev = listener_list.prev;
256     listener->next->prev = listener;
257     listener->prev->next = listener;
258     listener->transport = transport;
259 
260     if (transport) {
261         listener->disconnect.opaque = listener;
262         listener->disconnect.func   = listener_disconnect;
263         transport->AddDisconnect(&listener->disconnect);
264     }
265     return INSTALL_STATUS_OK;
266 
267 nomem:
268     fatal("cannot allocate listener");
269     return INSTALL_STATUS_INTERNAL_ERROR;
270 }
271