コード例 #1
0
ファイル: main.c プロジェクト: rindeal/umurmur
/* Drops privileges (if configured to do so). */
static void switch_user(void)
{
	struct passwd *pwd;
	struct group *grp = NULL;
	const char *username, *groupname;
	gid_t gid;

	username = getStrConf(USERNAME);
	groupname = getStrConf(GROUPNAME);

	if (!*username) {
		/* It's an error to specify groupname
		 * but leave username empty.
		 */
		if (*groupname)
			Log_fatal("username missing");

		/* Nothing to do. */
		return;
	}

	pwd = getpwnam(username);
	if (!pwd)
		Log_fatal("Unknown user '%s'", username);

	if (!*groupname)
		gid = pwd->pw_gid;
	else {
		grp = getgrnam(groupname);

		if (!grp)
			Log_fatal("Unknown group '%s'", groupname);

		gid = grp->gr_gid;
	}

	if (initgroups(pwd->pw_name, gid))
		Log_fatal("initgroups() failed: %s", strerror(errno));

	if (setgid(gid))
		Log_fatal("setgid() failed: %s", strerror(errno));

	if (setuid(pwd->pw_uid))
		Log_fatal("setuid() failed: %s", strerror(errno));

	if (!grp)
		grp = getgrgid(gid);
	if (!grp)
		Log_fatal("getgrgid() failed: %s", strerror(errno));

	Log_info("Switch to user '%s' group '%s'", pwd->pw_name, grp->gr_name);
}
コード例 #2
0
ファイル: log.c プロジェクト: ChlorideCull/RattleMurmur
void Log_reset()
{
	const char *logfilename;
	
	if (logfile) {
		logfilename = getStrConf(LOGFILE);
		fclose(logfile);
		openlogfile(logfilename);
	}
}
コード例 #3
0
ファイル: ssli_gnutls.c プロジェクト: Nauxuron/umurmur
void initializeCertificate()
{
	char* certificatePath = (char*) getStrConf(CERTIFICATE);

	if(!certificatePath) {
		Log_fatal("No certificate file specified.");
	}

	char* keyPath = (char*) getStrConf(KEY);

	if(!keyPath) {
		Log_fatal("No key file specified");
	}

	gnutls_certificate_allocate_credentials(&certificate);

	int error = gnutls_certificate_set_x509_key_file(certificate, certificatePath, keyPath, GNUTLS_X509_FMT_PEM);

	if( error != GNUTLS_E_SUCCESS ) {
		Log_fatal("Could not open key (%s) or certificate (%s).", keyPath, certificatePath);
	}
}
コード例 #4
0
ファイル: log.c プロジェクト: ChlorideCull/RattleMurmur
void Log_init(bool_t terminal)
{
	const char *logfilename;
	
	termprint = terminal;		
	if (termprint)
		return;
	
	logfilename = getStrConf(LOGFILE);
	if (logfilename != NULL) {
		openlogfile(logfilename);
	}
	else openlog("uMurmurd", LOG_PID, LOG_DAEMON);
	init = true;
}
コード例 #5
0
ファイル: server.c プロジェクト: QDeltaSoft/umurmur
void Server_run()
{
	int timeout = 1000, rc;
	struct pollfd *pollfds;
	int tcpsock, sockopt = 1;
	struct sockaddr_storage sin;
	int val, clientcount;
	etimer_t janitorTimer;
	const char *port;
	const char *addr;
	struct addrinfo hints, *res;
	bool_t enable_ipv6;

	/* max clients + listen sock + udp sock + client connecting that will be disconnected */
	pollfds = malloc((getIntConf(MAX_CLIENTS) + 3) * sizeof(struct pollfd));
	if (pollfds == NULL)
		Log_fatal("out of memory");

	/* Figure out bind address and port */
	if (bindport != 0)
		port = bindport;
	else
		port = getStrConf(BINDPORT);

	if (bindaddr != 0)
		addr = bindaddr;
	else
		addr = getStrConf(BINDADDR);
	
	/* Prepare TCP socket */

	enable_ipv6 = getBoolConf(ENABLE_IPV6);
	if (enable_ipv6) { /* Test if supported */
		int testsock = socket(AF_INET6, SOCK_STREAM, 0);
		if (testsock < 0 && errno == EAFNOSUPPORT) {
			Log_warn("IPv6 is not supported on this machine. Falling back to IPv4.");
			enable_ipv6 = false;
		}
		if (testsock > 0) close(testsock);
	}

	memset(&hints, 0, sizeof hints);
	if (enable_ipv6) {
		hints.ai_family = AF_INET6;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_flags = AI_PASSIVE | AI_V4MAPPED;
		hints.ai_protocol = 0;
	} else { /* IPv4 */
		hints.ai_family = AF_INET;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_flags = AI_PASSIVE;
		hints.ai_protocol = 0;
	}
	rc = getaddrinfo(addr, port, &hints, &res);
	if (rc != 0)
		Log_fatal("getaddrinfo: %s", gai_strerror(rc));

	Log_info("Bind to [%s]:%s", addr ? addr : "::" , port);

	tcpsock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	if (tcpsock < 0)
		Log_fatal("socket: %s", strerror(errno));
	if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(int)) != 0)
		Log_fatal("setsockopt: %s",strerror(errno));
	rc = bind(tcpsock, res->ai_addr, res->ai_addrlen);
	if (rc < 0)
		Log_fatal("bind: %s", strerror(errno));
	rc = listen(tcpsock, 3);
	if (rc < 0)
		Log_fatal("listen");
	fcntl(tcpsock, F_SETFL, O_NONBLOCK);

	pollfds[LISTEN_SOCK].fd = tcpsock;
	pollfds[LISTEN_SOCK].events = POLLIN;
	freeaddrinfo(res);

	/* Prepare UDP socket */

	memset(&hints, 0, sizeof hints);
	if (enable_ipv6) {
		hints.ai_family = AF_INET6;
		hints.ai_socktype = SOCK_DGRAM;
		hints.ai_flags = AI_PASSIVE | AI_V4MAPPED;
		hints.ai_protocol = 0;
	} else { /* IPv4 */
		hints.ai_family = AF_INET;
		hints.ai_socktype = SOCK_DGRAM;
		hints.ai_flags = AI_PASSIVE;
		hints.ai_protocol = 0;
	}
	rc = getaddrinfo(addr, port, &hints, &res);
	if (rc != 0) Log_fatal("getaddrinfo: %s", gai_strerror(rc));

	udpsock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	rc = bind(udpsock, res->ai_addr, res->ai_addrlen);
	if (rc < 0)
		Log_fatal("bind %d %s: %s", bindport, bindaddr, strerror(errno));
	val = 0xe0;
	rc = setsockopt(udpsock, IPPROTO_IP, IP_TOS, &val, sizeof(val));
	if (rc < 0)
		Log_warn("Server: Failed to set TOS for UDP Socket");
	val = 0x80;
	rc = setsockopt(udpsock, IPPROTO_IP, IP_TOS, &val, sizeof(val));
	if (rc < 0)
		Log_warn("Server: Failed to set TOS for UDP Socket");
	fcntl(udpsock, F_SETFL, O_NONBLOCK);
	listen(udpsock, 10);

	pollfds[UDP_SOCK].fd = udpsock;
	pollfds[UDP_SOCK].events = POLLIN | POLLHUP | POLLERR;
	freeaddrinfo(res);

	Timer_init(&janitorTimer);
	
	Log_info("uMurmur version %s ('%s') protocol version %d.%d.%d",
	         UMURMUR_VERSION, UMURMUR_CODENAME, PROTVER_MAJOR, PROTVER_MINOR, PROTVER_PATCH);
	Log_info("Visit http://code.google.com/p/umurmur/");
	
	/* Main server loop */
	while (!shutdown_server) {
		struct sockaddr_storage remote;
		int i;
		
		pollfds[UDP_SOCK].revents = 0;
		pollfds[TCP_SOCK].revents = 0;
		clientcount = Client_getfds(&pollfds[2]);
		
		timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL;
		if (timeout <= 0) {
			Client_janitor();
			Timer_restart(&janitorTimer);
			timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL;
		}
		rc = poll(pollfds, clientcount + 2, timeout);
		if (rc == 0) { /* Timeout */
			/* Do maintenance */
			Timer_restart(&janitorTimer);
			Client_janitor();
			continue;
		}
		if (rc < 0) {
			if (errno == EINTR) /* signal */
				continue;
			else
				Log_fatal("poll: error %d", errno);
		}
		if (pollfds[LISTEN_SOCK].revents) { /* New tcp connection */
			int tcpfd, flag = 1;
			uint32_t addrlen;
			addrlen = sizeof(struct sockaddr_storage);
			tcpfd = accept(pollfds[LISTEN_SOCK].fd, (struct sockaddr*)&remote, &addrlen);
			fcntl(tcpfd, F_SETFL, O_NONBLOCK);
			setsockopt(tcpfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
			Log_debug("Connection from %s port %d\n", inet_ntoa(remote.sin_addr),
					ntohs(remote.sin_port));
			if (Client_add(tcpfd, &remote) < 0)
				close(tcpfd);
		}

		if (pollfds[UDP_SOCK].revents) {
			Client_read_udp();
		}
		for (i = 0; i < clientcount; i++) {
			if (pollfds[i + 2].revents & POLLIN) {
				Client_read_fd(pollfds[i + 2].fd);
			}
			if (pollfds[i + 2].revents & POLLOUT) {
				Client_write_fd(pollfds[i + 2].fd);
			}
		}
	}

	/* Disconnect clients */
	Client_disconnect_all();
	free(pollfds);
}
コード例 #6
0
ファイル: server.c プロジェクト: neokril/umurmur
void Server_run()
{
	int timeout = 1000, rc;
	struct pollfd *pollfds;
	int tcpsock, sockopt = 1;
	struct sockaddr_in sin;
	int val, clientcount;
	etimer_t janitorTimer;
	unsigned short port;
	in_addr_t inet_address;

	/* max clients + listen sock + udp sock + client connecting that will be disconnected */
	pollfds = malloc((getIntConf(MAX_CLIENTS) + 3) * sizeof(struct pollfd));
	if (pollfds == NULL)
		Log_fatal("out of memory");

	/* Figure out bind address and port */
	if (bindport != 0)
		port = htons(bindport);
	else
		port = htons(getIntConf(BINDPORT));

	if (bindaddr != NULL && inet_addr(bindaddr) != -1)
		inet_address = inet_addr(bindaddr);
	else if (inet_addr(getStrConf(BINDADDR)) !=  -1)
		inet_address = inet_addr(getStrConf(BINDADDR));
	else
		inet_address = inet_addr("0.0.0.0");
	Log_info("Bind to %s:%hu", inet_address == 0 ? "*" : inet_ntoa(*((struct in_addr *)&inet_address)), ntohs(port));

	/* Prepare TCP socket */
	memset(&sin, 0, sizeof(sin));
	tcpsock = socket(PF_INET, SOCK_STREAM, 0);
	if (tcpsock < 0)
		Log_fatal("socket");
	if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(int)) != 0)
		Log_fatal("setsockopt: %s", strerror(errno));
	sin.sin_family = AF_INET;
	sin.sin_port = port;
	sin.sin_addr.s_addr = inet_address;

	rc = bind(tcpsock, (struct sockaddr *) &sin, sizeof (struct sockaddr_in));
	if (rc < 0) Log_fatal("bind: %s", strerror(errno));
	rc = listen(tcpsock, 3);
	if (rc < 0) Log_fatal("listen");
	fcntl(tcpsock, F_SETFL, O_NONBLOCK);

	pollfds[LISTEN_SOCK].fd = tcpsock;
	pollfds[LISTEN_SOCK].events = POLLIN;

	/* Prepare UDP socket */
	memset(&sin, 0, sizeof(sin));
	udpsock = socket(PF_INET, SOCK_DGRAM, 0);
	sin.sin_family = AF_INET;
	sin.sin_port = port;
	sin.sin_addr.s_addr = inet_address;

	rc = bind(udpsock, (struct sockaddr *) &sin, sizeof (struct sockaddr_in));
	if (rc < 0)
		Log_fatal("bind %d %s: %s", getIntConf(BINDPORT), getStrConf(BINDADDR), strerror(errno));
	val = 0xe0;
	rc = setsockopt(udpsock, IPPROTO_IP, IP_TOS, &val, sizeof(val));
	if (rc < 0)
		Log_warn("Server: Failed to set TOS for UDP Socket");
	val = 0x80;
	rc = setsockopt(udpsock, IPPROTO_IP, IP_TOS, &val, sizeof(val));
	if (rc < 0)
		Log_warn("Server: Failed to set TOS for UDP Socket");

	fcntl(udpsock, F_SETFL, O_NONBLOCK);
	pollfds[UDP_SOCK].fd = udpsock;
	pollfds[UDP_SOCK].events = POLLIN | POLLHUP | POLLERR;

	Timer_init(&janitorTimer);

	Log_info("uMurmur version %s ('%s') protocol version %d.%d.%d",
	         UMURMUR_VERSION, UMURMUR_CODENAME, PROTVER_MAJOR, PROTVER_MINOR, PROTVER_PATCH);
	Log_info("Visit http://code.google.com/p/umurmur/");

	/* Main server loop */
	while (!shutdown_server) {
		struct sockaddr_in remote;
		int i;

		pollfds[UDP_SOCK].revents = 0;
		pollfds[TCP_SOCK].revents = 0;
		clientcount = Client_getfds(&pollfds[2]);

		timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL;
		if (timeout <= 0) {
			Client_janitor();
			Timer_restart(&janitorTimer);
			timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL;
		}
		rc = poll(pollfds, clientcount + 2, timeout);
		if (rc == 0) { /* Timeout */
			/* Do maintenance */
			Timer_restart(&janitorTimer);
			Client_janitor();
			continue;
		}
		if (rc < 0) {
			if (errno == EINTR) /* signal */
				continue;
			else
				Log_fatal("poll: error %d", errno);
		}
		if (pollfds[LISTEN_SOCK].revents) { /* New tcp connection */
			int tcpfd, flag = 1;
			uint32_t addrlen;
			addrlen = sizeof(struct sockaddr_in);
			tcpfd = accept(pollfds[LISTEN_SOCK].fd, (struct sockaddr*)&remote, &addrlen);
			fcntl(tcpfd, F_SETFL, O_NONBLOCK);
			setsockopt(tcpfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
			Log_debug("Connection from %s port %d\n", inet_ntoa(remote.sin_addr),
					  ntohs(remote.sin_port));
			if (Client_add(tcpfd, &remote) < 0)
				close(tcpfd);
		}

		if (pollfds[UDP_SOCK].revents) {
			Client_read_udp();
		}
		for (i = 0; i < clientcount; i++) {
			if (pollfds[i + 2].revents & POLLIN) {
				Client_read_fd(pollfds[i + 2].fd);
			}
			if (pollfds[i + 2].revents & POLLOUT) {
				Client_write_fd(pollfds[i + 2].fd);
			}
		}
	}

	/* Disconnect clients */
	Client_disconnect_all();
	free(pollfds);
}