From 48704798ea79a4cf0a4024ffcd18fc11ca03a43c Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Mon, 19 Mar 2012 15:52:03 -0700 Subject: run minadbd as shell user, remove unused code Make minadbd drop its root privileges after initializing. We need to make the /tmp directory writable by the shell group so that it can drop the sideloaded file there. --- etc/init.rc | 3 + minadbd/README.txt | 14 +- minadbd/adb.c | 757 +----------------------------------------------- minadbd/adb.h | 27 +- minadbd/services.c | 1 + minadbd/sockets.c | 100 ------- minadbd/sysdeps.h | 25 +- minadbd/transport.c | 257 ---------------- minadbd/transport_usb.c | 27 -- 9 files changed, 40 insertions(+), 1171 deletions(-) diff --git a/etc/init.rc b/etc/init.rc index a301779aa..bf4ce62b5 100644 --- a/etc/init.rc +++ b/etc/init.rc @@ -15,6 +15,9 @@ on init mkdir /cache mount /tmp /tmp tmpfs + chown root shell /tmp + chmod 0775 /tmp + write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct D001 diff --git a/minadbd/README.txt b/minadbd/README.txt index 0c190d05d..c9df484c3 100644 --- a/minadbd/README.txt +++ b/minadbd/README.txt @@ -4,16 +4,19 @@ the following changes: adb.c - much support for host mode and non-linux OS's stripped out; this version only runs as adbd on the device. - - does not setuid/setgid itself (always stays root) + - always setuid/setgid's itself to the shell user - only uses USB transport - references to JDWP removed - main() removed + - all ADB_HOST and win32 code removed + - removed listeners, logging code, background server (for host) adb.h - minor changes to match adb.c changes sockets.c - references to JDWP removed + - ADB_HOST code removed services.c - all services except echo_service (which is commented out) removed @@ -25,3 +28,12 @@ services.c Android.mk - only builds in adbd mode; builds as static library instead of a standalone executable. + +sysdeps.h + - changes adb_creat() to use O_NOFOLLOW + +transport.c + - removed ADB_HOST code + +transport_usb.c + - removed ADB_HOST code diff --git a/minadbd/adb.c b/minadbd/adb.c index d1e97b31f..0e8fd2a7e 100644 --- a/minadbd/adb.c +++ b/minadbd/adb.c @@ -28,13 +28,9 @@ #include "sysdeps.h" #include "adb.h" -#if !ADB_HOST #include #include #include -#else -#include "usb_vendors.h" -#endif #if ADB_TRACE ADB_MUTEX_DEFINE( D_lock ); @@ -228,29 +224,6 @@ static void send_connect(atransport *t) HOST ? "host" : adb_device_banner); cp->msg.data_length = strlen((char*) cp->data) + 1; send_packet(cp, t); -#if ADB_HOST - /* XXX why sleep here? */ - // allow the device some time to respond to the connect message - adb_sleep_ms(1000); -#endif -} - -static char *connection_state_name(atransport *t) -{ - if (t == NULL) { - return "unknown"; - } - - switch(t->connection_state) { - case CS_BOOTLOADER: - return "bootloader"; - case CS_DEVICE: - return "device"; - case CS_OFFLINE: - return "offline"; - default: - return "unknown"; - } } void parse_banner(char *banner, atransport *t) @@ -400,448 +373,11 @@ void handle_packet(apacket *p, atransport *t) put_apacket(p); } -alistener listener_list = { - .next = &listener_list, - .prev = &listener_list, -}; - -static void ss_listener_event_func(int _fd, unsigned ev, void *_l) -{ - asocket *s; - - if(ev & FDE_READ) { - struct sockaddr addr; - socklen_t alen; - int fd; - - alen = sizeof(addr); - fd = adb_socket_accept(_fd, &addr, &alen); - if(fd < 0) return; - - adb_socket_setbufsize(fd, CHUNK_SIZE); - - s = create_local_socket(fd); - if(s) { - connect_to_smartsocket(s); - return; - } - - adb_close(fd); - } -} - -static void listener_event_func(int _fd, unsigned ev, void *_l) -{ - alistener *l = _l; - asocket *s; - - if(ev & FDE_READ) { - struct sockaddr addr; - socklen_t alen; - int fd; - - alen = sizeof(addr); - fd = adb_socket_accept(_fd, &addr, &alen); - if(fd < 0) return; - - s = create_local_socket(fd); - if(s) { - s->transport = l->transport; - connect_to_remote(s, l->connect_to); - return; - } - - adb_close(fd); - } -} - -static void free_listener(alistener* l) -{ - if (l->next) { - l->next->prev = l->prev; - l->prev->next = l->next; - l->next = l->prev = l; - } - - // closes the corresponding fd - fdevent_remove(&l->fde); - - if (l->local_name) - free((char*)l->local_name); - - if (l->connect_to) - free((char*)l->connect_to); - - if (l->transport) { - remove_transport_disconnect(l->transport, &l->disconnect); - } - free(l); -} - -static void listener_disconnect(void* _l, atransport* t) -{ - alistener* l = _l; - - free_listener(l); -} - -int local_name_to_fd(const char *name) -{ - int port; - - if(!strncmp("tcp:", name, 4)){ - int ret; - port = atoi(name + 4); - ret = socket_loopback_server(port, SOCK_STREAM); - return ret; - } -#ifndef HAVE_WIN32_IPC /* no Unix-domain sockets on Win32 */ - // It's non-sensical to support the "reserved" space on the adb host side - if(!strncmp(name, "local:", 6)) { - return socket_local_server(name + 6, - ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); - } else if(!strncmp(name, "localabstract:", 14)) { - return socket_local_server(name + 14, - ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); - } else if(!strncmp(name, "localfilesystem:", 16)) { - return socket_local_server(name + 16, - ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM); - } - -#endif - printf("unknown local portname '%s'\n", name); - return -1; -} - -static int remove_listener(const char *local_name, const char *connect_to, atransport* transport) -{ - alistener *l; - - for (l = listener_list.next; l != &listener_list; l = l->next) { - if (!strcmp(local_name, l->local_name) && - !strcmp(connect_to, l->connect_to) && - l->transport && l->transport == transport) { - - listener_disconnect(l, transport); - return 0; - } - } - - return -1; -} - -static int install_listener(const char *local_name, const char *connect_to, atransport* transport) -{ - alistener *l; - - //printf("install_listener('%s','%s')\n", local_name, connect_to); - - for(l = listener_list.next; l != &listener_list; l = l->next){ - if(strcmp(local_name, l->local_name) == 0) { - char *cto; - - /* can't repurpose a smartsocket */ - if(l->connect_to[0] == '*') { - return -1; - } - - cto = strdup(connect_to); - if(cto == 0) { - return -1; - } - - //printf("rebinding '%s' to '%s'\n", local_name, connect_to); - free((void*) l->connect_to); - l->connect_to = cto; - if (l->transport != transport) { - remove_transport_disconnect(l->transport, &l->disconnect); - l->transport = transport; - add_transport_disconnect(l->transport, &l->disconnect); - } - return 0; - } - } - - if((l = calloc(1, sizeof(alistener))) == 0) goto nomem; - if((l->local_name = strdup(local_name)) == 0) goto nomem; - if((l->connect_to = strdup(connect_to)) == 0) goto nomem; - - - l->fd = local_name_to_fd(local_name); - if(l->fd < 0) { - free((void*) l->local_name); - free((void*) l->connect_to); - free(l); - printf("cannot bind '%s'\n", local_name); - return -2; - } - - close_on_exec(l->fd); - if(!strcmp(l->connect_to, "*smartsocket*")) { - fdevent_install(&l->fde, l->fd, ss_listener_event_func, l); - } else { - fdevent_install(&l->fde, l->fd, listener_event_func, l); - } - fdevent_set(&l->fde, FDE_READ); - - l->next = &listener_list; - l->prev = listener_list.prev; - l->next->prev = l; - l->prev->next = l; - l->transport = transport; - - if (transport) { - l->disconnect.opaque = l; - l->disconnect.func = listener_disconnect; - add_transport_disconnect(transport, &l->disconnect); - } - return 0; - -nomem: - fatal("cannot allocate listener"); - return 0; -} - -#ifdef HAVE_WIN32_PROC -static BOOL WINAPI ctrlc_handler(DWORD type) -{ - exit(STATUS_CONTROL_C_EXIT); - return TRUE; -} -#endif - static void adb_cleanup(void) { usb_cleanup(); } -void start_logging(void) -{ -#ifdef HAVE_WIN32_PROC - char temp[ MAX_PATH ]; - FILE* fnul; - FILE* flog; - - GetTempPath( sizeof(temp) - 8, temp ); - strcat( temp, "adb.log" ); - - /* Win32 specific redirections */ - fnul = fopen( "NUL", "rt" ); - if (fnul != NULL) - stdin[0] = fnul[0]; - - flog = fopen( temp, "at" ); - if (flog == NULL) - flog = fnul; - - setvbuf( flog, NULL, _IONBF, 0 ); - - stdout[0] = flog[0]; - stderr[0] = flog[0]; - fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); -#else - int fd; - - fd = unix_open("/dev/null", O_RDONLY); - dup2(fd, 0); - adb_close(fd); - - fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640); - if(fd < 0) { - fd = unix_open("/dev/null", O_WRONLY); - } - dup2(fd, 1); - dup2(fd, 2); - adb_close(fd); - fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); -#endif -} - -#if !ADB_HOST -void start_device_log(void) -{ - int fd; - char path[PATH_MAX]; - struct tm now; - time_t t; - char value[PROPERTY_VALUE_MAX]; - - // read the trace mask from persistent property persist.adb.trace_mask - // give up if the property is not set or cannot be parsed - property_get("persist.adb.trace_mask", value, ""); - if (sscanf(value, "%x", &adb_trace_mask) != 1) - return; - - adb_mkdir("/data/adb", 0775); - tzset(); - time(&t); - localtime_r(&t, &now); - strftime(path, sizeof(path), - "/data/adb/adb-%Y-%m-%d-%H-%M-%S.txt", - &now); - fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0640); - if (fd < 0) - return; - - // redirect stdout and stderr to the log file - dup2(fd, 1); - dup2(fd, 2); - fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); - adb_close(fd); - - fd = unix_open("/dev/null", O_RDONLY); - dup2(fd, 0); - adb_close(fd); -} -#endif - -#if ADB_HOST -int launch_server(int server_port) -{ -#ifdef HAVE_WIN32_PROC - /* we need to start the server in the background */ - /* we create a PIPE that will be used to wait for the server's "OK" */ - /* message since the pipe handles must be inheritable, we use a */ - /* security attribute */ - HANDLE pipe_read, pipe_write; - SECURITY_ATTRIBUTES sa; - STARTUPINFO startup; - PROCESS_INFORMATION pinfo; - char program_path[ MAX_PATH ]; - int ret; - - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - - /* create pipe, and ensure its read handle isn't inheritable */ - ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 ); - if (!ret) { - fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() ); - return -1; - } - - SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 ); - - ZeroMemory( &startup, sizeof(startup) ); - startup.cb = sizeof(startup); - startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE ); - startup.hStdOutput = pipe_write; - startup.hStdError = GetStdHandle( STD_ERROR_HANDLE ); - startup.dwFlags = STARTF_USESTDHANDLES; - - ZeroMemory( &pinfo, sizeof(pinfo) ); - - /* get path of current program */ - GetModuleFileName( NULL, program_path, sizeof(program_path) ); - - ret = CreateProcess( - program_path, /* program path */ - "adb fork-server server", - /* the fork-server argument will set the - debug = 2 in the child */ - NULL, /* process handle is not inheritable */ - NULL, /* thread handle is not inheritable */ - TRUE, /* yes, inherit some handles */ - DETACHED_PROCESS, /* the new process doesn't have a console */ - NULL, /* use parent's environment block */ - NULL, /* use parent's starting directory */ - &startup, /* startup info, i.e. std handles */ - &pinfo ); - - CloseHandle( pipe_write ); - - if (!ret) { - fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() ); - CloseHandle( pipe_read ); - return -1; - } - - CloseHandle( pinfo.hProcess ); - CloseHandle( pinfo.hThread ); - - /* wait for the "OK\n" message */ - { - char temp[3]; - DWORD count; - - ret = ReadFile( pipe_read, temp, 3, &count, NULL ); - CloseHandle( pipe_read ); - if ( !ret ) { - fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() ); - return -1; - } - if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { - fprintf(stderr, "ADB server didn't ACK\n" ); - return -1; - } - } -#elif defined(HAVE_FORKEXEC) - char path[PATH_MAX]; - int fd[2]; - - // set up a pipe so the child can tell us when it is ready. - // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child. - if (pipe(fd)) { - fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); - return -1; - } - get_my_path(path, PATH_MAX); - pid_t pid = fork(); - if(pid < 0) return -1; - - if (pid == 0) { - // child side of the fork - - // redirect stderr to the pipe - // we use stderr instead of stdout due to stdout's buffering behavior. - adb_close(fd[0]); - dup2(fd[1], STDERR_FILENO); - adb_close(fd[1]); - - // child process - int result = execl(path, "adb", "fork-server", "server", NULL); - // this should not return - fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno); - } else { - // parent side of the fork - - char temp[3]; - - temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C'; - // wait for the "OK\n" message - adb_close(fd[1]); - int ret = adb_read(fd[0], temp, 3); - int saved_errno = errno; - adb_close(fd[0]); - if (ret < 0) { - fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno); - return -1; - } - if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { - fprintf(stderr, "ADB server didn't ACK\n" ); - return -1; - } - - setsid(); - } -#else -#error "cannot implement background server start on this platform" -#endif - return 0; -} -#endif - -/* Constructs a local name of form tcp:port. - * target_str points to the target string, it's content will be overwritten. - * target_size is the capacity of the target string. - * server_port is the port number to use for the local name. - */ -void build_local_name(char* target_str, size_t target_size, int server_port) -{ - snprintf(target_str, target_size, "tcp:%d", server_port); -} - int adb_main() { atexit(adb_cleanup); @@ -858,6 +394,16 @@ int adb_main() usb_init(); } + if (setgid(AID_SHELL) != 0) { + fprintf(stderr, "failed to setgid to shell\n"); + exit(1); + } + if (setuid(AID_SHELL) != 0) { + fprintf(stderr, "failed to setuid to shell\n"); + exit(1); + } + fprintf(stderr, "userid is %d\n", getuid()); + D("Event loop starting\n"); fdevent_loop(); @@ -866,286 +412,3 @@ int adb_main() return 0; } - -#if ADB_HOST -void connect_device(char* host, char* buffer, int buffer_size) -{ - int port, fd; - char* portstr = strchr(host, ':'); - char hostbuf[100]; - char serial[100]; - - strncpy(hostbuf, host, sizeof(hostbuf) - 1); - if (portstr) { - if (portstr - host >= sizeof(hostbuf)) { - snprintf(buffer, buffer_size, "bad host name %s", host); - return; - } - // zero terminate the host at the point we found the colon - hostbuf[portstr - host] = 0; - if (sscanf(portstr + 1, "%d", &port) == 0) { - snprintf(buffer, buffer_size, "bad port number %s", portstr); - return; - } - } else { - port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; - } - - snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port); - if (find_transport(serial)) { - snprintf(buffer, buffer_size, "already connected to %s", serial); - return; - } - - fd = socket_network_client(hostbuf, port, SOCK_STREAM); - if (fd < 0) { - snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port); - return; - } - - D("client: connected on remote on fd %d\n", fd); - close_on_exec(fd); - disable_tcp_nagle(fd); - register_socket_transport(fd, serial, port, 0); - snprintf(buffer, buffer_size, "connected to %s", serial); -} - -void connect_emulator(char* port_spec, char* buffer, int buffer_size) -{ - char* port_separator = strchr(port_spec, ','); - if (!port_separator) { - snprintf(buffer, buffer_size, - "unable to parse '%s' as ,", - port_spec); - return; - } - - // Zero-terminate console port and make port_separator point to 2nd port. - *port_separator++ = 0; - int console_port = strtol(port_spec, NULL, 0); - int adb_port = strtol(port_separator, NULL, 0); - if (!(console_port > 0 && adb_port > 0)) { - *(port_separator - 1) = ','; - snprintf(buffer, buffer_size, - "Invalid port numbers: Expected positive numbers, got '%s'", - port_spec); - return; - } - - /* Check if the emulator is already known. - * Note: There's a small but harmless race condition here: An emulator not - * present just yet could be registered by another invocation right - * after doing this check here. However, local_connect protects - * against double-registration too. From here, a better error message - * can be produced. In the case of the race condition, the very specific - * error message won't be shown, but the data doesn't get corrupted. */ - atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port); - if (known_emulator != NULL) { - snprintf(buffer, buffer_size, - "Emulator on port %d already registered.", adb_port); - return; - } - - /* Check if more emulators can be registered. Similar unproblematic - * race condition as above. */ - int candidate_slot = get_available_local_transport_index(); - if (candidate_slot < 0) { - snprintf(buffer, buffer_size, "Cannot accept more emulators."); - return; - } - - /* Preconditions met, try to connect to the emulator. */ - if (!local_connect_arbitrary_ports(console_port, adb_port)) { - snprintf(buffer, buffer_size, - "Connected to emulator on ports %d,%d", console_port, adb_port); - } else { - snprintf(buffer, buffer_size, - "Could not connect to emulator on ports %d,%d", - console_port, adb_port); - } -} -#endif - -int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s) -{ - atransport *transport = NULL; - char buf[4096]; - - if(!strcmp(service, "kill")) { - fprintf(stderr,"adb server killed by remote request\n"); - fflush(stdout); - adb_write(reply_fd, "OKAY", 4); - usb_cleanup(); - exit(0); - } - -#if ADB_HOST - // "transport:" is used for switching transport with a specified serial number - // "transport-usb:" is used for switching transport to the only USB transport - // "transport-local:" is used for switching transport to the only local transport - // "transport-any:" is used for switching transport to the only transport - if (!strncmp(service, "transport", strlen("transport"))) { - char* error_string = "unknown failure"; - transport_type type = kTransportAny; - - if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { - type = kTransportUsb; - } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { - type = kTransportLocal; - } else if (!strncmp(service, "transport-any", strlen("transport-any"))) { - type = kTransportAny; - } else if (!strncmp(service, "transport:", strlen("transport:"))) { - service += strlen("transport:"); - serial = service; - } - - transport = acquire_one_transport(CS_ANY, type, serial, &error_string); - - if (transport) { - s->transport = transport; - adb_write(reply_fd, "OKAY", 4); - } else { - sendfailmsg(reply_fd, error_string); - } - return 1; - } - - // return a list of all connected devices - if (!strcmp(service, "devices")) { - char buffer[4096]; - memset(buf, 0, sizeof(buf)); - memset(buffer, 0, sizeof(buffer)); - D("Getting device list \n"); - list_transports(buffer, sizeof(buffer)); - snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer); - D("Wrote device list \n"); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - - // add a new TCP transport, device or emulator - if (!strncmp(service, "connect:", 8)) { - char buffer[4096]; - char* host = service + 8; - if (!strncmp(host, "emu:", 4)) { - connect_emulator(host + 4, buffer, sizeof(buffer)); - } else { - connect_device(host, buffer, sizeof(buffer)); - } - // Send response for emulator and device - snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - - // remove TCP transport - if (!strncmp(service, "disconnect:", 11)) { - char buffer[4096]; - memset(buffer, 0, sizeof(buffer)); - char* serial = service + 11; - if (serial[0] == 0) { - // disconnect from all TCP devices - unregister_all_tcp_transports(); - } else { - char hostbuf[100]; - // assume port 5555 if no port is specified - if (!strchr(serial, ':')) { - snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial); - serial = hostbuf; - } - atransport *t = find_transport(serial); - - if (t) { - unregister_transport(t); - } else { - snprintf(buffer, sizeof(buffer), "No such device %s", serial); - } - } - - snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - - // returns our value for ADB_SERVER_VERSION - if (!strcmp(service, "version")) { - char version[12]; - snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION); - snprintf(buf, sizeof buf, "OKAY%04x%s", (unsigned)strlen(version), version); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - - if(!strncmp(service,"get-serialno",strlen("get-serialno"))) { - char *out = "unknown"; - transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); - if (transport && transport->serial) { - out = transport->serial; - } - snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - // indicates a new emulator instance has started - if (!strncmp(service,"emulator:",9)) { - int port = atoi(service+9); - local_connect(port); - /* we don't even need to send a reply */ - return 0; - } -#endif // ADB_HOST - - if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) { - char *local, *remote, *err; - int r; - atransport *transport; - - int createForward = strncmp(service,"kill",4); - - local = service + (createForward ? 8 : 12); - remote = strchr(local,';'); - if(remote == 0) { - sendfailmsg(reply_fd, "malformed forward spec"); - return 0; - } - - *remote++ = 0; - if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){ - sendfailmsg(reply_fd, "malformed forward spec"); - return 0; - } - - transport = acquire_one_transport(CS_ANY, ttype, serial, &err); - if (!transport) { - sendfailmsg(reply_fd, err); - return 0; - } - - if (createForward) { - r = install_listener(local, remote, transport); - } else { - r = remove_listener(local, remote, transport); - } - if(r == 0) { - /* 1st OKAY is connect, 2nd OKAY is status */ - writex(reply_fd, "OKAYOKAY", 8); - return 0; - } - - if (createForward) { - sendfailmsg(reply_fd, (r == -1) ? "cannot rebind smartsocket" : "cannot bind socket"); - } else { - sendfailmsg(reply_fd, "cannot remove listener"); - } - return 0; - } - - if(!strncmp(service,"get-state",strlen("get-state"))) { - transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); - char *state = connection_state_name(transport); - snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - return -1; -} diff --git a/minadbd/adb.h b/minadbd/adb.h index a989eddab..98fa5972e 100644 --- a/minadbd/adb.h +++ b/minadbd/adb.h @@ -41,7 +41,6 @@ typedef struct amessage amessage; typedef struct apacket apacket; typedef struct asocket asocket; -typedef struct alistener alistener; typedef struct aservice aservice; typedef struct atransport atransport; typedef struct adisconnect adisconnect; @@ -134,7 +133,7 @@ struct asocket { /* the adisconnect structure is used to record a callback that ** will be called whenever a transport is disconnected (e.g. by the user) ** this should be used to cleanup objects that depend on the -** transport (e.g. remote sockets, listeners, etc...) +** transport (e.g. remote sockets, etc...) */ struct adisconnect { @@ -194,30 +193,6 @@ struct atransport }; -/* A listener is an entity which binds to a local port -** and, upon receiving a connection on that port, creates -** an asocket to connect the new local connection to a -** specific remote service. -** -** TODO: some listeners read from the new connection to -** determine what exact service to connect to on the far -** side. -*/ -struct alistener -{ - alistener *next; - alistener *prev; - - fdevent fde; - int fd; - - const char *local_name; - const char *connect_to; - atransport *transport; - adisconnect disconnect; -}; - - void print_packet(const char *label, apacket *p); asocket *find_local_socket(unsigned id); diff --git a/minadbd/services.c b/minadbd/services.c index 8fc8b3ccb..aef37f7e4 100644 --- a/minadbd/services.c +++ b/minadbd/services.c @@ -53,6 +53,7 @@ static void sideload_service(int s, void *cookie) fd = adb_creat(ADB_SIDELOAD_FILENAME, 0644); if(fd < 0) { + fprintf(stderr, "failed to create %s\n", ADB_SIDELOAD_FILENAME); adb_close(s); return; } diff --git a/minadbd/sockets.c b/minadbd/sockets.c index 9f4cecb3a..2dd646159 100644 --- a/minadbd/sockets.c +++ b/minadbd/sockets.c @@ -413,22 +413,6 @@ asocket *create_local_service_socket(const char *name) return s; } -#if ADB_HOST -static asocket *create_host_service_socket(const char *name, const char* serial) -{ - asocket *s; - - s = host_service_to_socket(name, serial); - - if (s != NULL) { - D("LS(%d) bound to '%s'\n", s->id, name); - return s; - } - - return s; -} -#endif /* ADB_HOST */ - /* a Remote socket is used to send/receive data to/from a given transport object ** it needs to be closed when the transport is forcibly destroyed by the user */ @@ -612,11 +596,6 @@ char *skip_host_serial(char *service) { static int smart_socket_enqueue(asocket *s, apacket *p) { unsigned len; -#if ADB_HOST - char *service = NULL; - char* serial = NULL; - transport_type ttype = kTransportAny; -#endif D("SS(%d): enqueue %d\n", s->id, p->len); @@ -658,84 +637,6 @@ static int smart_socket_enqueue(asocket *s, apacket *p) D("SS(%d): '%s'\n", s->id, (char*) (p->data + 4)); -#if ADB_HOST - service = (char *)p->data + 4; - if(!strncmp(service, "host-serial:", strlen("host-serial:"))) { - char* serial_end; - service += strlen("host-serial:"); - - // serial number should follow "host:" and could be a host:port string. - serial_end = skip_host_serial(service); - if (serial_end) { - *serial_end = 0; // terminate string - serial = service; - service = serial_end + 1; - } - } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) { - ttype = kTransportUsb; - service += strlen("host-usb:"); - } else if (!strncmp(service, "host-local:", strlen("host-local:"))) { - ttype = kTransportLocal; - service += strlen("host-local:"); - } else if (!strncmp(service, "host:", strlen("host:"))) { - ttype = kTransportAny; - service += strlen("host:"); - } else { - service = NULL; - } - - if (service) { - asocket *s2; - - /* some requests are handled immediately -- in that - ** case the handle_host_request() routine has sent - ** the OKAY or FAIL message and all we have to do - ** is clean up. - */ - if(handle_host_request(service, ttype, serial, s->peer->fd, s) == 0) { - /* XXX fail message? */ - D( "SS(%d): handled host service '%s'\n", s->id, service ); - goto fail; - } - if (!strncmp(service, "transport", strlen("transport"))) { - D( "SS(%d): okay transport\n", s->id ); - p->len = 0; - return 0; - } - - /* try to find a local service with this name. - ** if no such service exists, we'll fail out - ** and tear down here. - */ - s2 = create_host_service_socket(service, serial); - if(s2 == 0) { - D( "SS(%d): couldn't create host service '%s'\n", s->id, service ); - sendfailmsg(s->peer->fd, "unknown host service"); - goto fail; - } - - /* we've connected to a local host service, - ** so we make our peer back into a regular - ** local socket and bind it to the new local - ** service socket, acknowledge the successful - ** connection, and close this smart socket now - ** that its work is done. - */ - adb_write(s->peer->fd, "OKAY", 4); - - s->peer->ready = local_socket_ready; - s->peer->close = local_socket_close; - s->peer->peer = s2; - s2->peer = s->peer; - s->peer = 0; - D( "SS(%d): okay\n", s->id ); - s->close(s); - - /* initial state is "ready" */ - s2->ready(s2); - return 0; - } -#else /* !ADB_HOST */ if (s->transport == NULL) { char* error_string = "unknown failure"; s->transport = acquire_one_transport (CS_ANY, @@ -746,7 +647,6 @@ static int smart_socket_enqueue(asocket *s, apacket *p) goto fail; } } -#endif if(!(s->transport) || (s->transport->connection_state == CS_OFFLINE)) { /* if there's no remote we fail the connection diff --git a/minadbd/sysdeps.h b/minadbd/sysdeps.h index b51807615..800ddb753 100644 --- a/minadbd/sysdeps.h +++ b/minadbd/sysdeps.h @@ -324,6 +324,18 @@ static __inline__ int adb_open_mode( const char* pathname, int options, int return open( pathname, options, mode ); } +static __inline__ int adb_creat(const char* path, int mode) +{ + int fd = open(path, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW, mode); + + if ( fd < 0 ) + return -1; + + close_on_exec(fd); + return fd; +} +#undef creat +#define creat ___xxx_creat static __inline__ int adb_open( const char* pathname, int options ) { @@ -380,19 +392,6 @@ static __inline__ int adb_unlink(const char* path) #undef unlink #define unlink ___xxx_unlink -static __inline__ int adb_creat(const char* path, int mode) -{ - int fd = creat(path, mode); - - if ( fd < 0 ) - return -1; - - close_on_exec(fd); - return fd; -} -#undef creat -#define creat ___xxx_creat - static __inline__ int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen) { int fd; diff --git a/minadbd/transport.c b/minadbd/transport.c index 2f7bd2784..ff2004932 100644 --- a/minadbd/transport.c +++ b/minadbd/transport.c @@ -363,154 +363,10 @@ static int transport_registration_send = -1; static int transport_registration_recv = -1; static fdevent transport_registration_fde; - -#if ADB_HOST -static int list_transports_msg(char* buffer, size_t bufferlen) -{ - char head[5]; - int len; - - len = list_transports(buffer+4, bufferlen-4); - snprintf(head, sizeof(head), "%04x", len); - memcpy(buffer, head, 4); - len += 4; - return len; -} - -/* this adds support required by the 'track-devices' service. - * this is used to send the content of "list_transport" to any - * number of client connections that want it through a single - * live TCP connection - */ -typedef struct device_tracker device_tracker; -struct device_tracker { - asocket socket; - int update_needed; - device_tracker* next; -}; - -/* linked list of all device trackers */ -static device_tracker* device_tracker_list; - -static void -device_tracker_remove( device_tracker* tracker ) -{ - device_tracker** pnode = &device_tracker_list; - device_tracker* node = *pnode; - - adb_mutex_lock( &transport_lock ); - while (node) { - if (node == tracker) { - *pnode = node->next; - break; - } - pnode = &node->next; - node = *pnode; - } - adb_mutex_unlock( &transport_lock ); -} - -static void -device_tracker_close( asocket* socket ) -{ - device_tracker* tracker = (device_tracker*) socket; - asocket* peer = socket->peer; - - D( "device tracker %p removed\n", tracker); - if (peer) { - peer->peer = NULL; - peer->close(peer); - } - device_tracker_remove(tracker); - free(tracker); -} - -static int -device_tracker_enqueue( asocket* socket, apacket* p ) -{ - /* you can't read from a device tracker, close immediately */ - put_apacket(p); - device_tracker_close(socket); - return -1; -} - -static int -device_tracker_send( device_tracker* tracker, - const char* buffer, - int len ) -{ - apacket* p = get_apacket(); - asocket* peer = tracker->socket.peer; - - memcpy(p->data, buffer, len); - p->len = len; - return peer->enqueue( peer, p ); -} - - -static void -device_tracker_ready( asocket* socket ) -{ - device_tracker* tracker = (device_tracker*) socket; - - /* we want to send the device list when the tracker connects - * for the first time, even if no update occured */ - if (tracker->update_needed > 0) { - char buffer[1024]; - int len; - - tracker->update_needed = 0; - - len = list_transports_msg(buffer, sizeof(buffer)); - device_tracker_send(tracker, buffer, len); - } -} - - -asocket* -create_device_tracker(void) -{ - device_tracker* tracker = calloc(1,sizeof(*tracker)); - - if(tracker == 0) fatal("cannot allocate device tracker"); - - D( "device tracker %p created\n", tracker); - - tracker->socket.enqueue = device_tracker_enqueue; - tracker->socket.ready = device_tracker_ready; - tracker->socket.close = device_tracker_close; - tracker->update_needed = 1; - - tracker->next = device_tracker_list; - device_tracker_list = tracker; - - return &tracker->socket; -} - - -/* call this function each time the transport list has changed */ -void update_transports(void) -{ - char buffer[1024]; - int len; - device_tracker* tracker; - - len = list_transports_msg(buffer, sizeof(buffer)); - - tracker = device_tracker_list; - while (tracker != NULL) { - device_tracker* next = tracker->next; - /* note: this may destroy the tracker if the connection is closed */ - device_tracker_send(tracker, buffer, len); - tracker = next; - } -} -#else void update_transports(void) { // nothing to do on the device side } -#endif // ADB_HOST typedef struct tmsg tmsg; struct tmsg @@ -822,64 +678,6 @@ retry: return result; } -#if ADB_HOST -static const char *statename(atransport *t) -{ - switch(t->connection_state){ - case CS_OFFLINE: return "offline"; - case CS_BOOTLOADER: return "bootloader"; - case CS_DEVICE: return "device"; - case CS_HOST: return "host"; - case CS_RECOVERY: return "recovery"; - case CS_SIDELOAD: return "sideload"; - case CS_NOPERM: return "no permissions"; - default: return "unknown"; - } -} - -int list_transports(char *buf, size_t bufsize) -{ - char* p = buf; - char* end = buf + bufsize; - int len; - atransport *t; - - /* XXX OVERRUN PROBLEMS XXX */ - adb_mutex_lock(&transport_lock); - for(t = transport_list.next; t != &transport_list; t = t->next) { - const char* serial = t->serial; - if (!serial || !serial[0]) - serial = "????????????"; - len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t)); - - if (p + len >= end) { - /* discard last line if buffer is too short */ - break; - } - p += len; - } - p[0] = 0; - adb_mutex_unlock(&transport_lock); - return p - buf; -} - - -/* hack for osx */ -void close_usb_devices() -{ - atransport *t; - - adb_mutex_lock(&transport_lock); - for(t = transport_list.next; t != &transport_list; t = t->next) { - if ( !t->kicked ) { - t->kicked = 1; - t->kick(t); - } - } - adb_mutex_unlock(&transport_lock); -} -#endif // ADB_HOST - void register_socket_transport(int s, const char *serial, int port, int local) { atransport *t = calloc(1, sizeof(atransport)); @@ -901,61 +699,6 @@ void register_socket_transport(int s, const char *serial, int port, int local) register_transport(t); } -#if ADB_HOST -atransport *find_transport(const char *serial) -{ - atransport *t; - - adb_mutex_lock(&transport_lock); - for(t = transport_list.next; t != &transport_list; t = t->next) { - if (t->serial && !strcmp(serial, t->serial)) { - break; - } - } - adb_mutex_unlock(&transport_lock); - - if (t != &transport_list) - return t; - else - return 0; -} - -void unregister_transport(atransport *t) -{ - adb_mutex_lock(&transport_lock); - t->next->prev = t->prev; - t->prev->next = t->next; - adb_mutex_unlock(&transport_lock); - - kick_transport(t); - transport_unref(t); -} - -// unregisters all non-emulator TCP transports -void unregister_all_tcp_transports() -{ - atransport *t, *next; - adb_mutex_lock(&transport_lock); - for (t = transport_list.next; t != &transport_list; t = next) { - next = t->next; - if (t->type == kTransportLocal && t->adb_port == 0) { - t->next->prev = t->prev; - t->prev->next = next; - // we cannot call kick_transport when holding transport_lock - if (!t->kicked) - { - t->kicked = 1; - t->kick(t); - } - transport_unref_locked(t); - } - } - - adb_mutex_unlock(&transport_lock); -} - -#endif - void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable) { atransport *t = calloc(1, sizeof(atransport)); diff --git a/minadbd/transport_usb.c b/minadbd/transport_usb.c index ee6b637b5..91cbf6151 100644 --- a/minadbd/transport_usb.c +++ b/minadbd/transport_usb.c @@ -23,10 +23,6 @@ #define TRACE_TAG TRACE_TRANSPORT #include "adb.h" -#if ADB_HOST -#include "usb_vendors.h" -#endif - #ifdef HAVE_BIG_ENDIAN #define H4(x) (((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24) static inline void fix_endians(apacket *p) @@ -121,28 +117,5 @@ void init_usb_transport(atransport *t, usb_handle *h, int state) t->type = kTransportUsb; t->usb = h; -#if ADB_HOST - HOST = 1; -#else HOST = 0; -#endif -} - -#if ADB_HOST -int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol) -{ - unsigned i; - for (i = 0; i < vendorIdCount; i++) { - if (vid == vendorIds[i]) { - if (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && - usb_protocol == ADB_PROTOCOL) { - return 1; - } - - return 0; - } - } - - return 0; } -#endif -- cgit v1.2.3