Пример #1
0
/*! \brief Event loop listening for signals and remote commands. */
static void event_loop(server_t *server)
{
	uint8_t buf[KNOT_WIRE_MAX_PKTSIZE];
	size_t buflen = sizeof(buf);

	/* Read control socket configuration. */
	conf_val_t listen_val = conf_get(conf(), C_CTL, C_LISTEN);
	conf_val_t rundir_val = conf_get(conf(), C_SRV, C_RUNDIR);
	char *rundir = conf_abs_path(&rundir_val, NULL);
	struct sockaddr_storage addr = conf_addr(&listen_val, rundir);
	free(rundir);

	/* Bind to control interface (error logging is inside the function. */
	int remote = remote_bind(&addr);

	sigset_t empty;
	(void)sigemptyset(&empty);

	/* Run event loop. */
	for (;;) {
		int ret = remote_poll(remote, &empty);

		/* Events. */
		if (ret > 0) {
			ret = remote_process(server, &addr, remote, buf, buflen);
			if (ret == KNOT_CTL_STOP) {
				break;
			}
		}

		/* Interrupts. */
		if (sig_req_stop) {
			break;
		}
		if (sig_req_reload) {
			sig_req_reload = false;
			server_reload(server, conf()->filename);
		}
	}

	server_stop(server);

	/* Close remote control interface. */
	remote_unbind(&addr, remote);

	/* Wait for server to finish. */
	server_wait(server);
}
Пример #2
0
gboolean remote_recv(GIOChannel * source, GIOCondition condition, gpointer data)
{
	if ((condition & G_IO_ERR) || (condition & G_IO_HUP))
	{
		remote_destroy();
		return FALSE;
	}

	if (condition & G_IO_IN)
	{
		char buf[512];
		int len;

		struct msghdr msg;
		struct cmsghdr *cmsg = NULL;
		struct ucred *pcred;
		struct iovec iov[1];
		char mbuf[CMSG_SPACE(sizeof (struct ucred))];

		memset(&msg, 0, sizeof msg);
		memset(mbuf, 0, sizeof mbuf);

		msg.msg_name = &csun;
		msg.msg_namelen = sizeof csun;

		iov[0].iov_base = buf;
		iov[0].iov_len = 512;

		msg.msg_iov = iov;
		msg.msg_iovlen = 1;

		msg.msg_control = mbuf;
		msg.msg_controllen = sizeof mbuf;

		if ((len = recvmsg(sck, &msg, 0)) == -1)
		{
			print_debug("%s: recvmsg: %s\n", GGadu_PLUGIN_NAME, strerror(errno));
			return TRUE;
		}

		/* szukamy w danych dodatkowych przes³anych uwierzytelnieñ */
		for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg))
		{
			if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS)
			{
				pcred = (struct ucred *) CMSG_DATA(cmsg);
				break;
			}
		}

		if (cmsg == NULL)
		{
			/* nie znale¼li¶my ¿adnych uwierzytelnieñ, wiêc ignorujemy pakiet */
			print_debug("%s: no credentials, discarding\n", GGadu_PLUGIN_NAME);
			return TRUE;
		}

		/* sprawdzanie uwierzytelnieñ
		 * w zale¿no¶ci od opcji sprawdzane jest:
		 *  - uid
		 *  - gid
		 */

		print_debug("%s: pid=%d, uid=%d, gid=%d\n", GGadu_PLUGIN_NAME, pcred->pid, pcred->uid, pcred->gid);

		if (var_same_uid && pcred->uid != getuid())
		{
			print_debug("%s: z³y uid (%d != %d)\n", GGadu_PLUGIN_NAME, pcred->uid, getuid());
			return TRUE;
		}
		if (var_same_gid && pcred->gid != getgid())
		{
			print_debug("%s: z³y gid (%d != %d)\n", GGadu_PLUGIN_NAME, pcred->gid, getgid());
			return TRUE;
		}

		/* sprawdzenie poprawno¶ci danych */
		if (len == 0)	/* nie mo¿e byæ */
		{
			print_debug("%s: recvmsg() = 0, a nie powinno\n", GGadu_PLUGIN_NAME);
			return TRUE;
		}

		if (buf[len - 1] != '\0')
		{
			print_debug("%s: b³êdny pakiet\n", GGadu_PLUGIN_NAME);
			return TRUE;
		}

/*
	csun = msg.msg_name;
*/
		csunlen = msg.msg_namelen;

		/* przes³anie danych do przetworzenia */
		remote_process(buf);

	}

	return TRUE;
}