int main(int argc, char **argv) { int trigger_fd; struct trigger_connect_params params; int local_fd[3], remote_fd[3]; int i; char *abs_exec_path; if (argc < 4) { fprintf(stderr, "usage: %s target_vmname program_ident local_program [local program arguments]\n", argv[0]); exit(1); } trigger_fd = open(QREXEC_AGENT_TRIGGER_PATH, O_WRONLY); if (trigger_fd < 0) { perror("open QREXEC_AGENT_TRIGGER_PATH"); exit(1); } for (i = 0; i < 3; i++) { local_fd[i] = connect_unix_socket(); read(local_fd[i], &remote_fd[i], sizeof(remote_fd[i])); if (i != 2 || getenv("PASS_LOCAL_STDERR")) { char *env; asprintf(&env, "SAVED_FD_%d=%d", i, dup(i)); putenv(env); dup2(local_fd[i], i); close(local_fd[i]); } } memset(¶ms, 0, sizeof(params)); strncpy(params.exec_index, argv[2], sizeof(params.exec_index)); strncpy(params.target_vmname, argv[1], sizeof(params.target_vmname)); snprintf(params.process_fds.ident, sizeof(params.process_fds.ident), "%d %d %d", remote_fd[0], remote_fd[1], remote_fd[2]); write(trigger_fd, ¶ms, sizeof(params)); close(trigger_fd); abs_exec_path = strdup(argv[3]); argv[3] = get_program_name(argv[3]); execv(abs_exec_path, argv + 3); perror("execv"); return 1; }
int main(int argc, char **argv) { int opt; char *domname = NULL; int s; int just_exec = 0; int connect_existing = 0; char *local_cmdline = NULL; while ((opt = getopt(argc, argv, "d:l:ec")) != -1) { switch (opt) { case 'd': domname = strdup(optarg); break; case 'l': local_cmdline = strdup(optarg); break; case 'e': just_exec = 1; break; case 'c': connect_existing = 1; break; default: usage(argv[0]); } } if (optind >= argc || !domname) usage(argv[0]); s = connect_unix_socket(domname); setenv("QREXEC_REMOTE_DOMAIN", domname, 1); prepare_local_fds(local_cmdline); if (just_exec) send_cmdline(s, MSG_CLIENT_TO_SERVER_JUST_EXEC, argv[optind]); else { int cmd; if (connect_existing) cmd = MSG_CLIENT_TO_SERVER_CONNECT_EXISTING; else cmd = MSG_CLIENT_TO_SERVER_EXEC_CMDLINE; send_cmdline(s, cmd, argv[optind]); select_loop(s); } return 0; }
/* test program for minissdpd */ int main(int argc, char * * argv) { const char command0[] = { 0x00, 0x00 }; char command1[] = "\x01\x00urn:schemas-upnp-org:device:InternetGatewayDevice"; char command2[] = "\x02\x00uuid:fc4ec57e-b051-11db-88f8-0060085db3f6::upnp:rootdevice"; const char command3[] = { 0x03, 0x00 }; /* old versions of minissdpd would reject a command with * a zero length string argument */ char command3compat[] = "\x03\x00ssdp:all"; char command4[] = "\x04\x00test:test:test"; const char bad_command[] = { 0xff, 0xff }; const char overflow[] = { 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; const char command5[] = { 0x05, 0x00 }; const char bad_command4[] = { 0x04, 0x01, 0x60, 0x8f, 0xff, 0xff, 0xff, 0x7f}; int s; int i; void * tmp; unsigned char * resp = NULL; size_t respsize = 0; unsigned char buf[4096]; ssize_t n; int total = 0; const char * sockpath = "/var/run/minissdpd.sock"; for(i=0; i<argc-1; i++) { if(0==strcmp(argv[i], "-s")) sockpath = argv[++i]; } command1[1] = sizeof(command1) - 3; command2[1] = sizeof(command2) - 3; command3compat[1] = sizeof(command3compat) - 3; command4[1] = sizeof(command4) - 3; s = connect_unix_socket(sockpath); n = SENDCOMMAND(command0, sizeof(command0)); n = read(s, buf, sizeof(buf)); printf("Response received %d bytes\n", (int)n); if(n > 0) { printversion(buf, n); } else { printf("Command 0 (get version) not supported\n"); close(s); s = connect_unix_socket(sockpath); } n = SENDCOMMAND(command1, sizeof(command1) - 1); n = read(s, buf, sizeof(buf)); printf("Response received %d bytes\n", (int)n); printresponse(buf, n); if(n == 0) { close(s); s = connect_unix_socket(sockpath); } n = SENDCOMMAND(command2, sizeof(command2) - 1); n = read(s, buf, sizeof(buf)); printf("Response received %d bytes\n", (int)n); printresponse(buf, n); if(n == 0) { close(s); s = connect_unix_socket(sockpath); } buf[0] = 0; /* Slight hack for printing num devices when 0 */ n = SENDCOMMAND(command3, sizeof(command3)); n = read(s, buf, sizeof(buf)); if(n == 0) { printf("command3 failed, testing compatible one\n"); close(s); s = connect_unix_socket(sockpath); n = SENDCOMMAND(command3compat, sizeof(command3compat) - 1); n = read(s, buf, sizeof(buf)); } printf("Response received %d bytes\n", (int)n); printf("Number of devices %d\n", (int)buf[0]); while(n > 0) { tmp = realloc(resp, respsize + n); if(tmp == NULL) { fprintf(stderr, "memory allocation error\n"); break; } resp = tmp; respsize += n; if (n > 0) { memcpy(resp + total, buf, n); total += n; } if (n < (ssize_t)sizeof(buf)) { break; } n = read(s, buf, sizeof(buf)); printf("response received %d bytes\n", (int)n); } if(resp != NULL) { printresponse(resp, total); free(resp); resp = NULL; } if(n == 0) { close(s); s = connect_unix_socket(sockpath); } n = SENDCOMMAND(command4, sizeof(command4)); /* no response for request type 4 */ n = SENDCOMMAND(bad_command, sizeof(bad_command)); n = read(s, buf, sizeof(buf)); printf("Response received %d bytes\n", (int)n); printresponse(buf, n); if(n == 0) { close(s); s = connect_unix_socket(sockpath); } n = SENDCOMMAND(overflow, sizeof(overflow)); n = read(s, buf, sizeof(buf)); printf("Response received %d bytes\n", (int)n); printresponse(buf, n); if(n == 0) { close(s); s = connect_unix_socket(sockpath); } n = SENDCOMMAND(command5, sizeof(command5)); n = read(s, buf, sizeof(buf)); printf("Response received %d bytes\n", (int)n); printresponse(buf, n); if(n == 0) { close(s); s = connect_unix_socket(sockpath); } n = SENDCOMMAND(bad_command4, sizeof(bad_command4)); n = read(s, buf, sizeof(buf)); printf("Response received %d bytes\n", (int)n); printresponse(buf, n); close(s); return 0; }
int main(int argc, char **argv) { int opt; char *domname = NULL; libvchan_t *data_vchan = NULL; int data_port; int data_domain; int msg_type; int s; int just_exec = 0; int connect_existing = 0; char *local_cmdline = NULL; char *remote_cmdline = NULL; char *request_id; char *src_domain_name = NULL; int src_domain_id = 0; /* if not -c given, the process is run in dom0 */ struct service_params svc_params; while ((opt = getopt(argc, argv, "d:l:ec:tT")) != -1) { switch (opt) { case 'd': domname = strdup(optarg); break; case 'l': local_cmdline = strdup(optarg); break; case 'e': just_exec = 1; break; case 'c': parse_connect(optarg, &request_id, &src_domain_name, &src_domain_id); connect_existing = 1; is_service = 1; break; case 't': replace_esc_stdout = 1; break; case 'T': replace_esc_stderr = 1; break; default: usage(argv[0]); } } if (optind >= argc || !domname) usage(argv[0]); remote_cmdline = argv[optind]; register_exec_func(&do_exec); if (just_exec + connect_existing + (local_cmdline != 0) > 1) { fprintf(stderr, "ERROR: only one of -e, -l, -c can be specified\n"); usage(argv[0]); } if (strcmp(domname, "dom0") == 0 && !connect_existing) { fprintf(stderr, "ERROR: when target domain is 'dom0', -c must be specified\n"); usage(argv[0]); } if (strcmp(domname, "dom0") == 0) { if (connect_existing) { msg_type = MSG_SERVICE_CONNECT; strncpy(svc_params.ident, request_id, sizeof(svc_params.ident)); } else if (just_exec) msg_type = MSG_JUST_EXEC; else msg_type = MSG_EXEC_CMDLINE; assert(src_domain_name); setenv("QREXEC_REMOTE_DOMAIN", src_domain_name, 1); s = connect_unix_socket(src_domain_name); negotiate_connection_params(s, 0, /* dom0 */ msg_type, connect_existing ? (void*)&svc_params : (void*)remote_cmdline, connect_existing ? sizeof(svc_params) : strlen(remote_cmdline) + 1, &data_domain, &data_port); prepare_local_fds(remote_cmdline); if (connect_existing) data_vchan = libvchan_client_init(data_domain, data_port); else { data_vchan = libvchan_server_init(data_domain, data_port, VCHAN_BUFFER_SIZE, VCHAN_BUFFER_SIZE); while (data_vchan && libvchan_is_open(data_vchan) == VCHAN_WAITING) libvchan_wait(data_vchan); } if (!data_vchan || !libvchan_is_open(data_vchan)) { fprintf(stderr, "Failed to open data vchan connection\n"); do_exit(1); } if (handle_agent_handshake(data_vchan, connect_existing) < 0) do_exit(1); select_loop(data_vchan); } else { if (just_exec) msg_type = MSG_JUST_EXEC; else msg_type = MSG_EXEC_CMDLINE; s = connect_unix_socket(domname); negotiate_connection_params(s, src_domain_id, msg_type, remote_cmdline, strlen(remote_cmdline) + 1, &data_domain, &data_port); close(s); setenv("QREXEC_REMOTE_DOMAIN", domname, 1); prepare_local_fds(local_cmdline); if (connect_existing) { s = connect_unix_socket(src_domain_name); send_service_connect(s, request_id, data_domain, data_port); close(s); } else { data_vchan = libvchan_server_init(data_domain, data_port, VCHAN_BUFFER_SIZE, VCHAN_BUFFER_SIZE); if (!data_vchan) { fprintf(stderr, "Failed to start data vchan server\n"); do_exit(1); } while (libvchan_is_open(data_vchan) == VCHAN_WAITING) libvchan_wait(data_vchan); if (!libvchan_is_open(data_vchan)) { fprintf(stderr, "Failed to open data vchan connection\n"); do_exit(1); } if (handle_agent_handshake(data_vchan, 0) < 0) do_exit(1); select_loop(data_vchan); } } return 0; }