Пример #1
0
void handle_trigger_io()
{
    struct msg_header hdr;
    struct trigger_service_params params;
    int ret;
    int client_fd;

    client_fd = do_accept(trigger_fd);
    if (client_fd < 0)
        return;
    hdr.len = sizeof(params);
    ret = read(client_fd, &params, sizeof(params));
    if (ret == sizeof(params)) {
        hdr.type = MSG_TRIGGER_SERVICE;
        snprintf(params.request_id.ident, sizeof(params.request_id), "SOCKET%d", client_fd);
        if (libvchan_send(ctrl_vchan, &hdr, sizeof(hdr)) < 0)
            handle_vchan_error("write hdr");
        if (libvchan_send(ctrl_vchan, &params, sizeof(params)) < 0)
            handle_vchan_error("write params");
    }
    if (ret <= 0) {
        close(client_fd);
    }
    /* do not close client_fd - we'll need it to send the connection details
     * later (when dom0 accepts the request) */
}
Пример #2
0
void release_connection(int id) {
    struct msg_header hdr;
    struct exec_params params;

    hdr.type = MSG_CONNECTION_TERMINATED;
    hdr.len = sizeof(struct exec_params);
    params.connect_domain = connection_info[id].connect_domain;
    params.connect_port = connection_info[id].connect_port;
    if (libvchan_send(ctrl_vchan, &hdr, sizeof(hdr)) < 0)
        handle_vchan_error("send");
    if (libvchan_send(ctrl_vchan, &params, sizeof(params)) < 0)
        handle_vchan_error("send");
    connection_info[id].pid = 0;
}
Пример #3
0
static void send_exit_code(libvchan_t *vchan, int status)
{
    struct msg_header hdr;

    hdr.type = MSG_DATA_EXIT_CODE;
    hdr.len = sizeof(int);
    if (libvchan_send(vchan, &hdr, sizeof(hdr)) != sizeof(hdr)) {
        fprintf(stderr, "Failed to write exit code to the agent\n");
        do_exit(1);
    }
    if (libvchan_send(vchan, &status, sizeof(status)) != sizeof(status)) {
        fprintf(stderr, "Failed to write exit code(2) to the agent\n");
        do_exit(1);
    }
}
Пример #4
0
static void rec_packet(libvchan_t * con) {
    char done = 1;
    int data[4];
		struct camera_data ca;

    libvchan_wait(con);
    int readSize = libvchan_recv(con, data, 4*sizeof(int));
    assert(readSize == 4*sizeof(int));
    DVM("received bounding box packet\n");

    //here are your corners Lee!
    ca.bbox_l = data[0];
    ca.bbox_r = data[1];
    ca.bbox_t = data[2];
    ca.bbox_b = data[3];

    /* int xmid = ((r + l) / 2) - 160; */
    /* int ymid = ((b + t) / 2) - 100; */

    /* ymid = -1.0*ymid; //sign change (based on how the camera is oriented) */

    /* //here are your angles Lee! */
    /* ca.angle_x = ((float) xmid)*(0.00410666); */
    /* ca.angle_y = ((float) ymid)*(0.00410666); */

    if (camera_vm_Output_from_vm_0_write_camera_data(&ca)) {
	DVM("wrote bounding box\n");
    } else {
	DVM("failed to write bouding box\n");
    }

    DVM("camera_vm: sending ack\n");
    libvchan_send(con, &done, sizeof(char));
}
Пример #5
0
static void handle_input(libvchan_t *vchan)
{
    char buf[MAX_DATA_CHUNK];
    int ret;
    size_t max_len;
    struct msg_header hdr;

    max_len = libvchan_buffer_space(vchan)-sizeof(hdr);
    if (max_len > sizeof(buf))
        max_len = sizeof(buf);
    if (max_len == 0)
        return;
    ret = read(local_stdout_fd, buf, max_len);
    if (ret < 0) {
        perror("read");
        do_exit(1);
    }
    hdr.type = is_service ? MSG_DATA_STDOUT : MSG_DATA_STDIN;
    hdr.len = ret;
    if (libvchan_send(vchan, &hdr, sizeof(hdr)) != sizeof(hdr)) {
        fprintf(stderr, "Failed to write STDIN data to the agent\n");
        do_exit(1);
    }
    if (ret == 0) {
        close(local_stdout_fd);
        local_stdout_fd = -1;
        if (local_stdin_fd == -1) {
            // if not a remote end of service call, wait for exit status
            if (is_service) {
                // if pipe in opposite direction already closed, no need to stay alive
                if (local_pid == 0) {
                    /* if this is "remote" service end and no real local process
                     * exists (using own stdin/out) send also fake exit code */
                    send_exit_code(vchan, 0);
                    do_exit(0);
                }
            }
        }
    }
    if (!write_vchan_all(vchan, buf, ret)) {
        if (!libvchan_is_open(vchan)) {
            // agent disconnected its end of socket, so no future data will be
            // send there; there is no sense to read from child stdout
            //
            // since vchan socket is buffered it doesn't mean all data was
            // received from the agent
            close(local_stdout_fd);
            local_stdout_fd = -1;
            if (local_stdin_fd == -1) {
                // since child does no longer accept data on its stdin, doesn't
                // make sense to process the data from the daemon
                //
                // we don't know real exit VM process code (exiting here, before
                // MSG_DATA_EXIT_CODE message)
                do_exit(1);
            }
        } else
            perror("write agent");
    }
}
static void send_service_refused(libvchan_t *vchan, struct service_params *params) {
    struct msg_header hdr;

    hdr.type = MSG_SERVICE_REFUSED;
    hdr.len = sizeof(*params);

    if (libvchan_send(vchan, &hdr, sizeof(hdr)) != sizeof(hdr)) {
        fprintf(stderr, "Failed to send MSG_SERVICE_REFUSED hdr to agent\n");
        exit(1);
    }

    if (libvchan_send(vchan, params, sizeof(*params)) != sizeof(*params)) {
        fprintf(stderr, "Failed to send MSG_SERVICE_REFUSED to agent\n");
        exit(1);
    }
}
int handle_agent_hello(libvchan_t *ctrl, const char *domain_name)
{
    struct msg_header hdr;
    struct peer_info info;

    if (libvchan_recv(ctrl, &hdr, sizeof(hdr)) != sizeof(hdr)) {
        fprintf(stderr, "Failed to read agent HELLO hdr\n");
        return -1;
    }

    if (hdr.type != MSG_HELLO || hdr.len != sizeof(info)) {
        fprintf(stderr, "Invalid HELLO packet received: type %d, len %d\n", hdr.type, hdr.len);
        return -1;
    }

    if (libvchan_recv(ctrl, &info, sizeof(info)) != sizeof(info)) {
        fprintf(stderr, "Failed to read agent HELLO body\n");
        return -1;
    }

    if (info.version != QREXEC_PROTOCOL_VERSION) {
        fprintf(stderr, "Incompatible agent protocol version (remote %d, local %d)\n", info.version, QREXEC_PROTOCOL_VERSION);
        incompatible_protocol_error_message(domain_name, info.version);
        return -1;
    }

    /* send own HELLO */
    /* those messages are the same as received from agent, but set it again for
     * readability */
    hdr.type = MSG_HELLO;
    hdr.len = sizeof(info);
    info.version = QREXEC_PROTOCOL_VERSION;

    if (libvchan_send(ctrl, &hdr, sizeof(hdr)) != sizeof(hdr)) {
        fprintf(stderr, "Failed to send HELLO hdr to agent\n");
        return -1;
    }

    if (libvchan_send(ctrl, &info, sizeof(info)) != sizeof(info)) {
        fprintf(stderr, "Failed to send HELLO hdr to agent\n");
        return -1;
    }

    return 0;
}
static int source_process_msg(pa_msgobject * o, int code, void *data,
                              int64_t offset, pa_memchunk * chunk)
{
    int r;
    struct userdata *u = PA_SOURCE(o)->userdata;
    int state;
    switch (code) {
    case PA_SOURCE_MESSAGE_SET_STATE:
        state = PA_PTR_TO_UINT(data);
        r = pa_source_process_msg(o, code, data, offset, chunk);
        if (r >= 0) {
            pa_log("source cork req state =%d, now state=%d\n", state,
                   (int) (u->source->state));
            uint32_t cmd = 0;
            if (u->source->state != PA_SOURCE_RUNNING && state == PA_SOURCE_RUNNING)
                cmd = QUBES_PA_SOURCE_START_CMD;
            else if (u->source->state == PA_SOURCE_RUNNING && state != PA_SOURCE_RUNNING)
                cmd = QUBES_PA_SOURCE_STOP_CMD;
            if (cmd != 0) {
                if (libvchan_send(u->rec_ctrl, (char*)&cmd, sizeof(cmd)) < 0) {
                    pa_log("vchan: failed to send record cmd");
                    /* This is a problem in case of enabling recording, in case
                     * of QUBES_PA_SOURCE_STOP_CMD it can happen that remote end
                     * is already disconnected, so indeed will not send further data.
                     * This can happen for example when we terminate the
                     * process because of pacat in dom0 has disconnected.
                     */
                    if (state == PA_SOURCE_RUNNING)
                        return -1;
                    else
                        return r;
                }
            }
        }
        return r;

    case PA_SOURCE_MESSAGE_GET_LATENCY: {
        size_t n = 0;
        n += u->memchunk_source.length;

        *((pa_usec_t *) data) =
            pa_bytes_to_usec(n, &u->source->sample_spec);
        return 0;
    }
    }

    return pa_source_process_msg(o, code, data, offset, chunk);
}
static int handle_cmdline_body_from_client(int fd, struct msg_header *hdr)
{
    struct exec_params params;
    int len = hdr->len-sizeof(params);
    char buf[len];
    int use_default_user = 0;
    int i;

    if (!read_all(fd, &params, sizeof(params))) {
        terminate_client(fd);
        return 0;
    }
    if (!read_all(fd, buf, len)) {
        terminate_client(fd);
        return 0;
    }

    if (hdr->type == MSG_SERVICE_CONNECT) {
        /* if the service was accepted, do not send spurious
         * MSG_SERVICE_REFUSED when service process itself exit with non-zero
         * code */
        for (i = 0; i <= policy_pending_max; i++) {
            if (policy_pending[i].pid &&
                    strncmp(policy_pending[i].params.ident, buf, len) == 0) {
                policy_pending[i].pid = 0;
                while (policy_pending_max > 0 &&
                        policy_pending[policy_pending_max].pid == 0)
                    policy_pending_max--;
                break;
            }
        }
    }

    if (!params.connect_port) {
        struct exec_params client_params;
        /* allocate port and send it to the client */
        params.connect_port = allocate_vchan_port(params.connect_domain);
        if (params.connect_port <= 0) {
            fprintf(stderr, "Failed to allocate new vchan port, too many clients?\n");
            terminate_client(fd);
            return 0;
        }
        /* notify the client when this connection got terminated */
        vchan_port_notify_client[params.connect_port-VCHAN_BASE_DATA_PORT] = fd;
        client_params.connect_port = params.connect_port;
        client_params.connect_domain = remote_domain_id;
        hdr->len = sizeof(client_params);
        if (!write_all(fd, hdr, sizeof(*hdr))) {
            terminate_client(fd);
            release_vchan_port(params.connect_port, params.connect_domain);
            return 0;
        }
        if (!write_all(fd, &client_params, sizeof(client_params))) {
            terminate_client(fd);
            release_vchan_port(params.connect_port, params.connect_domain);
            return 0;
        }
        /* restore original len value */
        hdr->len = len+sizeof(params);
    } else {
        assert(params.connect_port >= VCHAN_BASE_DATA_PORT);
        assert(params.connect_port < VCHAN_BASE_DATA_PORT+MAX_CLIENTS);
    }

    if (!strncmp(buf, default_user_keyword, default_user_keyword_len_without_colon+1)) {
        use_default_user = 1;
        hdr->len -= default_user_keyword_len_without_colon;
        hdr->len += strlen(default_user);
    }
    if (libvchan_send(vchan, hdr, sizeof(*hdr)) < 0)
        handle_vchan_error("send");
    if (libvchan_send(vchan, &params, sizeof(params)) < 0)
        handle_vchan_error("send params");
    if (use_default_user) {
        if (libvchan_send(vchan, default_user, strlen(default_user)) < 0)
            handle_vchan_error("send default_user");
        if (libvchan_send(vchan, buf+default_user_keyword_len_without_colon,
                    len-default_user_keyword_len_without_colon) < 0)
            handle_vchan_error("send buf");
    } else
        if (libvchan_send(vchan, buf, len) < 0)
            handle_vchan_error("send buf");
    return 1;
}