diff options
Diffstat (limited to 'adb/adb.c')
-rw-r--r-- | adb/adb.c | 287 |
1 files changed, 161 insertions, 126 deletions
@@ -318,6 +318,26 @@ static size_t fill_connect_data(char *buf, size_t bufsize) #endif } +#if !ADB_HOST +static void send_msg_with_header(int fd, const char* msg, size_t msglen) { + char header[5]; + if (msglen > 0xffff) + msglen = 0xffff; + snprintf(header, sizeof(header), "%04x", (unsigned)msglen); + writex(fd, header, 4); + writex(fd, msg, msglen); +} +#endif + +static void send_msg_with_okay(int fd, const char* msg, size_t msglen) { + char header[9]; + if (msglen > 0xffff) + msglen = 0xffff; + snprintf(header, sizeof(header), "OKAY%04x", (unsigned)msglen); + writex(fd, header, 8); + writex(fd, msg, msglen); +} + static void send_connect(atransport *t) { D("Calling send_connect \n"); @@ -1324,29 +1344,29 @@ int adb_main(int is_daemon, int server_port) " unchanged.\n"); } + /* add extra groups: + ** AID_ADB to access the USB driver + ** AID_LOG to read system logs (adb logcat) + ** AID_INPUT to diagnose input issues (getevent) + ** AID_INET to diagnose network issues (netcfg, ping) + ** AID_GRAPHICS to access the frame buffer + ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump) + ** AID_SDCARD_R to allow reading from the SD card + ** AID_SDCARD_RW to allow writing to the SD card + ** AID_NET_BW_STATS to read out qtaguid statistics + */ + gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS, + AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW, + AID_NET_BW_STATS }; + if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { + exit(1); + } + /* don't listen on a port (default 5037) if running in secure mode */ /* don't run as root if we are running in secure mode */ if (should_drop_privileges()) { drop_capabilities_bounding_set_if_needed(); - /* add extra groups: - ** AID_ADB to access the USB driver - ** AID_LOG to read system logs (adb logcat) - ** AID_INPUT to diagnose input issues (getevent) - ** AID_INET to diagnose network issues (netcfg, ping) - ** AID_GRAPHICS to access the frame buffer - ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump) - ** AID_SDCARD_R to allow reading from the SD card - ** AID_SDCARD_RW to allow writing to the SD card - ** AID_NET_BW_STATS to read out qtaguid statistics - */ - gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS, - AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW, - AID_NET_BW_STATS }; - if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { - exit(1); - } - /* then switch user and group to "shell" */ if (setgid(AID_SHELL) != 0) { exit(1); @@ -1418,10 +1438,123 @@ int adb_main(int is_daemon, int server_port) return 0; } +// Try to handle a network forwarding request. +// This returns 1 on success, 0 on failure, and -1 to indicate this is not +// a forwarding-related request. +int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd) +{ + if (!strcmp(service, "list-forward")) { + // Create the list of forward redirections. + int buffer_size = format_listeners(NULL, 0); + // Add one byte for the trailing zero. + char* buffer = malloc(buffer_size + 1); + if (buffer == NULL) { + sendfailmsg(reply_fd, "not enough memory"); + return 1; + } + (void) format_listeners(buffer, buffer_size + 1); +#if ADB_HOST + send_msg_with_okay(reply_fd, buffer, buffer_size); +#else + send_msg_with_header(reply_fd, buffer, buffer_size); +#endif + free(buffer); + return 1; + } + + if (!strcmp(service, "killforward-all")) { + remove_all_listeners(); +#if ADB_HOST + /* On the host: 1st OKAY is connect, 2nd OKAY is status */ + adb_write(reply_fd, "OKAY", 4); +#endif + adb_write(reply_fd, "OKAY", 4); + return 1; + } + + if (!strncmp(service, "forward:",8) || + !strncmp(service, "killforward:",12)) { + char *local, *remote, *err; + int r; + atransport *transport; + + int createForward = strncmp(service, "kill", 4); + int no_rebind = 0; + + local = strchr(service, ':') + 1; + + // Handle forward:norebind:<local>... here + if (createForward && !strncmp(local, "norebind:", 9)) { + no_rebind = 1; + local = strchr(local, ':') + 1; + } + + remote = strchr(local,';'); + + if (createForward) { + // Check forward: parameter format: '<local>;<remote>' + if(remote == 0) { + sendfailmsg(reply_fd, "malformed forward spec"); + return 1; + } + + *remote++ = 0; + if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) { + sendfailmsg(reply_fd, "malformed forward spec"); + return 1; + } + } else { + // Check killforward: parameter format: '<local>' + if (local[0] == 0) { + sendfailmsg(reply_fd, "malformed forward spec"); + return 1; + } + } + + transport = acquire_one_transport(CS_ANY, ttype, serial, &err); + if (!transport) { + sendfailmsg(reply_fd, err); + return 1; + } + + if (createForward) { + r = install_listener(local, remote, transport, no_rebind); + } else { + r = remove_listener(local, transport); + } + if(r == 0) { +#if ADB_HOST + /* On the host: 1st OKAY is connect, 2nd OKAY is status */ + writex(reply_fd, "OKAY", 4); +#endif + writex(reply_fd, "OKAY", 4); + return 1; + } + + if (createForward) { + const char* message; + switch (r) { + case INSTALL_STATUS_CANNOT_BIND: + message = "cannot bind to socket"; + break; + case INSTALL_STATUS_CANNOT_REBIND: + message = "cannot rebind existing socket"; + break; + default: + message = "internal error"; + } + sendfailmsg(reply_fd, message); + } else { + sendfailmsg(reply_fd, "cannot remove listener"); + } + return 1; + } + return 0; +} + 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"); @@ -1467,13 +1600,11 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r char buffer[4096]; int use_long = !strcmp(service+7, "-l"); if (use_long || service[7] == 0) { - memset(buf, 0, sizeof(buf)); memset(buffer, 0, sizeof(buffer)); D("Getting device list \n"); list_transports(buffer, sizeof(buffer), use_long); - snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer); D("Wrote device list \n"); - writex(reply_fd, buf, strlen(buf)); + send_msg_with_okay(reply_fd, buffer, strlen(buffer)); return 0; } } @@ -1502,8 +1633,7 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r } } - snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer); - writex(reply_fd, buf, strlen(buf)); + send_msg_with_okay(reply_fd, buffer, strlen(buffer)); return 0; } @@ -1511,8 +1641,7 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r 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)); + send_msg_with_okay(reply_fd, version, strlen(version)); return 0; } @@ -1522,8 +1651,7 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r if (transport && transport->serial) { out = transport->serial; } - snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out); - writex(reply_fd, buf, strlen(buf)); + send_msg_with_okay(reply_fd, out, strlen(out)); return 0; } if(!strncmp(service,"get-devpath",strlen("get-devpath"))) { @@ -1532,8 +1660,7 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r if (transport && transport->devpath) { out = transport->devpath; } - snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out); - writex(reply_fd, buf, strlen(buf)); + send_msg_with_okay(reply_fd, out, strlen(out)); return 0; } // indicates a new emulator instance has started @@ -1545,106 +1672,14 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r } #endif // ADB_HOST - if(!strcmp(service,"list-forward")) { - // Create the list of forward redirections. - char header[9]; - int buffer_size = format_listeners(NULL, 0); - // Add one byte for the trailing zero. - char* buffer = malloc(buffer_size+1); - (void) format_listeners(buffer, buffer_size+1); - snprintf(header, sizeof header, "OKAY%04x", buffer_size); - writex(reply_fd, header, 8); - writex(reply_fd, buffer, buffer_size); - free(buffer); - return 0; - } - - if (!strcmp(service,"killforward-all")) { - remove_all_listeners(); - adb_write(reply_fd, "OKAYOKAY", 8); - return 0; - } - - if(!strncmp(service,"forward:",8) || - !strncmp(service,"killforward:",12)) { - char *local, *remote, *err; - int r; - atransport *transport; - - int createForward = strncmp(service,"kill",4); - int no_rebind = 0; - - local = strchr(service, ':') + 1; - - // Handle forward:norebind:<local>... here - if (createForward && !strncmp(local, "norebind:", 9)) { - no_rebind = 1; - local = strchr(local, ':') + 1; - } - - remote = strchr(local,';'); - - if (createForward) { - // Check forward: parameter format: '<local>;<remote>' - 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; - } - } else { - // Check killforward: parameter format: '<local>' - if (local[0] == 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, no_rebind); - } else { - r = remove_listener(local, transport); - } - if(r == 0) { - /* 1st OKAY is connect, 2nd OKAY is status */ - writex(reply_fd, "OKAYOKAY", 8); - return 0; - } - - if (createForward) { - const char* message; - switch (r) { - case INSTALL_STATUS_CANNOT_BIND: - message = "cannot bind to socket"; - break; - case INSTALL_STATUS_CANNOT_REBIND: - message = "cannot rebind existing socket"; - break; - default: - message = "internal error"; - } - sendfailmsg(reply_fd, message); - } else { - sendfailmsg(reply_fd, "cannot remove listener"); - } - return 0; - } + int ret = handle_forward_request(service, ttype, serial, reply_fd); + if (ret >= 0) + return ret - 1; 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)); + send_msg_with_okay(reply_fd, state, strlen(state)); return 0; } return -1; |