コード例 #1
0
ファイル: bw.c プロジェクト: pllopis/libxenvchan
/**
       Simple libvchan application, both client and server.
       One side does writing, the other side does reading.
*/
int main(int argc, char **argv)
{
       struct libvchan *ctrl = 0;
       int wr;
       if (argc < 6)
               usage(argv);
       if (!strcmp(argv[2], "read"))
               wr = 0;
       else if (!strcmp(argv[2], "write"))
               wr = 1;
       else
               usage(argv);

       blocksize = atoi(argv[5]);
       total_size = atoll(argv[6]);
       buf = (char*) malloc(blocksize);
       if (buf == NULL) {
            perror("malloc");
            exit(1);
       }

       printf("Running bandwidth test with domain %d on port %d, blocksize %d transfer_size %llu\n",
              atoi(argv[3]), atoi(argv[4]), blocksize, total_size);

       if (!strcmp(argv[1], "server")) {
               if (argc < 8)
                    usage(argv);
               ctrl = libvchan_server_init(atoi(argv[3]), atoi(argv[4]), atoi(argv[7]), atoi(argv[8]));
       } else if (!strcmp(argv[1], "client"))
               ctrl = libvchan_client_init(atoi(argv[3]), atoi(argv[4]));
       else
               usage(argv);
       if (!ctrl) {
               perror("libvchan_*_init");
               exit(1);
       }

       if (wr)
               writer(ctrl);
       else
               reader(ctrl);
       libvchan_close(ctrl);
       return 0;
}
コード例 #2
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;
}
コード例 #3
0
/* do the preparatory tasks, needed before entering the main event loop */
void init(int xid)
{
    char qrexec_error_log_name[256];
    int logfd;
    int i;
    pid_t pid;
    int startup_timeout = MAX_STARTUP_TIME_DEFAULT;
    const char *startup_timeout_str = NULL;

    if (xid <= 0) {
        fprintf(stderr, "domain id=0?\n");
        exit(1);
    }
    startup_timeout_str = getenv("QREXEC_STARTUP_TIMEOUT");
    if (startup_timeout_str) {
        startup_timeout = atoi(startup_timeout_str);
        if (startup_timeout <= 0)
            // invalid or negative number
            startup_timeout = MAX_STARTUP_TIME_DEFAULT;
    }
    signal(SIGUSR1, sigusr1_handler);
    signal(SIGCHLD, sigchld_parent_handler);
    switch (pid=fork()) {
    case -1:
        perror("fork");
        exit(1);
    case 0:
        break;
    default:
        if (getenv("QREXEC_STARTUP_NOWAIT"))
            exit(0);
        if (!opt_quiet)
            fprintf(stderr, "Waiting for VM's qrexec agent.");
        for (i=0;i<startup_timeout;i++) {
            sleep(1);
            if (!opt_quiet)
                fprintf(stderr, ".");
            if (i==startup_timeout-1) {
                break;
            }
        }
        fprintf(stderr, "Cannot connect to '%s' qrexec agent for %d seconds, giving up\n", remote_domain_name, startup_timeout);
        exit(3);
    }
    close(0);
    snprintf(qrexec_error_log_name, sizeof(qrexec_error_log_name),
         "/var/log/qubes/qrexec.%s.log", remote_domain_name);
    umask(0007);        // make the log readable by the "qubes" group
    logfd =
        open(qrexec_error_log_name, O_WRONLY | O_CREAT | O_TRUNC,
         0660);

    if (logfd < 0) {
        perror("open");
        exit(1);
    }

    dup2(logfd, 1);
    dup2(logfd, 2);

    chdir("/var/run/qubes");
    if (setsid() < 0) {
        perror("setsid()");
        exit(1);
    }

    vchan = libvchan_client_init(xid, VCHAN_BASE_PORT);
    if (!vchan) {
        perror("cannot connect to qrexec agent");
        exit(1);
    }
    if (handle_agent_hello(vchan, remote_domain_name) < 0) {
        exit(1);
    }

    if (setgid(getgid()) < 0) {
        perror("setgid()");
        exit(1);
    }
    if (setuid(getuid()) < 0) {
        perror("setuid()");
        exit(1);
    }

    /* initialize clients state arrays */
    for (i = 0; i < MAX_CLIENTS; i++) {
        clients[i].state = CLIENT_INVALID;
        policy_pending[i].pid = 0;
        used_vchan_ports[i] = VCHAN_PORT_UNUSED;
        vchan_port_notify_client[i] = VCHAN_PORT_UNUSED;
    }

    /* When running as root, make the socket accessible; perms on /var/run/qubes still apply */
    umask(0);
    qrexec_daemon_unix_socket_fd =
        create_qrexec_socket(xid, remote_domain_name);
    umask(0077);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGCHLD, sigchld_handler);
    signal(SIGUSR1, SIG_DFL);
    kill(getppid(), SIGUSR1);   // let the parent know we are ready
}