Beispiel #1
0
int32_t
qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c,
			 struct qb_ipc_connection_response *r)
{
	int32_t res;
	struct qb_ipc_connection_request request;
	struct ipc_auth_data *data;
#ifdef QB_LINUX
	int off = 0;
	int on = 1;
#endif

	res = qb_ipcc_stream_sock_connect(c->name, &c->setup.u.us.sock);
	if (res != 0) {
		return res;
	}
#ifdef QB_LINUX
	setsockopt(c->setup.u.us.sock, SOL_SOCKET, SO_PASSCRED, &on,
		   sizeof(on));
#endif

	memset(&request, 0, sizeof(request));
	request.hdr.id = QB_IPC_MSG_AUTHENTICATE;
	request.hdr.size = sizeof(request);
	request.max_msg_size = c->setup.max_msg_size;
	res = qb_ipc_us_send(&c->setup, &request, request.hdr.size);
	if (res < 0) {
		qb_ipcc_us_sock_close(c->setup.u.us.sock);
		return res;
	}

	data = init_ipc_auth_data(c->setup.u.us.sock, sizeof(struct qb_ipc_connection_response));
	if (data == NULL) {
		qb_ipcc_us_sock_close(c->setup.u.us.sock);
		return -ENOMEM;
	}

	qb_ipc_us_ready(&c->setup, NULL, -1, POLLIN);
	res = qb_ipc_us_recv_msghdr(data);

#ifdef QB_LINUX
	setsockopt(c->setup.u.us.sock, SOL_SOCKET, SO_PASSCRED, &off,
		   sizeof(off));
#endif

	if (res != data->len) {
		destroy_ipc_auth_data(data);
		return res;
	}

	memcpy(r, &data->msg.res, sizeof(struct qb_ipc_connection_response));

	qb_ipc_auth_creds(data);
	c->egid = data->ugp.gid;
	c->server_pid = data->ugp.pid;

	destroy_ipc_auth_data(data);
	return r->hdr.error;
}
Beispiel #2
0
static int32_t
process_auth(int32_t fd, int32_t revents, void *d)
{
	struct ipc_auth_data *data = (struct ipc_auth_data *) d;

	int32_t res = 0;
#ifdef SO_PASSCRED
	int off = 0;
#endif

	if (data->s->server_sock == -1) {
		qb_util_log(LOG_DEBUG, "Closing fd (%d) for server shutdown", fd);
		res = -ESHUTDOWN;
		goto cleanup_and_return;
	}

	if (revents & POLLNVAL) {
		qb_util_log(LOG_DEBUG, "NVAL conn fd (%d)", fd);
		res = -EINVAL;
		goto cleanup_and_return;
	}
	if (revents & POLLHUP) {
		qb_util_log(LOG_DEBUG, "HUP conn fd (%d)", fd);
		res = -ESHUTDOWN;
		goto cleanup_and_return;
	}
	if ((revents & POLLIN) == 0) {
		return 0;
	}

	res = qb_ipc_us_recv_msghdr(data);
	if (res == -EAGAIN) {
		/* yield to mainloop, Let mainloop call us again */
		return 0;
	}

	if (res != data->len) {
		res = -EIO;
		goto cleanup_and_return;
	}

	res = qb_ipc_auth_creds(data);

cleanup_and_return:
#ifdef SO_PASSCRED
	setsockopt(data->sock, SOL_SOCKET, SO_PASSCRED, &off, sizeof(off));
#endif

	(void)data->s->poll_fns.dispatch_del(data->sock);

	if (res < 0) {
		close(data->sock);
	} else if (data->msg.req.hdr.id == QB_IPC_MSG_AUTHENTICATE) {
		(void)handle_new_connection(data->s, res, data->sock, &data->msg, data->len, &data->ugp);
	} else {
		close(data->sock);
	}
	destroy_ipc_auth_data(data);

	return 1;
}