예제 #1
0
static int
tls_exec(int argc, char *argv[])
{

	PJDLOG_ASSERT(argc > 3);
	PJDLOG_ASSERT(strcmp(argv[0], "tls") == 0);

	pjdlog_init(atoi(argv[3]) == 0 ? PJDLOG_MODE_SYSLOG : PJDLOG_MODE_STD);

	if (strcmp(argv[2], "client") == 0) {
		if (argc != 10)
			return (EINVAL);
		tls_exec_client(argv[1], atoi(argv[3]),
		    argv[4][0] == '\0' ? NULL : argv[4], argv[5], argv[6],
		    argv[7], atoi(argv[8]), atoi(argv[9]));
	} else if (strcmp(argv[2], "server") == 0) {
		if (argc != 7)
			return (EINVAL);
		tls_exec_server(argv[1], atoi(argv[3]), argv[4], argv[5],
		    atoi(argv[6]));
	}
	return (EINVAL);
}
예제 #2
0
void
hastd_secondary(struct hast_resource *res, struct nv *nvin)
{
	sigset_t mask;
	pthread_t td;
	pid_t pid;
	int error, mode, debuglevel;

	/*
	 * Create communication channel between parent and child.
	 */
	if (proto_client(NULL, "socketpair://", &res->hr_ctrl) < 0) {
		KEEP_ERRNO((void)pidfile_remove(pfh));
		pjdlog_exit(EX_OSERR,
		    "Unable to create control sockets between parent and child");
	}
	/*
	 * Create communication channel between child and parent.
	 */
	if (proto_client(NULL, "socketpair://", &res->hr_event) < 0) {
		KEEP_ERRNO((void)pidfile_remove(pfh));
		pjdlog_exit(EX_OSERR,
		    "Unable to create event sockets between child and parent");
	}

	pid = fork();
	if (pid < 0) {
		KEEP_ERRNO((void)pidfile_remove(pfh));
		pjdlog_exit(EX_OSERR, "Unable to fork");
	}

	if (pid > 0) {
		/* This is parent. */
		proto_close(res->hr_remotein);
		res->hr_remotein = NULL;
		proto_close(res->hr_remoteout);
		res->hr_remoteout = NULL;
		/* Declare that we are receiver. */
		proto_recv(res->hr_event, NULL, 0);
		/* Declare that we are sender. */
		proto_send(res->hr_ctrl, NULL, 0);
		res->hr_workerpid = pid;
		return;
	}

	gres = res;
	mode = pjdlog_mode_get();
	debuglevel = pjdlog_debug_get();

	/* Declare that we are sender. */
	proto_send(res->hr_event, NULL, 0);
	/* Declare that we are receiver. */
	proto_recv(res->hr_ctrl, NULL, 0);
	descriptors_cleanup(res);

	descriptors_assert(res, mode);

	pjdlog_init(mode);
	pjdlog_debug_set(debuglevel);
	pjdlog_prefix_set("[%s] (%s) ", res->hr_name, role2str(res->hr_role));
	setproctitle("%s (%s)", res->hr_name, role2str(res->hr_role));

	PJDLOG_VERIFY(sigemptyset(&mask) == 0);
	PJDLOG_VERIFY(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);

	/* Error in setting timeout is not critical, but why should it fail? */
	if (proto_timeout(res->hr_remotein, 2 * HAST_KEEPALIVE) < 0)
		pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
	if (proto_timeout(res->hr_remoteout, res->hr_timeout) < 0)
		pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");

	init_local(res);
	init_environment();

	if (drop_privs(res) != 0)
		exit(EX_CONFIG);
	pjdlog_info("Privileges successfully dropped.");

	/*
	 * Create the control thread before sending any event to the parent,
	 * as we can deadlock when parent sends control request to worker,
	 * but worker has no control thread started yet, so parent waits.
	 * In the meantime worker sends an event to the parent, but parent
	 * is unable to handle the event, because it waits for control
	 * request response.
	 */
	error = pthread_create(&td, NULL, ctrl_thread, res);
	PJDLOG_ASSERT(error == 0);

	init_remote(res, nvin);
	event_send(res, EVENT_CONNECT);

	error = pthread_create(&td, NULL, recv_thread, res);
	PJDLOG_ASSERT(error == 0);
	error = pthread_create(&td, NULL, disk_thread, res);
	PJDLOG_ASSERT(error == 0);
	(void)send_thread(res);
}
예제 #3
0
int
service_start(const char *name, int sock, service_limit_func_t *limitfunc,
    service_command_func_t *commandfunc, int argc, char *argv[])
{
	struct service *service;
	struct service_connection *sconn, *sconntmp;
	fd_set fds;
	int maxfd, nfds, serrno;

	assert(argc == 2);

	pjdlog_init(PJDLOG_MODE_STD);
	pjdlog_debug_set(atoi(argv[1]));

	service = service_alloc(name, limitfunc, commandfunc);
	if (service == NULL)
		return (errno);
	if (service_connection_add(service, sock, NULL) == NULL) {
		serrno = errno;
		service_free(service);
		return (serrno);
	}

	for (;;) {
		FD_ZERO(&fds);
		maxfd = -1;
		for (sconn = service_connection_first(service); sconn != NULL;
		    sconn = service_connection_next(sconn)) {
			maxfd = fd_add(&fds, maxfd,
			    service_connection_get_sock(sconn));
		}

		PJDLOG_ASSERT(maxfd >= 0);
		PJDLOG_ASSERT(maxfd + 1 <= (int)FD_SETSIZE);
		nfds = select(maxfd + 1, &fds, NULL, NULL, NULL);
		if (nfds < 0) {
			if (errno != EINTR)
				pjdlog_errno(LOG_ERR, "select() failed");
			continue;
		} else if (nfds == 0) {
			/* Timeout. */
			PJDLOG_ABORT("select() timeout");
			continue;
		}

		for (sconn = service_connection_first(service); sconn != NULL;
		    sconn = sconntmp) {
			/*
			 * Prepare for connection to be removed from the list
			 * on failure.
			 */
			sconntmp = service_connection_next(sconn);
			if (FD_ISSET(service_connection_get_sock(sconn), &fds))
				service_message(service, sconn);
		}
		if (service_connection_first(service) == NULL) {
			/*
			 * No connections left, exiting.
			 */
			break;
		}
	}

	return (0);
}
예제 #4
0
int
main(int argc, char **argv)
{
	char core[PATH_MAX], encryptedcore[PATH_MAX], keyfile[PATH_MAX];
	struct stat sb;
	const char *crashdir, *dumpnr, *privatekey;
	int ch, debug;
	size_t ii;
	bool usesyslog;

	pjdlog_init(PJDLOG_MODE_STD);
	pjdlog_prefix_set("(decryptcore) ");

	debug = 0;
	*core = '\0';
	crashdir = NULL;
	dumpnr = NULL;
	*encryptedcore = '\0';
	*keyfile = '\0';
	privatekey = NULL;
	usesyslog = false;
	while ((ch = getopt(argc, argv, "Lc:d:e:k:n:p:v")) != -1) {
		switch (ch) {
		case 'L':
			usesyslog = true;
			break;
		case 'c':
			strncpy(core, optarg, sizeof(core));
			break;
		case 'd':
			crashdir = optarg;
			break;
		case 'e':
			strncpy(encryptedcore, optarg, sizeof(encryptedcore));
			break;
		case 'k':
			strncpy(keyfile, optarg, sizeof(keyfile));
			break;
		case 'n':
			dumpnr = optarg;
			break;
		case 'p':
			privatekey = optarg;
			break;
		case 'v':
			debug++;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc != 0)
		usage();

	/* Verify mutually exclusive options. */
	if ((crashdir != NULL || dumpnr != NULL) &&
	    (*keyfile != '\0' || *encryptedcore != '\0' || *core != '\0')) {
		usage();
	}

	/*
	 * Set key, encryptedcore and core file names using crashdir and dumpnr.
	 */
	if (dumpnr != NULL) {
		for (ii = 0; ii < strnlen(dumpnr, PATH_MAX); ii++) {
			if (isdigit((int)dumpnr[ii]) == 0)
				usage();
		}

		if (crashdir == NULL)
			crashdir = DECRYPTCORE_CRASHDIR;
		PJDLOG_VERIFY(snprintf(keyfile, sizeof(keyfile),
		    "%s/key.%s", crashdir, dumpnr) > 0);
		PJDLOG_VERIFY(snprintf(core, sizeof(core),
		    "%s/vmcore.%s", crashdir, dumpnr) > 0);
		PJDLOG_VERIFY(snprintf(encryptedcore, sizeof(encryptedcore),
		    "%s/vmcore_encrypted.%s", crashdir, dumpnr) > 0);
	}

	if (privatekey == NULL || *keyfile == '\0' || *encryptedcore == '\0' ||
	    *core == '\0') {
		usage();
	}

	if (usesyslog)
		pjdlog_mode_set(PJDLOG_MODE_SYSLOG);
	pjdlog_debug_set(debug);

	if (!decrypt(privatekey, keyfile, encryptedcore, core)) {
		if (stat(core, &sb) == 0 && unlink(core) != 0)
			pjdlog_exit(1, "Unable to remove core");
		exit(1);
	}

	pjdlog_fini();

	exit(0);
}