Exemplo n.º 1
0
/* Disconnect and some other clean up. */
int http_exit(http_t *client)
{
	ASSERT(client);

	if (!client->initialized)
		return 0;

	client->initialized = 0;
	if (client->ssl_enabled)
		ssl_exit(client);

	return tcp_exit(&client->tcp);
}
Exemplo n.º 2
0
int main(int argc, char *argv[])
{
	int c, rc = 0, restart;
	struct option opt[] = {
		{ "once",              0, 0, '1' },
		{ "continue-on-error", 0, 0, 'c' },
		{ "exec",              1, 0, 'e' },
		{ "config",            1, 0, 'f' },
		{ "iface",             1, 0, 'i' },
		{ "loglevel",          1, 0, 'l' },
		{ "help",              0, 0, 'h' },
		{ "foreground",        0, 0, 'n' },
		{ "pidfile",           1, 0, 100 },
		{ "drop-privs",        1, 0, 'p' },
		{ "syslog",            0, 0, 's' },
		{ "startup-delay",     1, 0, 't' },
		{ "version",           0, 0, 'v' },
		{ NULL,                0, 0, 0   }
	};
	ddns_t *ctx = NULL;

	while ((c = getopt_long(argc, argv, "1ce:f:h?i:l:np:st:v", opt, NULL)) != EOF) {
		switch (c) {
		case '1':	/* --once */
			once = 1;
			break;

		case 'c':	/* --continue-on-error */
			ignore_errors = 1;
			break;

		case 'e':	/* --exec=CMD */
			script_exec = strdup(optarg);
			break;

		case 'f':	/* --config=FILE */
			config = strdup(optarg);
			break;

		case 'i':	/* --iface=IFNAME */
			iface = strdup(optarg);
			break;

		case 'l':	/* --loglevel=LEVEL */
			loglevel = loglvl(optarg);
			if (-1 == loglevel)
				return usage(1);
			break;

		case 'n':	/* --foreground */
			background = 0;
			break;

		case 100:	/* --pidfile=BASENAME */
			pidfile_name = strdup(optarg);
			break;

		case 'p':	/* --drop-privs=USER[:GROUP] */
			parse_privs(optarg);
			break;

		case 's':	/* --syslog */
			use_syslog = 1;
			break;

		case 't':	/* --startup-delay=SEC */
			startup_delay = atoi(optarg);
			break;

		case 'v':
			puts(VERSION);
			return 0;

		case 'h':	/* --help */
		case ':':	/* Missing parameter for option. */
		case '?':	/* Unknown option. */
		default:
			return usage(0);
		}
	}

	if (background) {
		if (daemon(0, 0) < 0) {
			fprintf(stderr, "Failed daemonizing %s: %m\n", __progname);
			return RC_OS_FORK_FAILURE;
		}
		use_syslog = 1;
	}

	if (use_syslog) {
		openlog(NULL, LOG_PID, LOG_USER);
		setlogmask(LOG_UPTO(loglevel));
	}

	if (drop_privs()) {
		logit(LOG_WARNING, "Failed dropping privileges: %s", strerror(errno));
		return RC_OS_CHANGE_PERSONA_FAILURE;
	}

	/* "Hello!" Let user know we've started up OK */
	logit(LOG_NOTICE, "%s", VERSION_STRING);

	if (!config)
		config = strdup(DEFAULT_CONFIG_FILE);

	/* Prepare SSL library, if enabled */
	ssl_init();

	do {
		restart = 0;

		rc = alloc_context(&ctx);
		if (rc != RC_OK)
			break;

		if (os_install_signal_handler(ctx))
			return RC_OS_INSTALL_SIGHANDLER_FAILED;

		cfg = conf_parse_file(config, ctx);
		if (!cfg) {
			free_context(ctx);
			return RC_FILE_IO_MISSING_FILE;
		}

		rc = ddns_main_loop(ctx);
		if (rc == RC_RESTART)
			restart = 1;

		free_context(ctx);
		cfg_free(cfg);
	} while (restart);

	if (use_syslog)
		closelog();
	free(config);
	ssl_exit();

	return rc;
}
Exemplo n.º 3
0
int ssl_init(http_t *client, char *msg)
{
#ifndef ENABLE_SSL
	(void)client;
	(void)msg;
	return 0;
#else
	int err, err_ssl, rc = 0;
	char buf[256];
	const char *sn;
	X509 *cert;

	if (client->verbose > 1)
		logit(LOG_INFO, "%s, initiating HTTPS ...", msg);

	do {
		client->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
		if (!client->ssl_ctx)
			return RC_HTTPS_OUT_OF_MEMORY;

#if defined(CONFIG_OPENSSL)
		/* POODLE, only allow TLSv1.x or later */
		SSL_CTX_set_options(client->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION);
#endif

		client->ssl = SSL_new(client->ssl_ctx);
		if (!client->ssl) {
			rc = RC_HTTPS_OUT_OF_MEMORY;
			break;
		}

		http_get_remote_name(client, &sn);
		if (set_server_name(client->ssl, sn)) {
			rc = RC_HTTPS_SNI_ERROR;
			break;
		}

		SSL_set_fd(client->ssl, client->tcp.ip.socket);
		err = SSL_connect(client->ssl);
		if (err <= 0) {
			err_ssl = SSL_get_error(client->ssl, err);
			logit(LOG_ERR, "SSL_connect %s! (err: %d)", "FAILED", err_ssl);
			rc = RC_HTTPS_FAILED_CONNECT;
			break;
		}

		if (client->verbose > 0)
			logit(LOG_INFO, "SSL connection using %s", SSL_get_cipher(client->ssl));

		/* Get server's certificate (note: beware of dynamic allocation) - opt */
		cert = SSL_get_peer_certificate(client->ssl);
		if (!cert) {
			logit(LOG_ERR, "SSL_get_peer_certificate %s!", "FAILED");
			rc = RC_HTTPS_FAILED_GETTING_CERT;
			break;
		}

		/* Logging some cert details. Please note: X509_NAME_oneline doesn't
		   work when giving NULL instead of a buffer. */
		buf[0] = 0;
		X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
		if (client->verbose > 1)
			logit(LOG_INFO, "SSL server cert subject: %s", buf);

		buf[0] = 0;
		X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
		if (client->verbose > 1)
			logit(LOG_INFO, "SSL server cert issuer: %s", buf);

		/* We could do all sorts of certificate verification stuff here before
		   deallocating the certificate. */
		X509_free(cert);
	} while (0);

	if (rc) {
		ssl_exit(client);
		return rc;
	}

	return 0;
#endif
}