Example #1
0
void
test_base64(u_int8_t *src, u_int32_t slen, struct kore_buf *res)
{
	char		*in;
	size_t		len;
	u_int8_t	*out;

	kore_buf_appendf(res, "test '%s'\n", src);

	if (!kore_base64_encode(src, slen, &in)) {
		kore_buf_appendf(res, "encoding '%s' failed\n", src);
	} else {
		kore_buf_appendf(res, "encoded: '%s'\n", in);

		if (!kore_base64_decode(in, &out, &len)) {
			kore_buf_appendf(res, "decoding failed\n");
		} else {
			kore_buf_appendf(res, "decoded: ");
			kore_buf_append(res, out, len);
			kore_buf_appendf(res, "\n");
			kore_free(out);
		}

		kore_free(in);
	}

	kore_buf_appendf(res, "\n");
}
Example #2
0
File: buf.c Project: SDAIA/kore
void
kore_buf_free(struct kore_buf *buf)
{
	kore_buf_cleanup(buf);
	if (buf->flags & KORE_BUF_OWNER_API)
		kore_free(buf);
}
Example #3
0
File: buf.c Project: SDAIA/kore
void
kore_buf_replace_string(struct kore_buf *b, char *src, void *dst, size_t len)
{
	char		*key, *end, *tmp, *p;
	size_t		blen, off, off2, nlen, klen;

	off = 0;
	klen = strlen(src);
	for (;;) {
		blen = b->offset;
		nlen = blen + len;
		p = (char *)b->data;

		key = kore_mem_find(p + off, b->offset - off, src, klen);
		if (key == NULL)
			break;

		end = key + klen;
		off = key - p;
		off2 = ((char *)(b->data + b->offset) - end);

		tmp = kore_malloc(nlen);
		memcpy(tmp, p, off);
		if (dst != NULL)
			memcpy((tmp + off), dst, len);
		memcpy((tmp + off + len), end, off2);

		kore_free(b->data);
		b->data = (u_int8_t *)tmp;
		b->offset = off + len + off2;
		b->length = nlen;

		off = off + len;
	}
}
Example #4
0
File: buf.c Project: SDAIA/kore
void
kore_buf_cleanup(struct kore_buf *buf)
{
	kore_free(buf->data);
	buf->data = NULL;
	buf->offset = 0;
	buf->length = 0;
}
Example #5
0
void
connection_del(struct connection *c)
{
	printf("%p: disconnecting\n", (void *)c);

	if (c->hdlr_extra != NULL)
		kore_pgsql_cleanup(c->hdlr_extra);

	kore_free(c->hdlr_extra);
	c->hdlr_extra = NULL;
}
Example #6
0
int
serve_file_upload(struct http_request *req)
{
	u_int8_t		*d;
	struct kore_buf		*b;
	struct http_file	*f;
	size_t			len;
	char			*name, buf[BUFSIZ];

	b = kore_buf_alloc(asset_len_upload_html);
	kore_buf_append(b, asset_upload_html, asset_len_upload_html);

	if (req->method == HTTP_METHOD_POST) {
		if (req->http_body_fd != -1)
			kore_log(LOG_NOTICE, "file is on disk");

		http_populate_multipart_form(req);
		if (http_argument_get_string(req, "firstname", &name)) {
			kore_buf_replace_string(b, "$firstname$",
			    name, strlen(name));
		} else {
			kore_buf_replace_string(b, "$firstname$", NULL, 0);
		}

		if ((f = http_file_lookup(req, "file")) != NULL) {
			(void)snprintf(buf, sizeof(buf),
			    "%s is %ld bytes", f->filename, f->length);
			kore_buf_replace_string(b,
			    "$upload$", buf, strlen(buf));
		} else {
			kore_buf_replace_string(b, "$upload$", NULL, 0);
		}
	} else {
		kore_buf_replace_string(b, "$upload$", NULL, 0);
		kore_buf_replace_string(b, "$firstname$", NULL, 0);
	}

	d = kore_buf_release(b, &len);

	http_response_header(req, "content-type", "text/html");
	http_response(req, 200, d, len);
	kore_free(d);

	return (KORE_RESULT_OK);
}
Example #7
0
int
serve_b64test(struct http_request *req)
{
	int			i;
	size_t			len;
	struct kore_buf		*res;
	u_int8_t		*data;

	res = kore_buf_alloc(1024);
	for (i = 0; b64tests[i] != NULL; i++)
		test_base64((u_int8_t *)b64tests[i], strlen(b64tests[i]), res);

	data = kore_buf_release(res, &len);

	http_response_header(req, "content-type", "text/plain");
	http_response(req, 200, data, len);
	kore_free(data);

	return (KORE_RESULT_OK);
}
Example #8
0
int
serve_params_test(struct http_request *req)
{
	struct kore_buf		*b;
	u_int8_t		*d;
	size_t			len;
	int			r, i;
	char			*test, name[10];

	if (req->method == HTTP_METHOD_GET)
		http_populate_get(req);
	else if (req->method == HTTP_METHOD_POST)
		http_populate_post(req);

	b = kore_buf_alloc(asset_len_params_html);
	kore_buf_append(b, asset_params_html, asset_len_params_html);

	/*
	 * The GET parameters will be filtered out on POST.
	 */
	if (http_argument_get_string(req, "arg1", &test)) {
		kore_buf_replace_string(b, "$arg1$", test, strlen(test));
	} else {
		kore_buf_replace_string(b, "$arg1$", NULL, 0);
	}

	if (http_argument_get_string(req, "arg2", &test)) {
		kore_buf_replace_string(b, "$arg2$", test, strlen(test));
	} else {
		kore_buf_replace_string(b, "$arg2$", NULL, 0);
	}

	if (req->method == HTTP_METHOD_GET) {
		kore_buf_replace_string(b, "$test1$", NULL, 0);
		kore_buf_replace_string(b, "$test2$", NULL, 0);
		kore_buf_replace_string(b, "$test3$", NULL, 0);

		if (http_argument_get_uint16(req, "id", &r))
			kore_log(LOG_NOTICE, "id: %d", r);
		else
			kore_log(LOG_NOTICE, "No id set");

		http_response_header(req, "content-type", "text/html");
		d = kore_buf_release(b, &len);
		http_response(req, 200, d, len);
		kore_free(d);

		return (KORE_RESULT_OK);
	}

	for (i = 1; i < 4; i++) {
		(void)snprintf(name, sizeof(name), "test%d", i);
		if (http_argument_get_string(req, name, &test)) {
			(void)snprintf(name, sizeof(name), "$test%d$", i);
			kore_buf_replace_string(b, name, test, strlen(test));
		} else {
			(void)snprintf(name, sizeof(name), "$test%d$", i);
			kore_buf_replace_string(b, name, NULL, 0);
		}
	}

	http_response_header(req, "content-type", "text/html");
	d = kore_buf_release(b, &len);
	http_response(req, 200, d, len);
	kore_free(d);

	return (KORE_RESULT_OK);
}
Example #9
0
File: kore.c Project: SDAIA/kore
int
main(int argc, char *argv[])
{
	int		ch, flags;

	flags = 0;

#if !defined(KORE_SINGLE_BINARY)
	while ((ch = getopt(argc, argv, "c:dfhnrv")) != -1) {
#else
	while ((ch = getopt(argc, argv, "dfhnrv")) != -1) {
#endif
		flags++;
		switch (ch) {
#if !defined(KORE_SINGLE_BINARY)
		case 'c':
			config_file = optarg;
			break;
#endif
#if defined(KORE_DEBUG)
		case 'd':
			kore_debug = 1;
			break;
#endif
		case 'f':
			foreground = 1;
			break;
		case 'h':
			usage();
			break;
		case 'n':
			skip_chroot = 1;
			break;
		case 'r':
			skip_runas = 1;
			break;
		case 'v':
			version();
			break;
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	kore_mem_init();

#if !defined(KORE_SINGLE_BINARY)
	if (argc > 0) {
		if (flags)
			fatal("You cannot specify kore flags and a command");
		return (kore_cli_main(argc, argv));
	}
#endif

	kore_pid = getpid();
	nlisteners = 0;
	LIST_INIT(&listeners);

	kore_log_init();
#if !defined(KORE_NO_HTTP)
	kore_auth_init();
	kore_validator_init();
#endif
	kore_domain_init();
	kore_module_init();
	kore_server_sslstart();

#if !defined(KORE_SINGLE_BINARY)
	if (config_file == NULL)
		usage();
#else
	kore_module_load(NULL, NULL);
#endif

	kore_parse_config();
	kore_platform_init();

#if !defined(KORE_NO_HTTP)
	kore_accesslog_init();
	if (http_body_disk_offload > 0) {
		if (mkdir(http_body_disk_path, 0700) == -1 && errno != EEXIST) {
			printf("can't create http_body_disk_path '%s': %s\n",
			    http_body_disk_path, errno_s);
			return (KORE_RESULT_ERROR);
		}
	}
#endif

	sig_recv = 0;
	signal(SIGHUP, kore_signal);
	signal(SIGQUIT, kore_signal);
	signal(SIGTERM, kore_signal);

	if (foreground)
		signal(SIGINT, kore_signal);
	else
		signal(SIGINT, SIG_IGN);

	kore_server_start();

	kore_log(LOG_NOTICE, "server shutting down");
	kore_worker_shutdown();

	if (!foreground)
		unlink(kore_pidfile);

	kore_listener_cleanup();
	kore_log(LOG_NOTICE, "goodbye");

	return (0);
}

#if !defined(KORE_NO_TLS)
int
kore_tls_sni_cb(SSL *ssl, int *ad, void *arg)
{
	struct kore_domain	*dom;
	const char		*sname;

	sname = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
	kore_debug("kore_tls_sni_cb(): received host %s", sname);

	if (sname != NULL && (dom = kore_domain_lookup(sname)) != NULL) {
		kore_debug("kore_ssl_sni_cb(): Using %s CTX", sname);
		SSL_set_SSL_CTX(ssl, dom->ssl_ctx);

		if (dom->cafile != NULL) {
			SSL_set_verify(ssl, SSL_VERIFY_PEER |
			    SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
		} else {
			SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
		}

		return (SSL_TLSEXT_ERR_OK);
	}

	return (SSL_TLSEXT_ERR_NOACK);
}

void
kore_tls_info_callback(const SSL *ssl, int flags, int ret)
{
	struct connection	*c;

	if (flags & SSL_CB_HANDSHAKE_START) {
		if ((c = SSL_get_app_data(ssl)) == NULL)
			fatal("no SSL_get_app_data");
		c->tls_reneg++;
	}
}
#endif

int
kore_server_bind(const char *ip, const char *port, const char *ccb)
{
	struct listener		*l;
	int			on, r;
	struct addrinfo		hints, *results;

	kore_debug("kore_server_bind(%s, %s)", ip, port);

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	hints.ai_flags = 0;

	r = getaddrinfo(ip, port, &hints, &results);
	if (r != 0)
		fatal("getaddrinfo(%s): %s", ip, gai_strerror(r));

	l = kore_malloc(sizeof(struct listener));
	l->type = KORE_TYPE_LISTENER;
	l->addrtype = results->ai_family;

	if (l->addrtype != AF_INET && l->addrtype != AF_INET6)
		fatal("getaddrinfo(): unknown address family %d", l->addrtype);

	if ((l->fd = socket(results->ai_family, SOCK_STREAM, 0)) == -1) {
		kore_free(l);
		freeaddrinfo(results);
		kore_debug("socket(): %s", errno_s);
		printf("failed to create socket: %s\n", errno_s);
		return (KORE_RESULT_ERROR);
	}

	if (!kore_connection_nonblock(l->fd, 1)) {
		kore_free(l);
		freeaddrinfo(results);
		printf("failed to make socket non blocking: %s\n", errno_s);
		return (KORE_RESULT_ERROR);
	}

	on = 1;
	if (setsockopt(l->fd, SOL_SOCKET,
	    SO_REUSEADDR, (const char *)&on, sizeof(on)) == -1) {
		close(l->fd);
		kore_free(l);
		freeaddrinfo(results);
		kore_debug("setsockopt(): %s", errno_s);
		printf("failed to set SO_REUSEADDR: %s\n", errno_s);
		return (KORE_RESULT_ERROR);
	}

	if (bind(l->fd, results->ai_addr, results->ai_addrlen) == -1) {
		close(l->fd);
		kore_free(l);
		freeaddrinfo(results);
		kore_debug("bind(): %s", errno_s);
		printf("failed to bind to %s port %s: %s\n", ip, port, errno_s);
		return (KORE_RESULT_ERROR);
	}

	freeaddrinfo(results);

	if (listen(l->fd, kore_socket_backlog) == -1) {
		close(l->fd);
		kore_free(l);
		kore_debug("listen(): %s", errno_s);
		printf("failed to listen on socket: %s\n", errno_s);
		return (KORE_RESULT_ERROR);
	}

	if (ccb != NULL) {
		*(void **)&(l->connect) = kore_module_getsym(ccb);
		if (l->connect == NULL) {
			printf("no such callback: '%s'\n", ccb);
			close(l->fd);
			kore_free(l);
			return (KORE_RESULT_ERROR);
		}
	} else {
		l->connect = NULL;
	}

	nlisteners++;
	LIST_INSERT_HEAD(&listeners, l, list);

	if (foreground) {
#if !defined(KORE_NO_TLS)
		kore_log(LOG_NOTICE, "running on https://%s:%s", ip, port);
#else
		kore_log(LOG_NOTICE, "running on http://%s:%s", ip, port);
#endif
	}

	return (KORE_RESULT_OK);
}

void
kore_listener_cleanup(void)
{
	struct listener		*l;

	while (!LIST_EMPTY(&listeners)) {
		l = LIST_FIRST(&listeners);
		LIST_REMOVE(l, list);
		close(l->fd);
		kore_free(l);
	}
}

void
kore_signal(int sig)
{
	sig_recv = sig;
}

static void
kore_server_sslstart(void)
{
#if !defined(KORE_NO_TLS)
	kore_debug("kore_server_sslstart()");

	SSL_library_init();
	SSL_load_error_strings();
#endif
}