mirror of
https://github.com/jorisvink/kore
synced 2025-03-10 04:59:02 -04:00
Merge branch 'master' into 4.x-releng
This commit is contained in:
commit
e466871b59
6
BEERS
6
BEERS
@ -17,20 +17,22 @@ I will note down the beer of your choice between the brackets.
|
|||||||
[] Daniel Fahlgren x 2
|
[] Daniel Fahlgren x 2
|
||||||
[] Dmitrii Golub
|
[] Dmitrii Golub
|
||||||
[] Elliot Schlegelmilch
|
[] Elliot Schlegelmilch
|
||||||
[] Erik Karlsson
|
[] Erik Karlsson x 2
|
||||||
[] Frederic Cambus
|
[] Frederic Cambus
|
||||||
[] Guy Nankivell
|
[] Guy Nankivell
|
||||||
[] James Turner
|
[] James Turner
|
||||||
|
[] Joel Arbring x 2
|
||||||
[] Manuel Kniep
|
[] Manuel Kniep
|
||||||
[] Marcin Szczepaniak
|
[] Marcin Szczepaniak
|
||||||
[] Matt Thompson
|
[] Matt Thompson
|
||||||
|
[] Matthew Norström
|
||||||
[] Nandor Kracser
|
[] Nandor Kracser
|
||||||
[] Pascal Borreli
|
[] Pascal Borreli
|
||||||
[] Quentin Perez
|
[] Quentin Perez
|
||||||
[] Raphaël Monrouzeau
|
[] Raphaël Monrouzeau
|
||||||
[] Raymond Pasco
|
[] Raymond Pasco
|
||||||
[] Remy Noulin
|
[] Remy Noulin
|
||||||
[] Rickard Lind
|
[] Rickard Lind x 2
|
||||||
[] Shih-Yuan Lee
|
[] Shih-Yuan Lee
|
||||||
[] Stanislav Yudin
|
[] Stanislav Yudin
|
||||||
[] Stig Telfer
|
[] Stig Telfer
|
||||||
|
27
Makefile
27
Makefile
@ -21,9 +21,9 @@ VERSION=$(OBJDIR)/version.c
|
|||||||
PYTHON_CURLOPT=misc/curl/python_curlopt.h
|
PYTHON_CURLOPT=misc/curl/python_curlopt.h
|
||||||
|
|
||||||
S_SRC= src/kore.c src/buf.c src/config.c src/connection.c \
|
S_SRC= src/kore.c src/buf.c src/config.c src/connection.c \
|
||||||
src/domain.c src/filemap.c src/fileref.c src/json.c src/mem.c \
|
src/domain.c src/filemap.c src/fileref.c src/json.c src/log.c \
|
||||||
src/msg.c src/module.c src/net.c src/pool.c src/runtime.c src/timer.c \
|
src/mem.c src/msg.c src/module.c src/net.c src/pool.c src/runtime.c \
|
||||||
src/utils.c src/worker.c src/keymgr.c
|
src/timer.c src/utils.c src/worker.c src/keymgr.c
|
||||||
|
|
||||||
FEATURES=
|
FEATURES=
|
||||||
FEATURES_INC=
|
FEATURES_INC=
|
||||||
@ -31,7 +31,7 @@ FEATURES_INC=
|
|||||||
CFLAGS+=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
|
CFLAGS+=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
|
||||||
CFLAGS+=-Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual
|
CFLAGS+=-Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual
|
||||||
CFLAGS+=-Wsign-compare -Iinclude/kore -I$(OBJDIR) -std=c99 -pedantic
|
CFLAGS+=-Wsign-compare -Iinclude/kore -I$(OBJDIR) -std=c99 -pedantic
|
||||||
CFLAGS+=-Wtype-limits
|
CFLAGS+=-Wtype-limits -fno-common
|
||||||
CFLAGS+=-DPREFIX='"$(PREFIX)"' -fstack-protector-all
|
CFLAGS+=-DPREFIX='"$(PREFIX)"' -fstack-protector-all
|
||||||
|
|
||||||
ifneq ("$(OPENSSL_PATH)", "")
|
ifneq ("$(OPENSSL_PATH)", "")
|
||||||
@ -66,7 +66,7 @@ ifneq ("$(NOHTTP)", "")
|
|||||||
FEATURES+=-DKORE_NO_HTTP
|
FEATURES+=-DKORE_NO_HTTP
|
||||||
else
|
else
|
||||||
S_SRC+= src/auth.c src/accesslog.c src/http.c \
|
S_SRC+= src/auth.c src/accesslog.c src/http.c \
|
||||||
src/validator.c src/websocket.c
|
src/route.c src/validator.c src/websocket.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ("$(PGSQL)", "")
|
ifneq ("$(PGSQL)", "")
|
||||||
@ -132,8 +132,10 @@ ifneq ("$(SANITIZE)", "")
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ("$(OSNAME)", "darwin")
|
ifeq ("$(OSNAME)", "darwin")
|
||||||
CFLAGS+=-I/opt/local/include/ -I/usr/local/opt/openssl/include
|
OSSL_INCL=$(shell pkg-config openssl --cflags)
|
||||||
LDFLAGS+=-L/opt/local/lib -L/usr/local/opt/openssl/lib
|
CFLAGS+=$(OSSL_INCL)
|
||||||
|
LDFLAGS+=$(shell pkg-config openssl --libs)
|
||||||
|
FEATURES_INC+=$(OSSL_INCL)
|
||||||
S_SRC+=src/bsd.c
|
S_SRC+=src/bsd.c
|
||||||
else ifeq ("$(OSNAME)", "linux")
|
else ifeq ("$(OSNAME)", "linux")
|
||||||
CFLAGS+=-D_GNU_SOURCE=1 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
|
CFLAGS+=-D_GNU_SOURCE=1 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
|
||||||
@ -160,7 +162,7 @@ $(PLATFORM): $(OBJDIR) force
|
|||||||
$(PYTHON_CURLOPT): $(OBJDIR) force
|
$(PYTHON_CURLOPT): $(OBJDIR) force
|
||||||
@cp $(PYTHON_CURLOPT) $(OBJDIR)
|
@cp $(PYTHON_CURLOPT) $(OBJDIR)
|
||||||
|
|
||||||
$(VERSION): force
|
$(VERSION): $(OBJDIR) force
|
||||||
@if [ -d .git ]; then \
|
@if [ -d .git ]; then \
|
||||||
GIT_REVISION=`git rev-parse --short=8 HEAD`; \
|
GIT_REVISION=`git rev-parse --short=8 HEAD`; \
|
||||||
GIT_BRANCH=`git rev-parse --abbrev-ref HEAD`; \
|
GIT_BRANCH=`git rev-parse --abbrev-ref HEAD`; \
|
||||||
@ -174,12 +176,15 @@ $(VERSION): force
|
|||||||
echo "No version information found (no .git or RELEASE)"; \
|
echo "No version information found (no .git or RELEASE)"; \
|
||||||
exit 1; \
|
exit 1; \
|
||||||
fi
|
fi
|
||||||
|
@printf "const char *kore_build_date = \"%s\";\n" \
|
||||||
|
`date +"%Y-%m-%d"` >> $(VERSION);
|
||||||
|
|
||||||
$(KODEV): src/cli.c
|
$(KODEV): src/cli.c
|
||||||
$(MAKE) -C kodev
|
$(MAKE) -C kodev
|
||||||
|
|
||||||
$(KORE): $(OBJDIR) $(S_OBJS)
|
$(KORE): $(OBJDIR) $(S_OBJS)
|
||||||
$(CC) $(S_OBJS) $(LDFLAGS) -o $(KORE)
|
$(CC) $(S_OBJS) $(LDFLAGS) -o $(KORE)
|
||||||
|
@echo $(LDFLAGS) > kore.linker
|
||||||
@echo $(FEATURES) $(FEATURES_INC) > kore.features
|
@echo $(FEATURES) $(FEATURES_INC) > kore.features
|
||||||
|
|
||||||
objects: $(OBJDIR) $(PLATFORM) $(GENERATED) $(S_OBJS)
|
objects: $(OBJDIR) $(PLATFORM) $(GENERATED) $(S_OBJS)
|
||||||
@ -197,7 +202,9 @@ install:
|
|||||||
install -m 644 share/man/kodev.1 $(DESTDIR)$(MAN_DIR)/man1/kodev.1
|
install -m 644 share/man/kodev.1 $(DESTDIR)$(MAN_DIR)/man1/kodev.1
|
||||||
install -m 555 $(KORE) $(DESTDIR)$(INSTALL_DIR)/$(KORE)
|
install -m 555 $(KORE) $(DESTDIR)$(INSTALL_DIR)/$(KORE)
|
||||||
install -m 644 kore.features $(DESTDIR)$(SHARE_DIR)/features
|
install -m 644 kore.features $(DESTDIR)$(SHARE_DIR)/features
|
||||||
|
install -m 644 kore.linker $(DESTDIR)$(SHARE_DIR)/linker
|
||||||
install -m 644 include/kore/*.h $(DESTDIR)$(INCLUDE_DIR)
|
install -m 644 include/kore/*.h $(DESTDIR)$(INCLUDE_DIR)
|
||||||
|
install -m 644 misc/ffdhe4096.pem $(DESTDIR)$(SHARE_DIR)/ffdhe4096.pem
|
||||||
$(MAKE) -C kodev install
|
$(MAKE) -C kodev install
|
||||||
$(MAKE) install-sources
|
$(MAKE) install-sources
|
||||||
|
|
||||||
@ -253,6 +260,8 @@ tools-install:
|
|||||||
$(OBJDIR)/%.o: src/%.c
|
$(OBJDIR)/%.o: src/%.c
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
src/kore.c: $(VERSION)
|
||||||
|
|
||||||
src/python.c: $(PYTHON_CURLOPT)
|
src/python.c: $(PYTHON_CURLOPT)
|
||||||
|
|
||||||
src/seccomp.c: $(PLATFORM)
|
src/seccomp.c: $(PLATFORM)
|
||||||
@ -260,7 +269,7 @@ src/seccomp.c: $(PLATFORM)
|
|||||||
clean:
|
clean:
|
||||||
rm -f $(VERSION)
|
rm -f $(VERSION)
|
||||||
find . -type f -name \*.o -exec rm {} \;
|
find . -type f -name \*.o -exec rm {} \;
|
||||||
rm -rf $(KORE) $(OBJDIR) kore.features
|
rm -rf $(KORE) $(OBJDIR) kore.features kore.linker
|
||||||
$(MAKE) -C kodev clean
|
$(MAKE) -C kodev clean
|
||||||
|
|
||||||
releng-build-examples:
|
releng-build-examples:
|
||||||
|
@ -35,7 +35,7 @@ License
|
|||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
--------------
|
--------------
|
||||||
[Read the documentation](https://docs.kore.io/4.0.0/)
|
[Read the documentation](https://docs.kore.io/4.1.0/)
|
||||||
|
|
||||||
Performance
|
Performance
|
||||||
-----------
|
-----------
|
||||||
@ -52,11 +52,11 @@ Kore only supports x64, arm and aarch64 architectures.
|
|||||||
|
|
||||||
Building Kore
|
Building Kore
|
||||||
-------------
|
-------------
|
||||||
Clone this repository or get the latest release at [https://kore.io/releases/4.0.0](https://kore.io/releases/4.0.0).
|
Clone this repository or get the latest release at [https://kore.io/releases/4.1.0](https://kore.io/releases/4.1.0).
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
* openssl (1.0.2, 1.1.0 or 1.1.1)
|
* openssl 1.1.1 or libressl 3.x
|
||||||
(note: libressl 3.0.0+ works as a replacement)
|
(note: openssl 3.0.0 is currently *not* supported)
|
||||||
|
|
||||||
Requirement for asynchronous curl (optional)
|
Requirement for asynchronous curl (optional)
|
||||||
* libcurl (7.64.0 or higher)
|
* libcurl (7.64.0 or higher)
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
# Server configuration.
|
# Server configuration.
|
||||||
server tls {
|
server tls {
|
||||||
bind 127.0.0.1 443
|
bind 127.0.0.1 443
|
||||||
#bind_unix /var/run/kore.sock
|
#unix /var/run/kore.sock
|
||||||
}
|
}
|
||||||
|
|
||||||
#server notls {
|
#server notls {
|
||||||
@ -20,16 +20,57 @@ server tls {
|
|||||||
# tls no
|
# tls no
|
||||||
#}
|
#}
|
||||||
|
|
||||||
# The worker process root directory. If chrooting was not disabled
|
# Kore can have multiple settings for each processes that run under it.
|
||||||
# at startup the worker processes will chroot into this directory.
|
# There are 3 different type of processes:
|
||||||
#
|
#
|
||||||
# If this configuration option is not set, Kore will take the current
|
# 1) Worker processes, these handle the HTTP requests and your code
|
||||||
# working directory as the root.
|
# runs inside of these.
|
||||||
root /home/joris/src/kore
|
# 2) The keymgr process, this handles your domain private keys
|
||||||
|
# and signing during the TLS handshakes. It also holds your
|
||||||
|
# ACME account-key and will sign ACME requests.
|
||||||
|
# 3) The acme process, this talks to the ACME servers.
|
||||||
|
#
|
||||||
|
# You can individually turn on/off chrooting and dropping user
|
||||||
|
# privileges per process. The -n and -r command-line options
|
||||||
|
# are a global override for skipping chroot or dropping user
|
||||||
|
# permissions on all processes.
|
||||||
|
#
|
||||||
|
# If no root/runas options are set in a process, it will inherit the
|
||||||
|
# default values from the worker processes.
|
||||||
|
#
|
||||||
|
# The worker processes will get the current working directory or
|
||||||
|
# current user if no options where specified for it.
|
||||||
|
#
|
||||||
|
# Configures the worker processes.
|
||||||
|
privsep worker {
|
||||||
|
# The user the workers will run as.
|
||||||
|
runas kore
|
||||||
|
|
||||||
# Worker processes will run as the specified user. If this option is
|
# The root directory for the worker processes, if chroot isn't
|
||||||
# missing Kore will run as the current user.
|
# skipped, this is the directory it will chroot into.
|
||||||
runas joris
|
#
|
||||||
|
# If not set, Kore will take the current working directory.
|
||||||
|
root /var/chroot/kore
|
||||||
|
|
||||||
|
# We could configure this process to not chroot and only
|
||||||
|
# chdir into its root directory.
|
||||||
|
#skip chroot
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configures the keymgr process.
|
||||||
|
# If TLS is enabled you will need to specify paths to the domain
|
||||||
|
# certificate and key that Kore will load. This loading is done
|
||||||
|
# from the keymgr (separate process) and all paths must be relative
|
||||||
|
# to the keymgr process its root configuration option.
|
||||||
|
privsep keymgr {
|
||||||
|
# The user the keymgr will run as.
|
||||||
|
runas keymgr
|
||||||
|
|
||||||
|
# The root directory for the keymgr process. In this example
|
||||||
|
# we do not turn off chroot for this process so the keymgr
|
||||||
|
# will chroot into this directory.
|
||||||
|
root /etc/keymgr
|
||||||
|
}
|
||||||
|
|
||||||
# How many worker processes Kore will spawn. If the directive
|
# How many worker processes Kore will spawn. If the directive
|
||||||
# worker_set_affinity is set to 1 (the default) Kore will automatically
|
# worker_set_affinity is set to 1 (the default) Kore will automatically
|
||||||
@ -88,25 +129,6 @@ workers 4
|
|||||||
# NOTE: This file location must be inside your chrooted environment.
|
# NOTE: This file location must be inside your chrooted environment.
|
||||||
#rand_file random.data
|
#rand_file random.data
|
||||||
|
|
||||||
# Key manager specific options.
|
|
||||||
# If TLS is enabled you will need to specify paths to the domain
|
|
||||||
# certificate and key that Kore will load. This loading is done
|
|
||||||
# from the keymgr (separate process) and all paths must be relative
|
|
||||||
# to the keymgr_root configuration option.
|
|
||||||
#
|
|
||||||
# keymgr_root The root path the keymgr will chdir into.
|
|
||||||
# If chroot was not disable at startup time
|
|
||||||
# the keymgr process will chroot into here.
|
|
||||||
#
|
|
||||||
# keymgr_runas The user to run the keymgr as.
|
|
||||||
#
|
|
||||||
# If privsep and chrooting is enabled at startup time but these
|
|
||||||
# configuration options were not set, they will take over the
|
|
||||||
# values from the 'root' and 'runas' configuration options.
|
|
||||||
#
|
|
||||||
#keymgr_root
|
|
||||||
#keymgr_runas
|
|
||||||
|
|
||||||
# Filemap settings
|
# Filemap settings
|
||||||
# filemap_index Name of the file to be used as the directory
|
# filemap_index Name of the file to be used as the directory
|
||||||
# index for a filemap.
|
# index for a filemap.
|
||||||
@ -189,18 +211,20 @@ validator v_regex regex ^/test/[a-z]*$
|
|||||||
validator v_number regex ^[0-9]*$
|
validator v_number regex ^[0-9]*$
|
||||||
validator v_session function v_session_validate
|
validator v_session function v_session_validate
|
||||||
|
|
||||||
# Specify what TLS version to be used. Default is TLSv1.2
|
# Specify what TLS version to be used. Default is TLSv1.3 if available.
|
||||||
|
# Otherwise it will use TLS 1.2.
|
||||||
# Allowed values:
|
# Allowed values:
|
||||||
# 1.2 for TLSv1.2 (default)
|
# 1.3 for TLSv1.3 (default, if available)
|
||||||
# 1.0 for TLSv1.0
|
# 1.2 for TLSv1.2
|
||||||
# both for TLSv1.0 and TLSv1.2
|
# both for TLSv1.2 and TLSv1.3
|
||||||
#tls_version 1.2
|
#tls_version 1.3
|
||||||
|
|
||||||
# Specify the TLS ciphers that will be used.
|
# Specify the TLS ciphers that will be used.
|
||||||
#tls_cipher ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!kRSA:!kDSA
|
#tls_cipher AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256:AEAD-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256
|
||||||
|
|
||||||
# Required DH parameters for TLS.
|
# Required DH parameters for TLS if DHE ciphersuites are in-use.
|
||||||
#tls_dhparam dh2048.pem
|
# Defaults to SHARE_DIR/ffdhe4096.pem, can be overwritten.
|
||||||
|
#tls_dhparam /usr/local/share/kore/ffdhe4096.pem
|
||||||
|
|
||||||
# OpenBSD specific settings.
|
# OpenBSD specific settings.
|
||||||
# Add more pledges if your application requires more privileges.
|
# Add more pledges if your application requires more privileges.
|
||||||
@ -298,24 +322,24 @@ domain localhost {
|
|||||||
accesslog /var/log/kore_access.log
|
accesslog /var/log/kore_access.log
|
||||||
|
|
||||||
# Page handlers with no authentication required.
|
# Page handlers with no authentication required.
|
||||||
static /css/style.css serve_style_css
|
route /css/style.css serve_style_css
|
||||||
static / serve_index
|
route / serve_index
|
||||||
static /intro.jpg serve_intro
|
route /intro.jpg serve_intro
|
||||||
static /b64test serve_b64test
|
route /b64test serve_b64test
|
||||||
static /upload serve_file_upload
|
route /upload serve_file_upload
|
||||||
static /lock-test serve_lock_test
|
route /lock-test serve_lock_test
|
||||||
static /validator serve_validator
|
route /validator serve_validator
|
||||||
static /params-test serve_params_test
|
route /params-test serve_params_test
|
||||||
static /private serve_private
|
route /private serve_private
|
||||||
|
|
||||||
# Restrict some URIs to certain methods
|
# Restrict some URIs to certain methods
|
||||||
restrict /private post
|
restrict /private post
|
||||||
restrict /validator post get head
|
restrict /validator post get head
|
||||||
|
|
||||||
# Page handlers with authentication.
|
# Page handlers with authentication.
|
||||||
static /private/test serve_private_test auth_example
|
route /private/test serve_private_test auth_example
|
||||||
|
|
||||||
# Allow access to files from the directory static_files via
|
# Allow access to files from the directory route_files via
|
||||||
# the /files/ URI.
|
# the /files/ URI.
|
||||||
#
|
#
|
||||||
# Note the directory given must be relative to the root configuration
|
# Note the directory given must be relative to the root configuration
|
||||||
@ -369,7 +393,7 @@ domain localhost {
|
|||||||
# client_verify /other/ca.crt
|
# client_verify /other/ca.crt
|
||||||
# client_verify_depth 1
|
# client_verify_depth 1
|
||||||
|
|
||||||
# static /css/style.css serve_style_css
|
# route /css/style.css serve_style_css
|
||||||
# static / serve_index
|
# route / serve_index
|
||||||
# dynamic ^/[a-z0-9_]*$ serve_profile
|
# route ^/[a-z0-9_]*$ serve_profile
|
||||||
#}
|
#}
|
||||||
|
@ -5,8 +5,6 @@ server tls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
workers 1
|
workers 1
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
pledge dns
|
pledge dns
|
||||||
|
|
||||||
domain * {
|
domain * {
|
||||||
@ -15,6 +13,11 @@ domain * {
|
|||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
|
|
||||||
route / http
|
route / {
|
||||||
route /ftp ftp
|
handler http
|
||||||
|
}
|
||||||
|
|
||||||
|
route /ftp {
|
||||||
|
handler ftp
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ state_setup(struct http_request *req)
|
|||||||
{
|
{
|
||||||
struct kore_curl *client;
|
struct kore_curl *client;
|
||||||
|
|
||||||
client = http_state_create(req, sizeof(*client), NULL);
|
client = http_state_create(req, sizeof(*client));
|
||||||
|
|
||||||
if (!kore_curl_init(client,
|
if (!kore_curl_init(client,
|
||||||
"http://ftp.eu.openbsd.org/pub/OpenBSD/README", KORE_CURL_ASYNC)) {
|
"http://ftp.eu.openbsd.org/pub/OpenBSD/README", KORE_CURL_ASYNC)) {
|
||||||
|
@ -59,7 +59,7 @@ state_setup(struct http_request *req)
|
|||||||
{
|
{
|
||||||
struct kore_curl *client;
|
struct kore_curl *client;
|
||||||
|
|
||||||
client = http_state_create(req, sizeof(*client), NULL);
|
client = http_state_create(req, sizeof(*client));
|
||||||
|
|
||||||
/* Initialize curl. */
|
/* Initialize curl. */
|
||||||
if (!kore_curl_init(client, "https://kore.io", KORE_CURL_ASYNC)) {
|
if (!kore_curl_init(client, "https://kore.io", KORE_CURL_ASYNC)) {
|
||||||
|
@ -6,15 +6,21 @@ server tls {
|
|||||||
|
|
||||||
load ./cookies.so
|
load ./cookies.so
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
domain * {
|
domain * {
|
||||||
attach tls
|
attach tls
|
||||||
|
|
||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
|
|
||||||
route / serve_cookies
|
route / {
|
||||||
route /secure serve_cookies
|
handler serve_cookies
|
||||||
route /vault serve_cookies
|
}
|
||||||
|
|
||||||
|
route /secure {
|
||||||
|
handler serve_cookies
|
||||||
|
}
|
||||||
|
|
||||||
|
route /vault {
|
||||||
|
handler serve_cookies
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,14 @@ server tls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
load ./cpp.so
|
load ./cpp.so
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
domain * {
|
domain * {
|
||||||
attach tls
|
attach tls
|
||||||
|
|
||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
route / page
|
|
||||||
|
route / {
|
||||||
|
handler page
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
-----BEGIN DH PARAMETERS-----
|
|
||||||
MIIBCAKCAQEAn4f4Qn5SudFjEYPWTbUaOTLUH85YWmmPFW1+b5bRa9ygr+1wfamv
|
|
||||||
VKVT7jO8c4msSNikUf6eEfoH0H4VTCaj+Habwu+Sj+I416r3mliMD4SjNsUJrBrY
|
|
||||||
Y0QV3ZUgZz4A8ARk/WwQcRl8+ZXJz34IaLwAcpyNhoV46iHVxW0ty8ND0U4DIku/
|
|
||||||
PNayKimu4BXWXk4RfwNVP59t8DQKqjshZ4fDnbotskmSZ+e+FHrd+Kvrq/WButvV
|
|
||||||
Bzy9fYgnUlJ82g/bziCI83R2xAdtH014fR63MpElkqdNeChb94pPbEdFlNUvYIBN
|
|
||||||
xx2vTUQMqRbB4UdG2zuzzr5j98HDdblQ+wIBAg==
|
|
||||||
-----END DH PARAMETERS-----
|
|
@ -6,8 +6,6 @@ server tls {
|
|||||||
|
|
||||||
load ./generic.so example_load
|
load ./generic.so example_load
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
http_body_max 1024000000
|
http_body_max 1024000000
|
||||||
http_body_disk_offload 1024000
|
http_body_disk_offload 1024000
|
||||||
|
|
||||||
|
@ -2,13 +2,13 @@ Test parameter to integer conversions.
|
|||||||
|
|
||||||
Run:
|
Run:
|
||||||
```
|
```
|
||||||
# kodev run
|
$ kodev run
|
||||||
```
|
```
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
```
|
```
|
||||||
# curl -i -k https://127.0.0.1:8888/?id=123123
|
$ curl -i -k https://127.0.0.1:8888/?id=123123
|
||||||
# curl -i -k https://127.0.0.1:8888/?id=-123123
|
$ curl -i -k https://127.0.0.1:8888/?id=-123123
|
||||||
```
|
```
|
||||||
|
|
||||||
The correct integer types should only be represented in the output.
|
The correct integer types should only be represented in the output.
|
||||||
|
@ -9,8 +9,6 @@ load ./integers.so
|
|||||||
workers 2
|
workers 2
|
||||||
worker_max_connections 5000
|
worker_max_connections 5000
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
validator v_id regex ^-?[0-9]*.?[0-9]+$
|
validator v_id regex ^-?[0-9]*.?[0-9]+$
|
||||||
|
|
||||||
domain * {
|
domain * {
|
||||||
@ -18,10 +16,12 @@ domain * {
|
|||||||
|
|
||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
route / page
|
|
||||||
|
route / {
|
||||||
|
handler page
|
||||||
|
methods get
|
||||||
|
|
||||||
# allowed parameters in the query string for GETs
|
# allowed parameters in the query string for GETs
|
||||||
params qs:get / {
|
validate get id v_id
|
||||||
validate id v_id
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,14 @@ server tls {
|
|||||||
|
|
||||||
load ./json.so
|
load ./json.so
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
domain 127.0.0.1 {
|
domain 127.0.0.1 {
|
||||||
attach tls
|
attach tls
|
||||||
|
|
||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
|
|
||||||
route / page
|
route / {
|
||||||
restrict / post
|
handler page
|
||||||
|
methods post
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,14 +30,24 @@ page(struct http_request *req)
|
|||||||
kore_json_init(&json, req->http_body->data, req->http_body->length);
|
kore_json_init(&json, req->http_body->data, req->http_body->length);
|
||||||
|
|
||||||
if (!kore_json_parse(&json)) {
|
if (!kore_json_parse(&json)) {
|
||||||
kore_buf_appendf(&buf, "%s\n", kore_json_strerror(&json));
|
kore_buf_appendf(&buf, "%s\n", kore_json_strerror());
|
||||||
} else {
|
} else {
|
||||||
item = kore_json_find_string(json.root, "foo/bar");
|
item = kore_json_find_string(json.root, "foo/bar");
|
||||||
if (item != NULL) {
|
if (item != NULL) {
|
||||||
kore_buf_appendf(&buf,
|
kore_buf_appendf(&buf,
|
||||||
"foo.bar = '%s'\n", item->data.string);
|
"foo.bar = '%s'\n", item->data.string);
|
||||||
} else {
|
} else {
|
||||||
kore_buf_appendf(&buf, "string foo.bar not found\n");
|
kore_buf_appendf(&buf, "foo.bar %s\n",
|
||||||
|
kore_json_strerror());
|
||||||
|
}
|
||||||
|
|
||||||
|
item = kore_json_find_integer_u64(json.root, "foo/integer");
|
||||||
|
if (item != NULL) {
|
||||||
|
kore_buf_appendf(&buf,
|
||||||
|
"foo.integer = '%" PRIu64 "'\n", item->data.u64);
|
||||||
|
} else {
|
||||||
|
kore_buf_appendf(&buf, "foo.integer %s\n",
|
||||||
|
kore_json_strerror());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
examples/json_yajl/.gitignore
vendored
5
examples/json_yajl/.gitignore
vendored
@ -1,5 +0,0 @@
|
|||||||
*.o
|
|
||||||
.objs
|
|
||||||
json_yajl.so
|
|
||||||
assets.h
|
|
||||||
cert
|
|
@ -1,21 +0,0 @@
|
|||||||
This example demonstrates how you can use external libs in your application.
|
|
||||||
|
|
||||||
In this case we link against yajl (Yet Another JSON library) in order to
|
|
||||||
parse a JSON string that was POSTed to the server.
|
|
||||||
|
|
||||||
Take a peek at conf/build.conf for different build flavors and how to
|
|
||||||
link to other libraries.
|
|
||||||
|
|
||||||
Run:
|
|
||||||
```
|
|
||||||
$ kodev run
|
|
||||||
```
|
|
||||||
|
|
||||||
Test:
|
|
||||||
```
|
|
||||||
$ curl -i -k -d '{"foo":{"bar": "Hello world"}}' https://127.0.0.1:8888
|
|
||||||
```
|
|
||||||
|
|
||||||
The result should echo back the foo.bar JSON path value: Hello world.
|
|
||||||
|
|
||||||
The yajl repo is available @ https://github.com/lloyd/yajl
|
|
@ -1,19 +0,0 @@
|
|||||||
# json_yajl build config
|
|
||||||
# You can switch flavors using: kodev flavor [newflavor]
|
|
||||||
|
|
||||||
# The cflags below are shared between flavors
|
|
||||||
cflags=-Wall -Wmissing-declarations -Wshadow
|
|
||||||
cflags=-Wstrict-prototypes -Wmissing-prototypes
|
|
||||||
cflags=-Wpointer-arith -Wcast-qual -Wsign-compare
|
|
||||||
|
|
||||||
dev {
|
|
||||||
# These cflags are added to the shared ones when
|
|
||||||
# you build the "dev" flavor.
|
|
||||||
cflags=-g
|
|
||||||
ldflags=-lyajl
|
|
||||||
}
|
|
||||||
|
|
||||||
#prod {
|
|
||||||
# You can specify additional CFLAGS here which are only
|
|
||||||
# included if you build with the "prod" flavor.
|
|
||||||
#}
|
|
@ -1,18 +0,0 @@
|
|||||||
# Placeholder configuration
|
|
||||||
|
|
||||||
server tls {
|
|
||||||
bind 127.0.0.1 8888
|
|
||||||
}
|
|
||||||
|
|
||||||
load ./json_yajl.so
|
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
domain 127.0.0.1 {
|
|
||||||
attach tls
|
|
||||||
|
|
||||||
certfile cert/server.pem
|
|
||||||
certkey cert/key.pem
|
|
||||||
|
|
||||||
route / page
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2018 Joris Vink <joris@coders.se>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <kore/kore.h>
|
|
||||||
#include <kore/http.h>
|
|
||||||
|
|
||||||
#include <yajl/yajl_tree.h>
|
|
||||||
|
|
||||||
int page(struct http_request *);
|
|
||||||
|
|
||||||
int
|
|
||||||
page(struct http_request *req)
|
|
||||||
{
|
|
||||||
ssize_t ret;
|
|
||||||
struct kore_buf *buf;
|
|
||||||
char *body;
|
|
||||||
yajl_val node, v;
|
|
||||||
char eb[1024];
|
|
||||||
u_int8_t data[BUFSIZ];
|
|
||||||
const char *path[] = { "foo", "bar", NULL };
|
|
||||||
|
|
||||||
/* We only allow POST/PUT methods. */
|
|
||||||
if (req->method != HTTP_METHOD_POST &&
|
|
||||||
req->method != HTTP_METHOD_PUT) {
|
|
||||||
http_response_header(req, "allow", "POST, PUT");
|
|
||||||
http_response(req, HTTP_STATUS_METHOD_NOT_ALLOWED, NULL, 0);
|
|
||||||
return (KORE_RESULT_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read the entire received body into a memory buffer.
|
|
||||||
*/
|
|
||||||
buf = kore_buf_alloc(128);
|
|
||||||
for (;;) {
|
|
||||||
ret = http_body_read(req, data, sizeof(data));
|
|
||||||
if (ret == -1) {
|
|
||||||
kore_buf_free(buf);
|
|
||||||
kore_log(LOG_NOTICE, "error reading body");
|
|
||||||
http_response(req, 500, NULL, 0);
|
|
||||||
return (KORE_RESULT_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
kore_buf_append(buf, data, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Grab our body data as a NUL-terminated string. */
|
|
||||||
body = kore_buf_stringify(buf, NULL);
|
|
||||||
|
|
||||||
/* Parse the body via yajl now. */
|
|
||||||
node = yajl_tree_parse(body, eb, sizeof(eb));
|
|
||||||
if (node == NULL) {
|
|
||||||
if (strlen(eb)) {
|
|
||||||
kore_log(LOG_NOTICE, "parse error: %s", eb);
|
|
||||||
} else {
|
|
||||||
kore_log(LOG_NOTICE, "parse error: unknown");
|
|
||||||
}
|
|
||||||
|
|
||||||
kore_buf_free(buf);
|
|
||||||
http_response(req, 400, NULL, 0);
|
|
||||||
return (KORE_RESULT_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reuse old buffer, don't need it anymore for body. */
|
|
||||||
kore_buf_reset(buf);
|
|
||||||
|
|
||||||
/* Attempt to grab foo.bar from the JSON tree. */
|
|
||||||
v = yajl_tree_get(node, path, yajl_t_string);
|
|
||||||
if (v == NULL) {
|
|
||||||
kore_buf_appendf(buf, "no such path: foo.bar\n");
|
|
||||||
} else {
|
|
||||||
kore_buf_appendf(buf, "foo.bar = '%s'\n", YAJL_GET_STRING(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release the JSON tree now. */
|
|
||||||
yajl_tree_free(node);
|
|
||||||
|
|
||||||
/* Respond to the client. */
|
|
||||||
http_response(req, 200, buf->data, buf->offset);
|
|
||||||
kore_buf_free(buf);
|
|
||||||
|
|
||||||
return (KORE_RESULT_OK);
|
|
||||||
}
|
|
@ -6,14 +6,17 @@ server tls {
|
|||||||
|
|
||||||
load ./jsonrpc.so
|
load ./jsonrpc.so
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
domain * {
|
domain * {
|
||||||
attach tls
|
attach tls
|
||||||
|
|
||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
|
|
||||||
route / homepage
|
route / {
|
||||||
route /v1 v1
|
handler homepage
|
||||||
|
}
|
||||||
|
|
||||||
|
route /v1 {
|
||||||
|
handler v1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,13 @@ server tls {
|
|||||||
|
|
||||||
load ./memtag.so init
|
load ./memtag.so init
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
domain * {
|
domain * {
|
||||||
attach tls
|
attach tls
|
||||||
|
|
||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
|
|
||||||
route / page
|
route / {
|
||||||
|
handler page
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,18 @@ server tls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
load ./messaging.so init
|
load ./messaging.so init
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
workers 4
|
|
||||||
|
|
||||||
domain * {
|
domain * {
|
||||||
attach tls
|
attach tls
|
||||||
|
|
||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
route / page
|
|
||||||
route /shutdown page_shutdown
|
route / {
|
||||||
|
handler page
|
||||||
|
}
|
||||||
|
|
||||||
|
route /shutdown {
|
||||||
|
handler page_shutdown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@ server tls {
|
|||||||
bind 127.0.0.1 8888 connection_setup
|
bind 127.0.0.1 8888 connection_setup
|
||||||
}
|
}
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
domain * {
|
domain * {
|
||||||
attach tls
|
attach tls
|
||||||
|
|
||||||
|
@ -6,8 +6,6 @@ server tls {
|
|||||||
|
|
||||||
load ./parameters.so
|
load ./parameters.so
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
# The validator used to validate the 'id' parameter
|
# The validator used to validate the 'id' parameter
|
||||||
# defined below. We'll use a simple regex to make sure
|
# defined below. We'll use a simple regex to make sure
|
||||||
# it only matches positive numbers.
|
# it only matches positive numbers.
|
||||||
@ -19,15 +17,10 @@ domain * {
|
|||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
|
|
||||||
route / page
|
route / {
|
||||||
|
handler page
|
||||||
|
methods get
|
||||||
|
|
||||||
# The parameters allowed for "/" (GET method).
|
validate qs:get id v_id
|
||||||
#
|
|
||||||
# If you would want to declare parameters available
|
|
||||||
# to the page handler for POST, swap the 'get' setting
|
|
||||||
# to 'post' instead, Kore takes care of the rest.
|
|
||||||
params qs:get / {
|
|
||||||
# Validate the id parameter with the v_id validator.
|
|
||||||
validate id v_id
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,14 @@ server tls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
load ./pgsql-sync.so init
|
load ./pgsql-sync.so init
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
domain * {
|
domain * {
|
||||||
attach tls
|
attach tls
|
||||||
|
|
||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
route / page
|
|
||||||
|
route / {
|
||||||
|
handler page
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,6 @@ server other {
|
|||||||
bind 127.0.0.1 8889 connection_new
|
bind 127.0.0.1 8889 connection_new
|
||||||
}
|
}
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
http_keepalive_time 0
|
http_keepalive_time 0
|
||||||
|
|
||||||
domain * {
|
domain * {
|
||||||
@ -20,6 +18,11 @@ domain * {
|
|||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
|
|
||||||
route / page
|
route / {
|
||||||
route /hello hello
|
handler page
|
||||||
|
}
|
||||||
|
|
||||||
|
route /hello {
|
||||||
|
handler hello
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ request_perform_init(struct http_request *req)
|
|||||||
|
|
||||||
/* Setup our state context (if not yet set). */
|
/* Setup our state context (if not yet set). */
|
||||||
if (!http_state_exists(req)) {
|
if (!http_state_exists(req)) {
|
||||||
state = http_state_create(req, sizeof(*state), NULL);
|
state = http_state_create(req, sizeof(*state));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the kore_pgsql data structure and bind it
|
* Initialize the kore_pgsql data structure and bind it
|
||||||
|
@ -4,8 +4,6 @@ server tls {
|
|||||||
bind 127.0.0.1 8888
|
bind 127.0.0.1 8888
|
||||||
}
|
}
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
websocket_maxframe 65536
|
websocket_maxframe 65536
|
||||||
websocket_timeout 10000
|
websocket_timeout 10000
|
||||||
|
|
||||||
@ -15,6 +13,12 @@ domain * {
|
|||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
|
|
||||||
route / page
|
route / {
|
||||||
route /connect page_ws_connect
|
handler page
|
||||||
|
}
|
||||||
|
|
||||||
|
route /connect {
|
||||||
|
handler page_ws_connect
|
||||||
|
methods get
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <kore/kore.h>
|
#include <kore/kore.h>
|
||||||
#include <kore/http.h>
|
#include <kore/http.h>
|
||||||
#include <kore/tasks.h>
|
#include <kore/tasks.h>
|
||||||
|
#include <kore/hooks.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -49,17 +50,12 @@ void pipe_data_available(struct kore_task *);
|
|||||||
/* Our pipe reader. */
|
/* Our pipe reader. */
|
||||||
struct kore_task pipe_task;
|
struct kore_task pipe_task;
|
||||||
|
|
||||||
/* Module init function (see config). */
|
void
|
||||||
int
|
kore_worker_configure(void)
|
||||||
init(int state)
|
|
||||||
{
|
{
|
||||||
/* Do not allow reload. */
|
|
||||||
if (state == KORE_MODULE_UNLOAD)
|
|
||||||
return (KORE_RESULT_ERROR);
|
|
||||||
|
|
||||||
/* Only do this on a dedicated worker. */
|
/* Only do this on a dedicated worker. */
|
||||||
if (worker->id != 1)
|
if (worker->id != 1)
|
||||||
return (KORE_RESULT_OK);
|
return;
|
||||||
|
|
||||||
/* Create our task. */
|
/* Create our task. */
|
||||||
kore_task_create(&pipe_task, pipe_reader);
|
kore_task_create(&pipe_task, pipe_reader);
|
||||||
@ -69,8 +65,6 @@ init(int state)
|
|||||||
|
|
||||||
/* Start the task. */
|
/* Start the task. */
|
||||||
kore_task_run(&pipe_task);
|
kore_task_run(&pipe_task);
|
||||||
|
|
||||||
return (KORE_RESULT_OK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called whenever we get a new websocket connection. */
|
/* Called whenever we get a new websocket connection. */
|
||||||
|
@ -3,9 +3,11 @@ Kore python async/await examples.
|
|||||||
This example also shows off the asynchronous HTTP client support
|
This example also shows off the asynchronous HTTP client support
|
||||||
and requires libcurl on your machine.
|
and requires libcurl on your machine.
|
||||||
|
|
||||||
|
Requires that Kore is built with PYTHON=1 CURL=1
|
||||||
|
|
||||||
Run:
|
Run:
|
||||||
```
|
```
|
||||||
$ kodev run
|
$ kore app.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Test:
|
Test:
|
||||||
|
@ -16,8 +16,13 @@
|
|||||||
|
|
||||||
import kore
|
import kore
|
||||||
|
|
||||||
from async_queue import queue_helper
|
import async_http
|
||||||
|
import async_queue
|
||||||
|
import async_socket
|
||||||
|
import async_process
|
||||||
|
import async_process
|
||||||
|
|
||||||
# Kore worker started, start the queue helper coroutine.
|
kore.server(ip="127.0.0.1", port="8888", tls=False)
|
||||||
def kore_worker_configure():
|
kore.domain("*")
|
||||||
kore.task_create(queue_helper())
|
|
||||||
|
kore.task_create(async_queue.queue_helper())
|
@ -21,6 +21,7 @@
|
|||||||
import kore
|
import kore
|
||||||
|
|
||||||
# Handler called for /httpclient
|
# Handler called for /httpclient
|
||||||
|
@kore.route("/httpclient", methods=["get"])
|
||||||
async def httpclient(req):
|
async def httpclient(req):
|
||||||
# Create an httpclient.
|
# Create an httpclient.
|
||||||
client = kore.httpclient("https://kore.io")
|
client = kore.httpclient("https://kore.io")
|
@ -28,6 +28,7 @@ import kore
|
|||||||
# The shared lock
|
# The shared lock
|
||||||
lock = kore.lock()
|
lock = kore.lock()
|
||||||
|
|
||||||
|
@kore.route("/lock", methods=["get"])
|
||||||
async def async_lock(req):
|
async def async_lock(req):
|
||||||
# A kore.lock should be used with the "async with" syntax.
|
# A kore.lock should be used with the "async with" syntax.
|
||||||
async with lock:
|
async with lock:
|
@ -25,6 +25,7 @@
|
|||||||
import kore
|
import kore
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
@kore.route("/proc", methods=["get"])
|
||||||
async def async_proc(req):
|
async def async_proc(req):
|
||||||
#
|
#
|
||||||
# You may specify a timeout when creating the kore.proc object.
|
# You may specify a timeout when creating the kore.proc object.
|
@ -36,6 +36,7 @@ async def queue_helper():
|
|||||||
# Send it on the received queue.
|
# Send it on the received queue.
|
||||||
obj["rq"].push(msg)
|
obj["rq"].push(msg)
|
||||||
|
|
||||||
|
@kore.route("/queue", methods=["get"])
|
||||||
async def async_queue(req):
|
async def async_queue(req):
|
||||||
# Create our own queue.
|
# Create our own queue.
|
||||||
rq = kore.queue()
|
rq = kore.queue()
|
@ -23,6 +23,7 @@
|
|||||||
import kore
|
import kore
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
@kore.route("/socket", methods=["get"])
|
||||||
async def async_socket(req):
|
async def async_socket(req):
|
||||||
# Create the socket using Pythons built-in socket class.
|
# Create the socket using Pythons built-in socket class.
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
@ -51,6 +52,7 @@ async def async_socket(req):
|
|||||||
|
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
@kore.route("/socket-test", methods=["get"])
|
||||||
async def socket_test(req):
|
async def socket_test(req):
|
||||||
# Delay response a bit, just cause we can.
|
# Delay response a bit, just cause we can.
|
||||||
await kore.suspend(5000)
|
await kore.suspend(5000)
|
@ -1,34 +0,0 @@
|
|||||||
# python-async build config
|
|
||||||
# You can switch flavors using: kodev flavor [newflavor]
|
|
||||||
|
|
||||||
# Set to yes if you wish to produce a single binary instead
|
|
||||||
# of a dynamic library. If you set this to yes you must also
|
|
||||||
# set kore_source together with kore_flavor.
|
|
||||||
single_binary=yes
|
|
||||||
kore_source=../../
|
|
||||||
kore_flavor=PYTHON=1 CURL=1 NOTLS=1 DEBUG=1
|
|
||||||
|
|
||||||
# The flags below are shared between flavors
|
|
||||||
cflags=-Wall -Wmissing-declarations -Wshadow
|
|
||||||
cflags=-Wstrict-prototypes -Wmissing-prototypes
|
|
||||||
cflags=-Wpointer-arith -Wcast-qual -Wsign-compare
|
|
||||||
|
|
||||||
cxxflags=-Wall -Wmissing-declarations -Wshadow
|
|
||||||
cxxflags=-Wpointer-arith -Wcast-qual -Wsign-compare
|
|
||||||
|
|
||||||
# Mime types for assets served via the builtin asset_serve_*
|
|
||||||
#mime_add=txt:text/plain; charset=utf-8
|
|
||||||
#mime_add=png:image/png
|
|
||||||
#mime_add=html:text/html; charset=utf-8
|
|
||||||
|
|
||||||
dev {
|
|
||||||
# These flags are added to the shared ones when
|
|
||||||
# you build the "dev" flavor.
|
|
||||||
cflags=-g
|
|
||||||
cxxflags=-g
|
|
||||||
}
|
|
||||||
|
|
||||||
#prod {
|
|
||||||
# You can specify additional flags here which are only
|
|
||||||
# included if you build with the "prod" flavor.
|
|
||||||
#}
|
|
@ -1,28 +0,0 @@
|
|||||||
# python-async configuration
|
|
||||||
|
|
||||||
server notls {
|
|
||||||
tls no
|
|
||||||
bind 127.0.0.1 8888
|
|
||||||
}
|
|
||||||
|
|
||||||
python_path src
|
|
||||||
|
|
||||||
python_import ./src/setup.py
|
|
||||||
python_import ./src/async_lock.py
|
|
||||||
python_import ./src/async_queue.py
|
|
||||||
python_import ./src/async_process.py
|
|
||||||
python_import ./src/async_socket.py
|
|
||||||
python_import ./src/async_http.py
|
|
||||||
|
|
||||||
domain * {
|
|
||||||
attach notls
|
|
||||||
|
|
||||||
route /queue async_queue
|
|
||||||
route /lock async_lock
|
|
||||||
route /proc async_proc
|
|
||||||
|
|
||||||
route /socket async_socket
|
|
||||||
route /socket-test socket_test
|
|
||||||
|
|
||||||
route /httpclient httpclient
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Joris Vink <joris@coders.se>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <kore/kore.h>
|
|
||||||
#include <kore/hooks.h>
|
|
||||||
|
|
||||||
/* Let kore handle the default option parsing. */
|
|
||||||
void
|
|
||||||
kore_parent_configure(int argc, char **argv)
|
|
||||||
{
|
|
||||||
kore_default_getopt(argc, argv);
|
|
||||||
}
|
|
11
examples/python-echo/README.md
Normal file
11
examples/python-echo/README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
Example of using the asynchronous python api to create a simple
|
||||||
|
echo server.
|
||||||
|
|
||||||
|
Kore must have been built with PYTHON=1.
|
||||||
|
|
||||||
|
On the command-line run the following
|
||||||
|
|
||||||
|
$ kore echo.py
|
||||||
|
|
||||||
|
Then connect to 127.0.0.1 port 6969 using netcat or so and you'll
|
||||||
|
see it echo back everything you send it.
|
@ -1,34 +0,0 @@
|
|||||||
# python-echo build config
|
|
||||||
# You can switch flavors using: kodev flavor [newflavor]
|
|
||||||
|
|
||||||
# Set to yes if you wish to produce a single binary instead
|
|
||||||
# of a dynamic library. If you set this to yes you must also
|
|
||||||
# set kore_source together with kore_flavor.
|
|
||||||
single_binary=yes
|
|
||||||
kore_source=../../
|
|
||||||
kore_flavor=NOTLS=1 PYTHON=1
|
|
||||||
|
|
||||||
# The flags below are shared between flavors
|
|
||||||
cflags=-Wall -Wmissing-declarations -Wshadow
|
|
||||||
cflags=-Wstrict-prototypes -Wmissing-prototypes
|
|
||||||
cflags=-Wpointer-arith -Wcast-qual -Wsign-compare
|
|
||||||
|
|
||||||
cxxflags=-Wall -Wmissing-declarations -Wshadow
|
|
||||||
cxxflags=-Wpointer-arith -Wcast-qual -Wsign-compare
|
|
||||||
|
|
||||||
# Mime types for assets served via the builtin asset_serve_*
|
|
||||||
#mime_add=txt:text/plain; charset=utf-8
|
|
||||||
#mime_add=png:image/png
|
|
||||||
#mime_add=html:text/html; charset=utf-8
|
|
||||||
|
|
||||||
dev {
|
|
||||||
# These flags are added to the shared ones when
|
|
||||||
# you build the "dev" flavor.
|
|
||||||
cflags=-g
|
|
||||||
cxxflags=-g
|
|
||||||
}
|
|
||||||
|
|
||||||
#prod {
|
|
||||||
# You can specify additional flags here which are only
|
|
||||||
# included if you build with the "prod" flavor.
|
|
||||||
#}
|
|
@ -1,3 +0,0 @@
|
|||||||
# python-echo configuration
|
|
||||||
|
|
||||||
python_import src/echo.py
|
|
@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Joris Vink <joris@coders.se>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <kore/kore.h>
|
|
||||||
#include <kore/hooks.h>
|
|
||||||
|
|
||||||
/* Let kore handle the default option parsing. */
|
|
||||||
void
|
|
||||||
kore_parent_configure(int argc, char **argv)
|
|
||||||
{
|
|
||||||
kore_default_getopt(argc, argv);
|
|
||||||
}
|
|
@ -5,8 +5,6 @@ server tls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
load ./sse.so
|
load ./sse.so
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
http_keepalive_time 600
|
http_keepalive_time 600
|
||||||
|
|
||||||
domain * {
|
domain * {
|
||||||
@ -15,6 +13,11 @@ domain * {
|
|||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
|
|
||||||
route / page
|
route / {
|
||||||
route /subscribe subscribe
|
handler page
|
||||||
|
}
|
||||||
|
|
||||||
|
route /subscribe {
|
||||||
|
handler subscribe
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@ server tls {
|
|||||||
bind 127.0.0.1 8888
|
bind 127.0.0.1 8888
|
||||||
}
|
}
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
task_threads 4
|
task_threads 4
|
||||||
worker_max_connections 1000
|
worker_max_connections 1000
|
||||||
http_keepalive_time 0
|
http_keepalive_time 0
|
||||||
@ -19,14 +17,14 @@ domain * {
|
|||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
accesslog kore_access.log
|
accesslog kore_access.log
|
||||||
|
|
||||||
route / page_handler
|
route / {
|
||||||
route /post_back post_back
|
handler page_handler
|
||||||
|
validate qs:get user v_user
|
||||||
params qs:get / {
|
|
||||||
validate user v_user
|
|
||||||
}
|
}
|
||||||
|
|
||||||
params post /post_back {
|
route /post_back {
|
||||||
validate user v_user
|
handler post_back
|
||||||
|
methods post
|
||||||
|
validate post user v_user
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# Kore as a TLS proxy configuration.
|
# Kore as a TLS proxy configuration.
|
||||||
|
|
||||||
load ./tls-proxy.so
|
load ./tls-proxy.so
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bind the proxy to a given IP and port. For every
|
# Bind the proxy to a given IP and port. For every
|
||||||
|
@ -6,8 +6,6 @@ server tls {
|
|||||||
|
|
||||||
load ./upload.so
|
load ./upload.so
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
http_body_max 1024000000
|
http_body_max 1024000000
|
||||||
http_body_disk_offload 4096
|
http_body_disk_offload 4096
|
||||||
|
|
||||||
@ -17,5 +15,7 @@ domain * {
|
|||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
|
|
||||||
route / page
|
route / {
|
||||||
|
handler page
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,6 @@ server tls {
|
|||||||
|
|
||||||
load ./video_stream.so init
|
load ./video_stream.so init
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
http_keepalive_time 600
|
http_keepalive_time 600
|
||||||
|
|
||||||
domain * {
|
domain * {
|
||||||
@ -17,6 +15,11 @@ domain * {
|
|||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
accesslog access.log
|
accesslog access.log
|
||||||
|
|
||||||
route / asset_serve_video_html
|
route / {
|
||||||
route ^/[a-z]*.[a-z0-9]{3}$ video_stream
|
handler asset_serve_video_html
|
||||||
|
}
|
||||||
|
|
||||||
|
route ^/[a-z]*.[a-z0-9]{3}$ {
|
||||||
|
handler video_stream
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,6 @@ server tls {
|
|||||||
|
|
||||||
load ./websocket.so
|
load ./websocket.so
|
||||||
|
|
||||||
tls_dhparam dh2048.pem
|
|
||||||
|
|
||||||
# Increase workers so connections are spread
|
# Increase workers so connections are spread
|
||||||
# across them to demonstrate WEBSOCKET_BROADCAST_GLOBAL.
|
# across them to demonstrate WEBSOCKET_BROADCAST_GLOBAL.
|
||||||
workers 4
|
workers 4
|
||||||
@ -21,6 +19,11 @@ domain * {
|
|||||||
certfile cert/server.pem
|
certfile cert/server.pem
|
||||||
certkey cert/key.pem
|
certkey cert/key.pem
|
||||||
|
|
||||||
route / page
|
route / {
|
||||||
route /connect page_ws_connect
|
handler page
|
||||||
|
}
|
||||||
|
|
||||||
|
route /connect {
|
||||||
|
handler page_ws_connect
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ int kore_acme_tls_alpn(SSL *, const unsigned char **, unsigned char *,
|
|||||||
const unsigned char *, unsigned int, void *);
|
const unsigned char *, unsigned int, void *);
|
||||||
|
|
||||||
extern char *acme_email;
|
extern char *acme_email;
|
||||||
|
extern int acme_domains;
|
||||||
extern char *acme_provider;
|
extern char *acme_provider;
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#define KORE_DAEMONIZED_HOOK "kore_parent_daemonized"
|
#define KORE_DAEMONIZED_HOOK "kore_parent_daemonized"
|
||||||
|
|
||||||
void kore_seccomp_hook(void);
|
void kore_seccomp_hook(void);
|
||||||
|
void kore_worker_signal(int);
|
||||||
void kore_worker_teardown(void);
|
void kore_worker_teardown(void);
|
||||||
void kore_parent_teardown(void);
|
void kore_parent_teardown(void);
|
||||||
void kore_worker_configure(void);
|
void kore_worker_configure(void);
|
||||||
|
@ -119,7 +119,7 @@ struct http_arg {
|
|||||||
do { \
|
do { \
|
||||||
int err; \
|
int err; \
|
||||||
type nval; \
|
type nval; \
|
||||||
nval = (type)kore_strtonum64(q->s_value, sign, &err); \
|
nval = (type)kore_strtonum64(data, sign, &err); \
|
||||||
if (err != KORE_RESULT_OK) \
|
if (err != KORE_RESULT_OK) \
|
||||||
return (KORE_RESULT_ERROR); \
|
return (KORE_RESULT_ERROR); \
|
||||||
COPY_ARG_TYPE(nval, type); \
|
COPY_ARG_TYPE(nval, type); \
|
||||||
@ -129,7 +129,7 @@ struct http_arg {
|
|||||||
do { \
|
do { \
|
||||||
int err; \
|
int err; \
|
||||||
type nval; \
|
type nval; \
|
||||||
nval = kore_strtodouble(q->s_value, min, max, &err); \
|
nval = kore_strtodouble(data, min, max, &err); \
|
||||||
if (err != KORE_RESULT_OK) \
|
if (err != KORE_RESULT_OK) \
|
||||||
return (KORE_RESULT_ERROR); \
|
return (KORE_RESULT_ERROR); \
|
||||||
COPY_ARG_TYPE(nval, type); \
|
COPY_ARG_TYPE(nval, type); \
|
||||||
@ -139,7 +139,7 @@ struct http_arg {
|
|||||||
do { \
|
do { \
|
||||||
int err; \
|
int err; \
|
||||||
int64_t nval; \
|
int64_t nval; \
|
||||||
nval = kore_strtonum(q->s_value, 10, min, max, &err); \
|
nval = kore_strtonum(data, 10, min, max, &err); \
|
||||||
if (err != KORE_RESULT_OK) \
|
if (err != KORE_RESULT_OK) \
|
||||||
return (KORE_RESULT_ERROR); \
|
return (KORE_RESULT_ERROR); \
|
||||||
COPY_ARG_TYPE(nval, type); \
|
COPY_ARG_TYPE(nval, type); \
|
||||||
@ -159,38 +159,62 @@ struct http_arg {
|
|||||||
COPY_ARG_INT(min, max, type); \
|
COPY_ARG_INT(min, max, type); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define http_argument_type(r, n, so, no, t) \
|
|
||||||
http_argument_get(r, n, so, no, t)
|
|
||||||
|
|
||||||
#define http_argument_get_string(r, n, o) \
|
#define http_argument_get_string(r, n, o) \
|
||||||
http_argument_type(r, n, (void **)o, NULL, HTTP_ARG_TYPE_STRING)
|
http_argument_get(r, n, (void **)o, NULL, HTTP_ARG_TYPE_STRING)
|
||||||
|
|
||||||
#define http_argument_get_byte(r, n, o) \
|
#define http_argument_get_byte(r, n, o) \
|
||||||
http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_BYTE)
|
http_argument_get(r, n, NULL, o, HTTP_ARG_TYPE_BYTE)
|
||||||
|
|
||||||
#define http_argument_get_uint16(r, n, o) \
|
#define http_argument_get_uint16(r, n, o) \
|
||||||
http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_UINT16)
|
http_argument_get(r, n, NULL, o, HTTP_ARG_TYPE_UINT16)
|
||||||
|
|
||||||
#define http_argument_get_int16(r, n, o) \
|
#define http_argument_get_int16(r, n, o) \
|
||||||
http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_INT16)
|
http_argument_get(r, n, NULL, o, HTTP_ARG_TYPE_INT16)
|
||||||
|
|
||||||
#define http_argument_get_uint32(r, n, o) \
|
#define http_argument_get_uint32(r, n, o) \
|
||||||
http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_UINT32)
|
http_argument_get(r, n, NULL, o, HTTP_ARG_TYPE_UINT32)
|
||||||
|
|
||||||
#define http_argument_get_int32(r, n, o) \
|
#define http_argument_get_int32(r, n, o) \
|
||||||
http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_INT32)
|
http_argument_get(r, n, NULL, o, HTTP_ARG_TYPE_INT32)
|
||||||
|
|
||||||
#define http_argument_get_uint64(r, n, o) \
|
#define http_argument_get_uint64(r, n, o) \
|
||||||
http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_UINT64)
|
http_argument_get(r, n, NULL, o, HTTP_ARG_TYPE_UINT64)
|
||||||
|
|
||||||
#define http_argument_get_int64(r, n, o) \
|
#define http_argument_get_int64(r, n, o) \
|
||||||
http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_INT64)
|
http_argument_get(r, n, NULL, o, HTTP_ARG_TYPE_INT64)
|
||||||
|
|
||||||
#define http_argument_get_float(r, n, o) \
|
#define http_argument_get_float(r, n, o) \
|
||||||
http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_FLOAT)
|
http_argument_get(r, n, NULL, o, HTTP_ARG_TYPE_FLOAT)
|
||||||
|
|
||||||
#define http_argument_get_double(r, n, o) \
|
#define http_argument_get_double(r, n, o) \
|
||||||
http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_DOUBLE)
|
http_argument_get(r, n, NULL, o, HTTP_ARG_TYPE_DOUBLE)
|
||||||
|
|
||||||
|
#define http_request_header_byte(r, n, o) \
|
||||||
|
http_request_header_get(r, n, NULL, o, HTTP_ARG_TYPE_BYTE)
|
||||||
|
|
||||||
|
#define http_request_header_uint16(r, n, o) \
|
||||||
|
http_request_header_get(r, n, NULL, o, HTTP_ARG_TYPE_UINT16)
|
||||||
|
|
||||||
|
#define http_request_header_int16(r, n, o) \
|
||||||
|
http_request_header_get(r, n, NULL, o, HTTP_ARG_TYPE_INT16)
|
||||||
|
|
||||||
|
#define http_request_header_uint32(r, n, o) \
|
||||||
|
http_request_header_get(r, n, NULL, o, HTTP_ARG_TYPE_UINT32)
|
||||||
|
|
||||||
|
#define http_request_header_int32(r, n, o) \
|
||||||
|
http_request_header_get(r, n, NULL, o, HTTP_ARG_TYPE_INT32)
|
||||||
|
|
||||||
|
#define http_request_header_uint64(r, n, o) \
|
||||||
|
http_request_header_get(r, n, NULL, o, HTTP_ARG_TYPE_UINT64)
|
||||||
|
|
||||||
|
#define http_request_header_int64(r, n, o) \
|
||||||
|
http_request_header_get(r, n, NULL, o, HTTP_ARG_TYPE_INT64)
|
||||||
|
|
||||||
|
#define http_request_header_float(r, n, o) \
|
||||||
|
http_request_header_get(r, n, NULL, o, HTTP_ARG_TYPE_FLOAT)
|
||||||
|
|
||||||
|
#define http_request_header_double(r, n, o) \
|
||||||
|
http_request_header_get(r, n, NULL, o, HTTP_ARG_TYPE_DOUBLE)
|
||||||
|
|
||||||
struct http_file {
|
struct http_file {
|
||||||
char *name;
|
char *name;
|
||||||
@ -262,13 +286,13 @@ struct http_request {
|
|||||||
struct kore_buf *http_body;
|
struct kore_buf *http_body;
|
||||||
int http_body_fd;
|
int http_body_fd;
|
||||||
char *http_body_path;
|
char *http_body_path;
|
||||||
size_t http_body_length;
|
u_int64_t http_body_length;
|
||||||
size_t http_body_offset;
|
u_int64_t http_body_offset;
|
||||||
size_t content_length;
|
u_int64_t content_length;
|
||||||
void *hdlr_extra;
|
void *hdlr_extra;
|
||||||
size_t state_len;
|
size_t state_len;
|
||||||
char *query_string;
|
char *query_string;
|
||||||
struct kore_module_handle *hdlr;
|
struct kore_route *rt;
|
||||||
struct http_runlock_queue *runlock;
|
struct http_runlock_queue *runlock;
|
||||||
void (*onfree)(struct http_request *);
|
void (*onfree)(struct http_request *);
|
||||||
|
|
||||||
@ -357,6 +381,10 @@ int http_body_digest(struct http_request *, char *, size_t);
|
|||||||
int http_redirect_add(struct kore_domain *,
|
int http_redirect_add(struct kore_domain *,
|
||||||
const char *, int, const char *);
|
const char *, int, const char *);
|
||||||
void http_response(struct http_request *, int, const void *, size_t);
|
void http_response(struct http_request *, int, const void *, size_t);
|
||||||
|
void http_response_json(struct http_request *, int,
|
||||||
|
struct kore_json_item *);
|
||||||
|
void http_response_close(struct http_request *, int,
|
||||||
|
const void *, size_t);
|
||||||
void http_response_fileref(struct http_request *, int,
|
void http_response_fileref(struct http_request *, int,
|
||||||
struct kore_fileref *);
|
struct kore_fileref *);
|
||||||
void http_serveable(struct http_request *, const void *,
|
void http_serveable(struct http_request *, const void *,
|
||||||
@ -385,8 +413,7 @@ const char *http_media_type(const char *);
|
|||||||
void *http_state_get(struct http_request *);
|
void *http_state_get(struct http_request *);
|
||||||
int http_state_exists(struct http_request *);
|
int http_state_exists(struct http_request *);
|
||||||
void http_state_cleanup(struct http_request *);
|
void http_state_cleanup(struct http_request *);
|
||||||
void *http_state_create(struct http_request *, size_t,
|
void *http_state_create(struct http_request *, size_t);
|
||||||
void (*onfree)(struct http_request *));
|
|
||||||
|
|
||||||
int http_argument_urldecode(char *);
|
int http_argument_urldecode(char *);
|
||||||
int http_header_recv(struct netbuf *);
|
int http_header_recv(struct netbuf *);
|
||||||
@ -396,6 +423,8 @@ void http_populate_multipart_form(struct http_request *);
|
|||||||
void http_populate_cookies(struct http_request *);
|
void http_populate_cookies(struct http_request *);
|
||||||
int http_argument_get(struct http_request *,
|
int http_argument_get(struct http_request *,
|
||||||
const char *, void **, void *, int);
|
const char *, void **, void *, int);
|
||||||
|
int http_request_header_get(struct http_request *,
|
||||||
|
const char *, void **, void *, int);
|
||||||
|
|
||||||
void http_file_rewind(struct http_file *);
|
void http_file_rewind(struct http_file *);
|
||||||
ssize_t http_file_read(struct http_file *, void *, size_t);
|
ssize_t http_file_read(struct http_file *, void *, size_t);
|
||||||
|
@ -103,7 +103,8 @@ extern int daemon(int, int);
|
|||||||
|
|
||||||
#define KORE_DOMAINNAME_LEN 255
|
#define KORE_DOMAINNAME_LEN 255
|
||||||
#define KORE_PIDFILE_DEFAULT "kore.pid"
|
#define KORE_PIDFILE_DEFAULT "kore.pid"
|
||||||
#define KORE_DEFAULT_CIPHER_LIST "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!kRSA:!kDSA"
|
#define KORE_DHPARAM_PATH PREFIX "/share/kore/ffdhe4096.pem"
|
||||||
|
#define KORE_DEFAULT_CIPHER_LIST "AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256:AEAD-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256"
|
||||||
|
|
||||||
#if defined(KORE_DEBUG)
|
#if defined(KORE_DEBUG)
|
||||||
#define kore_debug(...) \
|
#define kore_debug(...) \
|
||||||
@ -286,6 +287,9 @@ struct kore_runtime {
|
|||||||
int type;
|
int type;
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
int (*http_request)(void *, struct http_request *);
|
int (*http_request)(void *, struct http_request *);
|
||||||
|
void (*http_request_free)(void *, struct http_request *);
|
||||||
|
void (*http_body_chunk)(void *,
|
||||||
|
struct http_request *, const void *, size_t);
|
||||||
int (*validator)(void *, struct http_request *, const void *);
|
int (*validator)(void *, struct http_request *, const void *);
|
||||||
void (*wsconnect)(void *, struct connection *);
|
void (*wsconnect)(void *, struct connection *);
|
||||||
void (*wsdisconnect)(void *, struct connection *);
|
void (*wsdisconnect)(void *, struct connection *);
|
||||||
@ -294,6 +298,7 @@ struct kore_runtime {
|
|||||||
#endif
|
#endif
|
||||||
void (*execute)(void *);
|
void (*execute)(void *);
|
||||||
int (*onload)(void *, int);
|
int (*onload)(void *, int);
|
||||||
|
void (*signal)(void *, int);
|
||||||
void (*connect)(void *, struct connection *);
|
void (*connect)(void *, struct connection *);
|
||||||
void (*configure)(void *, int, char **);
|
void (*configure)(void *, int, char **);
|
||||||
};
|
};
|
||||||
@ -303,6 +308,37 @@ struct kore_runtime_call {
|
|||||||
struct kore_runtime *runtime;
|
struct kore_runtime *runtime;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !defined(KORE_NO_HTTP)
|
||||||
|
|
||||||
|
struct kore_route_params {
|
||||||
|
char *name;
|
||||||
|
int flags;
|
||||||
|
u_int8_t method;
|
||||||
|
struct kore_validator *validator;
|
||||||
|
|
||||||
|
TAILQ_ENTRY(kore_route_params) list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kore_route {
|
||||||
|
char *path;
|
||||||
|
char *func;
|
||||||
|
int type;
|
||||||
|
int errors;
|
||||||
|
int methods;
|
||||||
|
regex_t rctx;
|
||||||
|
struct kore_domain *dom;
|
||||||
|
struct kore_auth *auth;
|
||||||
|
struct kore_runtime_call *rcall;
|
||||||
|
struct kore_runtime_call *on_free;
|
||||||
|
struct kore_runtime_call *on_headers;
|
||||||
|
struct kore_runtime_call *on_body_chunk;
|
||||||
|
|
||||||
|
TAILQ_HEAD(, kore_route_params) params;
|
||||||
|
TAILQ_ENTRY(kore_route) list;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
struct kore_domain {
|
struct kore_domain {
|
||||||
u_int16_t id;
|
u_int16_t id;
|
||||||
int logerr;
|
int logerr;
|
||||||
@ -326,7 +362,7 @@ struct kore_domain {
|
|||||||
SSL_CTX *ssl_ctx;
|
SSL_CTX *ssl_ctx;
|
||||||
int x509_verify_depth;
|
int x509_verify_depth;
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
TAILQ_HEAD(, kore_module_handle) handlers;
|
TAILQ_HEAD(, kore_route) routes;
|
||||||
TAILQ_HEAD(, http_redirect) redirects;
|
TAILQ_HEAD(, http_redirect) redirects;
|
||||||
#endif
|
#endif
|
||||||
TAILQ_ENTRY(kore_domain) list;
|
TAILQ_ENTRY(kore_domain) list;
|
||||||
@ -362,15 +398,6 @@ LIST_HEAD(kore_server_list, kore_server);
|
|||||||
|
|
||||||
#define KORE_PARAMS_QUERY_STRING 0x0001
|
#define KORE_PARAMS_QUERY_STRING 0x0001
|
||||||
|
|
||||||
struct kore_handler_params {
|
|
||||||
char *name;
|
|
||||||
int flags;
|
|
||||||
u_int8_t method;
|
|
||||||
struct kore_validator *validator;
|
|
||||||
|
|
||||||
TAILQ_ENTRY(kore_handler_params) list;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define KORE_AUTH_TYPE_COOKIE 1
|
#define KORE_AUTH_TYPE_COOKIE 1
|
||||||
#define KORE_AUTH_TYPE_HEADER 2
|
#define KORE_AUTH_TYPE_HEADER 2
|
||||||
#define KORE_AUTH_TYPE_REQUEST 3
|
#define KORE_AUTH_TYPE_REQUEST 3
|
||||||
@ -419,23 +446,6 @@ struct kore_module {
|
|||||||
TAILQ_ENTRY(kore_module) list;
|
TAILQ_ENTRY(kore_module) list;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
|
||||||
|
|
||||||
struct kore_module_handle {
|
|
||||||
char *path;
|
|
||||||
char *func;
|
|
||||||
int type;
|
|
||||||
int errors;
|
|
||||||
regex_t rctx;
|
|
||||||
struct kore_domain *dom;
|
|
||||||
struct kore_runtime_call *rcall;
|
|
||||||
struct kore_auth *auth;
|
|
||||||
int methods;
|
|
||||||
TAILQ_HEAD(, kore_handler_params) params;
|
|
||||||
TAILQ_ENTRY(kore_module_handle) list;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The workers get a 128KB log buffer per worker, and parent will fetch their
|
* The workers get a 128KB log buffer per worker, and parent will fetch their
|
||||||
* logs when it reached at least 75% of that or if its been > 1 second since
|
* logs when it reached at least 75% of that or if its been > 1 second since
|
||||||
@ -449,9 +459,17 @@ struct kore_alog_header {
|
|||||||
u_int16_t loglen;
|
u_int16_t loglen;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct kore_privsep {
|
||||||
|
char *root;
|
||||||
|
char *runas;
|
||||||
|
int skip_runas;
|
||||||
|
int skip_chroot;
|
||||||
|
};
|
||||||
|
|
||||||
struct kore_worker {
|
struct kore_worker {
|
||||||
u_int16_t id;
|
u_int16_t id;
|
||||||
u_int16_t cpu;
|
u_int16_t cpu;
|
||||||
|
int ready;
|
||||||
int running;
|
int running;
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
int tracing;
|
int tracing;
|
||||||
@ -462,7 +480,8 @@ struct kore_worker {
|
|||||||
u_int8_t has_lock;
|
u_int8_t has_lock;
|
||||||
int restarted;
|
int restarted;
|
||||||
u_int64_t time_locked;
|
u_int64_t time_locked;
|
||||||
struct kore_module_handle *active_hdlr;
|
struct kore_route *active_route;
|
||||||
|
struct kore_privsep *ps;
|
||||||
|
|
||||||
/* Used by the workers to store accesslogs. */
|
/* Used by the workers to store accesslogs. */
|
||||||
struct {
|
struct {
|
||||||
@ -570,7 +589,6 @@ struct kore_buf {
|
|||||||
struct kore_json {
|
struct kore_json {
|
||||||
const u_int8_t *data;
|
const u_int8_t *data;
|
||||||
int depth;
|
int depth;
|
||||||
int error;
|
|
||||||
size_t length;
|
size_t length;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
|
|
||||||
@ -588,7 +606,7 @@ struct kore_json_item {
|
|||||||
char *string;
|
char *string;
|
||||||
double number;
|
double number;
|
||||||
int literal;
|
int literal;
|
||||||
int64_t s64;
|
int64_t integer;
|
||||||
u_int64_t u64;
|
u_int64_t u64;
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
@ -659,6 +677,7 @@ struct kore_timer {
|
|||||||
#define KORE_MSG_CRL 9
|
#define KORE_MSG_CRL 9
|
||||||
#define KORE_MSG_ACCEPT_AVAILABLE 10
|
#define KORE_MSG_ACCEPT_AVAILABLE 10
|
||||||
#define KORE_PYTHON_SEND_OBJ 11
|
#define KORE_PYTHON_SEND_OBJ 11
|
||||||
|
#define KORE_MSG_WORKER_LOG 12
|
||||||
#define KORE_MSG_ACME_BASE 100
|
#define KORE_MSG_ACME_BASE 100
|
||||||
|
|
||||||
/* messages for applications should start at 201. */
|
/* messages for applications should start at 201. */
|
||||||
@ -693,6 +712,7 @@ extern char *config_file;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern pid_t kore_pid;
|
extern pid_t kore_pid;
|
||||||
|
extern int kore_quit;
|
||||||
extern int kore_quiet;
|
extern int kore_quiet;
|
||||||
extern int kore_debug;
|
extern int kore_debug;
|
||||||
extern int skip_chroot;
|
extern int skip_chroot;
|
||||||
@ -700,8 +720,6 @@ extern int skip_runas;
|
|||||||
extern int kore_foreground;
|
extern int kore_foreground;
|
||||||
|
|
||||||
extern char *kore_pidfile;
|
extern char *kore_pidfile;
|
||||||
extern char *kore_root_path;
|
|
||||||
extern char *kore_runas_user;
|
|
||||||
extern char *kore_tls_cipher_list;
|
extern char *kore_tls_cipher_list;
|
||||||
|
|
||||||
extern volatile sig_atomic_t sig_recv;
|
extern volatile sig_atomic_t sig_recv;
|
||||||
@ -710,15 +728,16 @@ extern int tls_version;
|
|||||||
extern DH *tls_dhparam;
|
extern DH *tls_dhparam;
|
||||||
extern char *rand_file;
|
extern char *rand_file;
|
||||||
extern int keymgr_active;
|
extern int keymgr_active;
|
||||||
extern char *keymgr_runas_user;
|
|
||||||
extern char *keymgr_root_path;
|
extern struct kore_privsep worker_privsep;
|
||||||
extern char *acme_runas_user;
|
extern struct kore_privsep keymgr_privsep;
|
||||||
extern char *acme_root_path;
|
extern struct kore_privsep acme_privsep;
|
||||||
|
|
||||||
extern u_int8_t nlisteners;
|
extern u_int8_t nlisteners;
|
||||||
extern u_int16_t cpu_count;
|
extern u_int16_t cpu_count;
|
||||||
extern u_int8_t worker_count;
|
extern u_int8_t worker_count;
|
||||||
extern const char *kore_version;
|
extern const char *kore_version;
|
||||||
|
extern const char *kore_build_date;
|
||||||
extern int worker_policy;
|
extern int worker_policy;
|
||||||
extern u_int8_t worker_set_affinity;
|
extern u_int8_t worker_set_affinity;
|
||||||
extern u_int32_t worker_rlimit_nofiles;
|
extern u_int32_t worker_rlimit_nofiles;
|
||||||
@ -736,17 +755,19 @@ extern struct kore_server_list kore_servers;
|
|||||||
|
|
||||||
void kore_signal(int);
|
void kore_signal(int);
|
||||||
void kore_shutdown(void);
|
void kore_shutdown(void);
|
||||||
|
void kore_signal_trap(int);
|
||||||
void kore_signal_setup(void);
|
void kore_signal_setup(void);
|
||||||
void kore_proctitle(const char *);
|
void kore_proctitle(const char *);
|
||||||
void kore_default_getopt(int, char **);
|
void kore_default_getopt(int, char **);
|
||||||
|
|
||||||
void kore_worker_reap(void);
|
void kore_worker_reap(void);
|
||||||
void kore_worker_init(void);
|
int kore_worker_init(void);
|
||||||
|
void kore_worker_privsep(void);
|
||||||
|
void kore_worker_started(void);
|
||||||
void kore_worker_make_busy(void);
|
void kore_worker_make_busy(void);
|
||||||
void kore_worker_shutdown(void);
|
void kore_worker_shutdown(void);
|
||||||
void kore_worker_dispatch_signal(int);
|
void kore_worker_dispatch_signal(int);
|
||||||
void kore_worker_privdrop(const char *, const char *);
|
int kore_worker_spawn(u_int16_t, u_int16_t, u_int16_t);
|
||||||
void kore_worker_spawn(u_int16_t, u_int16_t, u_int16_t);
|
|
||||||
int kore_worker_keymgr_response_verify(struct kore_msg *,
|
int kore_worker_keymgr_response_verify(struct kore_msg *,
|
||||||
const void *, struct kore_domain **);
|
const void *, struct kore_domain **);
|
||||||
|
|
||||||
@ -845,6 +866,7 @@ int kore_connection_accept(struct listener *,
|
|||||||
|
|
||||||
u_int64_t kore_time_ms(void);
|
u_int64_t kore_time_ms(void);
|
||||||
void kore_log_init(void);
|
void kore_log_init(void);
|
||||||
|
void kore_log_file(const char *);
|
||||||
|
|
||||||
#if defined(KORE_USE_PYTHON)
|
#if defined(KORE_USE_PYTHON)
|
||||||
int kore_configure_setting(const char *, char *);
|
int kore_configure_setting(const char *, char *);
|
||||||
@ -892,7 +914,11 @@ char *kore_read_line(FILE *, char *, size_t);
|
|||||||
|
|
||||||
EVP_PKEY *kore_rsakey_load(const char *);
|
EVP_PKEY *kore_rsakey_load(const char *);
|
||||||
EVP_PKEY *kore_rsakey_generate(const char *);
|
EVP_PKEY *kore_rsakey_generate(const char *);
|
||||||
|
int kore_x509_issuer_name(struct connection *, char **, int);
|
||||||
int kore_x509_subject_name(struct connection *, char **, int);
|
int kore_x509_subject_name(struct connection *, char **, int);
|
||||||
|
int kore_x509name_foreach(X509_NAME *, int, void *,
|
||||||
|
int (*)(void *, int, int, const char *,
|
||||||
|
const void *, size_t, int));
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
void kore_websocket_handshake(struct http_request *,
|
void kore_websocket_handshake(struct http_request *,
|
||||||
@ -948,12 +974,16 @@ int kore_domain_attach(struct kore_domain *, struct kore_server *);
|
|||||||
void kore_domain_tlsinit(struct kore_domain *, int,
|
void kore_domain_tlsinit(struct kore_domain *, int,
|
||||||
const void *, size_t);
|
const void *, size_t);
|
||||||
void kore_domain_crl_add(struct kore_domain *, const void *, size_t);
|
void kore_domain_crl_add(struct kore_domain *, const void *, size_t);
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
int kore_module_handler_new(struct kore_domain *, const char *,
|
void kore_route_reload(void);
|
||||||
const char *, const char *, int);
|
void kore_route_free(struct kore_route *);
|
||||||
void kore_module_handler_free(struct kore_module_handle *);
|
void kore_route_callback(struct kore_route *, const char *);
|
||||||
struct kore_module_handle *kore_module_handler_find(struct http_request *,
|
|
||||||
struct kore_domain *);
|
struct kore_route *kore_route_create(struct kore_domain *,
|
||||||
|
const char *, int);
|
||||||
|
int kore_route_lookup(struct http_request *,
|
||||||
|
struct kore_domain *, int, struct kore_route **);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct kore_runtime_call *kore_runtime_getcall(const char *);
|
struct kore_runtime_call *kore_runtime_getcall(const char *);
|
||||||
@ -962,11 +992,16 @@ struct kore_module *kore_module_load(const char *,
|
|||||||
|
|
||||||
void kore_runtime_execute(struct kore_runtime_call *);
|
void kore_runtime_execute(struct kore_runtime_call *);
|
||||||
int kore_runtime_onload(struct kore_runtime_call *, int);
|
int kore_runtime_onload(struct kore_runtime_call *, int);
|
||||||
|
void kore_runtime_signal(struct kore_runtime_call *, int);
|
||||||
void kore_runtime_configure(struct kore_runtime_call *, int, char **);
|
void kore_runtime_configure(struct kore_runtime_call *, int, char **);
|
||||||
void kore_runtime_connect(struct kore_runtime_call *, struct connection *);
|
void kore_runtime_connect(struct kore_runtime_call *, struct connection *);
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
int kore_runtime_http_request(struct kore_runtime_call *,
|
int kore_runtime_http_request(struct kore_runtime_call *,
|
||||||
struct http_request *);
|
struct http_request *);
|
||||||
|
void kore_runtime_http_request_free(struct kore_runtime_call *,
|
||||||
|
struct http_request *);
|
||||||
|
void kore_runtime_http_body_chunk(struct kore_runtime_call *,
|
||||||
|
struct http_request *, const void *, size_t);
|
||||||
int kore_runtime_validator(struct kore_runtime_call *,
|
int kore_runtime_validator(struct kore_runtime_call *,
|
||||||
struct http_request *, const void *);
|
struct http_request *, const void *);
|
||||||
void kore_runtime_wsconnect(struct kore_runtime_call *, struct connection *);
|
void kore_runtime_wsconnect(struct kore_runtime_call *, struct connection *);
|
||||||
@ -1038,13 +1073,15 @@ void kore_buf_appendv(struct kore_buf *, const char *, va_list);
|
|||||||
void kore_buf_replace_string(struct kore_buf *,
|
void kore_buf_replace_string(struct kore_buf *,
|
||||||
const char *, const void *, size_t);
|
const char *, const void *, size_t);
|
||||||
|
|
||||||
|
int kore_json_errno(void);
|
||||||
int kore_json_parse(struct kore_json *);
|
int kore_json_parse(struct kore_json *);
|
||||||
void kore_json_cleanup(struct kore_json *);
|
void kore_json_cleanup(struct kore_json *);
|
||||||
void kore_json_item_free(struct kore_json_item *);
|
void kore_json_item_free(struct kore_json_item *);
|
||||||
void kore_json_init(struct kore_json *, const void *, size_t);
|
void kore_json_init(struct kore_json *, const void *, size_t);
|
||||||
void kore_json_item_tobuf(struct kore_json_item *, struct kore_buf *);
|
void kore_json_item_tobuf(struct kore_json_item *, struct kore_buf *);
|
||||||
|
void kore_json_item_attach(struct kore_json_item *, struct kore_json_item *);
|
||||||
|
|
||||||
const char *kore_json_strerror(struct kore_json *);
|
const char *kore_json_strerror(void);
|
||||||
struct kore_json_item *kore_json_find(struct kore_json_item *,
|
struct kore_json_item *kore_json_find(struct kore_json_item *,
|
||||||
const char *, u_int32_t);
|
const char *, u_int32_t);
|
||||||
struct kore_json_item *kore_json_create_item(struct kore_json_item *,
|
struct kore_json_item *kore_json_create_item(struct kore_json_item *,
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#undef _POSIX_C_SOURCE
|
#undef _POSIX_C_SOURCE
|
||||||
#undef _XOPEN_SOURCE
|
#undef _XOPEN_SOURCE
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN 1
|
||||||
|
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <frameobject.h>
|
#include <frameobject.h>
|
||||||
|
|
||||||
@ -32,6 +34,7 @@ void kore_python_proc_reap(void);
|
|||||||
int kore_python_coro_pending(void);
|
int kore_python_coro_pending(void);
|
||||||
void kore_python_path(const char *);
|
void kore_python_path(const char *);
|
||||||
void kore_python_coro_delete(void *);
|
void kore_python_coro_delete(void *);
|
||||||
|
void kore_python_routes_resolve(void);
|
||||||
void kore_python_log_error(const char *);
|
void kore_python_log_error(const char *);
|
||||||
|
|
||||||
PyObject *kore_python_callable(PyObject *, const char *);
|
PyObject *kore_python_callable(PyObject *, const char *);
|
||||||
@ -48,8 +51,11 @@ extern const char *kore_pymodule;
|
|||||||
extern struct kore_module_functions kore_python_module;
|
extern struct kore_module_functions kore_python_module;
|
||||||
extern struct kore_runtime kore_python_runtime;
|
extern struct kore_runtime kore_python_runtime;
|
||||||
|
|
||||||
|
#define KORE_PYTHON_SIGNAL_HOOK "koreapp.signal"
|
||||||
#define KORE_PYTHON_TEARDOWN_HOOK "koreapp.cleanup"
|
#define KORE_PYTHON_TEARDOWN_HOOK "koreapp.cleanup"
|
||||||
#define KORE_PYTHON_CONFIG_HOOK "koreapp.configure"
|
#define KORE_PYTHON_CONFIG_HOOK "koreapp.configure"
|
||||||
#define KORE_PYTHON_DAEMONIZED_HOOK "koreapp.daemonized"
|
#define KORE_PYTHON_DAEMONIZED_HOOK "koreapp.daemonized"
|
||||||
|
#define KORE_PYTHON_WORKER_STOP_HOOK "koreapp.workerstop"
|
||||||
|
#define KORE_PYTHON_WORKER_START_HOOK "koreapp.workerstart"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#define CORO_STATE_SUSPENDED 2
|
#define CORO_STATE_SUSPENDED 2
|
||||||
|
|
||||||
struct python_coro {
|
struct python_coro {
|
||||||
u_int32_t id;
|
u_int64_t id;
|
||||||
int state;
|
int state;
|
||||||
int killed;
|
int killed;
|
||||||
PyObject *obj;
|
PyObject *obj;
|
||||||
@ -45,6 +45,8 @@ static PyObject *python_kore_queue(PyObject *, PyObject *);
|
|||||||
static PyObject *python_kore_worker(PyObject *, PyObject *);
|
static PyObject *python_kore_worker(PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_tracer(PyObject *, PyObject *);
|
static PyObject *python_kore_tracer(PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_fatalx(PyObject *, PyObject *);
|
static PyObject *python_kore_fatalx(PyObject *, PyObject *);
|
||||||
|
static PyObject *python_kore_task_id(PyObject *, PyObject *);
|
||||||
|
static PyObject *python_kore_sigtrap(PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_setname(PyObject *, PyObject *);
|
static PyObject *python_kore_setname(PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_suspend(PyObject *, PyObject *);
|
static PyObject *python_kore_suspend(PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_shutdown(PyObject *, PyObject *);
|
static PyObject *python_kore_shutdown(PyObject *, PyObject *);
|
||||||
@ -54,6 +56,7 @@ static PyObject *python_kore_task_kill(PyObject *, PyObject *);
|
|||||||
static PyObject *python_kore_prerequest(PyObject *, PyObject *);
|
static PyObject *python_kore_prerequest(PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_task_create(PyObject *, PyObject *);
|
static PyObject *python_kore_task_create(PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_socket_wrap(PyObject *, PyObject *);
|
static PyObject *python_kore_socket_wrap(PyObject *, PyObject *);
|
||||||
|
static PyObject *python_kore_route(PyObject *, PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_timer(PyObject *, PyObject *, PyObject *);
|
static PyObject *python_kore_timer(PyObject *, PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_domain(PyObject *, PyObject *, PyObject *);
|
static PyObject *python_kore_domain(PyObject *, PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_gather(PyObject *, PyObject *, PyObject *);
|
static PyObject *python_kore_gather(PyObject *, PyObject *, PyObject *);
|
||||||
@ -61,6 +64,9 @@ static PyObject *python_kore_sendobj(PyObject *, PyObject *,
|
|||||||
PyObject *);
|
PyObject *);
|
||||||
static PyObject *python_kore_server(PyObject *, PyObject *,
|
static PyObject *python_kore_server(PyObject *, PyObject *,
|
||||||
PyObject *);
|
PyObject *);
|
||||||
|
static PyObject *python_kore_privsep(PyObject *, PyObject *,
|
||||||
|
PyObject *);
|
||||||
|
|
||||||
|
|
||||||
#if defined(KORE_USE_PGSQL)
|
#if defined(KORE_USE_PGSQL)
|
||||||
static PyObject *python_kore_pgsql_query(PyObject *, PyObject *,
|
static PyObject *python_kore_pgsql_query(PyObject *, PyObject *,
|
||||||
@ -92,6 +98,8 @@ static struct PyMethodDef pykore_methods[] = {
|
|||||||
METHOD("tracer", python_kore_tracer, METH_VARARGS),
|
METHOD("tracer", python_kore_tracer, METH_VARARGS),
|
||||||
METHOD("fatal", python_kore_fatal, METH_VARARGS),
|
METHOD("fatal", python_kore_fatal, METH_VARARGS),
|
||||||
METHOD("fatalx", python_kore_fatalx, METH_VARARGS),
|
METHOD("fatalx", python_kore_fatalx, METH_VARARGS),
|
||||||
|
METHOD("task_id", python_kore_task_id, METH_NOARGS),
|
||||||
|
METHOD("sigtrap", python_kore_sigtrap, METH_VARARGS),
|
||||||
METHOD("setname", python_kore_setname, METH_VARARGS),
|
METHOD("setname", python_kore_setname, METH_VARARGS),
|
||||||
METHOD("suspend", python_kore_suspend, METH_VARARGS),
|
METHOD("suspend", python_kore_suspend, METH_VARARGS),
|
||||||
METHOD("shutdown", python_kore_shutdown, METH_NOARGS),
|
METHOD("shutdown", python_kore_shutdown, METH_NOARGS),
|
||||||
@ -101,10 +109,12 @@ static struct PyMethodDef pykore_methods[] = {
|
|||||||
METHOD("prerequest", python_kore_prerequest, METH_VARARGS),
|
METHOD("prerequest", python_kore_prerequest, METH_VARARGS),
|
||||||
METHOD("task_create", python_kore_task_create, METH_VARARGS),
|
METHOD("task_create", python_kore_task_create, METH_VARARGS),
|
||||||
METHOD("socket_wrap", python_kore_socket_wrap, METH_VARARGS),
|
METHOD("socket_wrap", python_kore_socket_wrap, METH_VARARGS),
|
||||||
|
METHOD("route", python_kore_route, METH_VARARGS | METH_KEYWORDS),
|
||||||
METHOD("timer", python_kore_timer, METH_VARARGS | METH_KEYWORDS),
|
METHOD("timer", python_kore_timer, METH_VARARGS | METH_KEYWORDS),
|
||||||
|
METHOD("domain", python_kore_domain, METH_VARARGS | METH_KEYWORDS),
|
||||||
METHOD("server", python_kore_server, METH_VARARGS | METH_KEYWORDS),
|
METHOD("server", python_kore_server, METH_VARARGS | METH_KEYWORDS),
|
||||||
METHOD("gather", python_kore_gather, METH_VARARGS | METH_KEYWORDS),
|
METHOD("gather", python_kore_gather, METH_VARARGS | METH_KEYWORDS),
|
||||||
METHOD("domain", python_kore_domain, METH_VARARGS | METH_KEYWORDS),
|
METHOD("privsep", python_kore_privsep, METH_VARARGS | METH_KEYWORDS),
|
||||||
METHOD("sendobj", python_kore_sendobj, METH_VARARGS | METH_KEYWORDS),
|
METHOD("sendobj", python_kore_sendobj, METH_VARARGS | METH_KEYWORDS),
|
||||||
METHOD("websocket_broadcast", python_websocket_broadcast, METH_VARARGS),
|
METHOD("websocket_broadcast", python_websocket_broadcast, METH_VARARGS),
|
||||||
#if defined(KORE_USE_PGSQL)
|
#if defined(KORE_USE_PGSQL)
|
||||||
@ -186,9 +196,38 @@ static PyTypeObject pyseccomp_type = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct pyroute {
|
||||||
|
PyObject_HEAD
|
||||||
|
char *path;
|
||||||
|
PyObject *func;
|
||||||
|
PyObject *kwargs;
|
||||||
|
struct kore_domain *domain;
|
||||||
|
TAILQ_ENTRY(pyroute) list;
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyObject *pyroute_inner(struct pyroute *, PyObject *);
|
||||||
|
static void pyroute_dealloc(struct pyroute *);
|
||||||
|
|
||||||
|
static PyMethodDef pyroute_methods[] = {
|
||||||
|
METHOD("inner", pyroute_inner, METH_VARARGS),
|
||||||
|
METHOD(NULL, NULL, -1)
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyTypeObject pyroute_type = {
|
||||||
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
|
.tp_name = "kore.route",
|
||||||
|
.tp_doc = "kore route function",
|
||||||
|
.tp_methods = pyroute_methods,
|
||||||
|
.tp_basicsize = sizeof(struct pyroute),
|
||||||
|
.tp_dealloc = (destructor)pyroute_dealloc,
|
||||||
|
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||||
|
};
|
||||||
|
|
||||||
struct pydomain {
|
struct pydomain {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
struct kore_domain *config;
|
struct kore_domain *config;
|
||||||
|
struct kore_module_handle *next;
|
||||||
|
PyObject *kwargs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *pydomain_filemaps(struct pydomain *, PyObject *);
|
static PyObject *pydomain_filemaps(struct pydomain *, PyObject *);
|
||||||
@ -659,11 +698,13 @@ static PyObject *pyconnection_get_fd(struct pyconnection *, void *);
|
|||||||
static PyObject *pyconnection_get_addr(struct pyconnection *, void *);
|
static PyObject *pyconnection_get_addr(struct pyconnection *, void *);
|
||||||
|
|
||||||
static PyObject *pyconnection_get_peer_x509(struct pyconnection *, void *);
|
static PyObject *pyconnection_get_peer_x509(struct pyconnection *, void *);
|
||||||
|
static PyObject *pyconnection_get_peer_x509dict(struct pyconnection *, void *);
|
||||||
|
|
||||||
static PyGetSetDef pyconnection_getset[] = {
|
static PyGetSetDef pyconnection_getset[] = {
|
||||||
GETTER("fd", pyconnection_get_fd),
|
GETTER("fd", pyconnection_get_fd),
|
||||||
GETTER("addr", pyconnection_get_addr),
|
GETTER("addr", pyconnection_get_addr),
|
||||||
GETTER("x509", pyconnection_get_peer_x509),
|
GETTER("x509", pyconnection_get_peer_x509),
|
||||||
|
GETTER("x509dict", pyconnection_get_peer_x509dict),
|
||||||
GETTER(NULL, NULL),
|
GETTER(NULL, NULL),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -741,8 +782,10 @@ static PyObject *pyhttp_get_path(struct pyhttp_request *, void *);
|
|||||||
static PyObject *pyhttp_get_body(struct pyhttp_request *, void *);
|
static PyObject *pyhttp_get_body(struct pyhttp_request *, void *);
|
||||||
static PyObject *pyhttp_get_agent(struct pyhttp_request *, void *);
|
static PyObject *pyhttp_get_agent(struct pyhttp_request *, void *);
|
||||||
static PyObject *pyhttp_get_method(struct pyhttp_request *, void *);
|
static PyObject *pyhttp_get_method(struct pyhttp_request *, void *);
|
||||||
|
static PyObject *pyhttp_get_protocol(struct pyhttp_request *, void *);
|
||||||
static PyObject *pyhttp_get_body_path(struct pyhttp_request *, void *);
|
static PyObject *pyhttp_get_body_path(struct pyhttp_request *, void *);
|
||||||
static PyObject *pyhttp_get_connection(struct pyhttp_request *, void *);
|
static PyObject *pyhttp_get_connection(struct pyhttp_request *, void *);
|
||||||
|
static PyObject *pyhttp_get_body_digest(struct pyhttp_request *, void *);
|
||||||
|
|
||||||
static PyGetSetDef pyhttp_request_getset[] = {
|
static PyGetSetDef pyhttp_request_getset[] = {
|
||||||
GETTER("host", pyhttp_get_host),
|
GETTER("host", pyhttp_get_host),
|
||||||
@ -750,7 +793,9 @@ static PyGetSetDef pyhttp_request_getset[] = {
|
|||||||
GETTER("body", pyhttp_get_body),
|
GETTER("body", pyhttp_get_body),
|
||||||
GETTER("agent", pyhttp_get_agent),
|
GETTER("agent", pyhttp_get_agent),
|
||||||
GETTER("method", pyhttp_get_method),
|
GETTER("method", pyhttp_get_method),
|
||||||
|
GETTER("protocol", pyhttp_get_protocol),
|
||||||
GETTER("body_path", pyhttp_get_body_path),
|
GETTER("body_path", pyhttp_get_body_path),
|
||||||
|
GETTER("body_digest", pyhttp_get_body_digest),
|
||||||
GETTER("connection", pyhttp_get_connection),
|
GETTER("connection", pyhttp_get_connection),
|
||||||
GETTER(NULL, NULL)
|
GETTER(NULL, NULL)
|
||||||
};
|
};
|
||||||
@ -806,12 +851,16 @@ struct pycurl_slist {
|
|||||||
LIST_ENTRY(pycurl_slist) list;
|
LIST_ENTRY(pycurl_slist) list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct pycurl_data {
|
||||||
|
struct kore_curl curl;
|
||||||
|
LIST_HEAD(, pycurl_slist) slists;
|
||||||
|
};
|
||||||
|
|
||||||
struct pycurl_handle {
|
struct pycurl_handle {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
struct kore_curl curl;
|
|
||||||
char *url;
|
char *url;
|
||||||
struct kore_buf *body;
|
struct kore_buf *body;
|
||||||
LIST_HEAD(, pycurl_slist) slists;
|
struct pycurl_data data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pycurl_handle_op {
|
struct pycurl_handle_op {
|
||||||
@ -831,11 +880,11 @@ static PyObject *pycurl_handle_run(struct pycurl_handle *, PyObject *);
|
|||||||
static PyObject *pycurl_handle_setopt(struct pycurl_handle *, PyObject *);
|
static PyObject *pycurl_handle_setopt(struct pycurl_handle *, PyObject *);
|
||||||
static PyObject *pycurl_handle_setbody(struct pycurl_handle *, PyObject *);
|
static PyObject *pycurl_handle_setbody(struct pycurl_handle *, PyObject *);
|
||||||
|
|
||||||
static PyObject *pycurl_handle_setopt_string(struct pycurl_handle *,
|
static PyObject *pycurl_handle_setopt_string(struct pycurl_data *,
|
||||||
int, PyObject *);
|
int, PyObject *);
|
||||||
static PyObject *pycurl_handle_setopt_long(struct pycurl_handle *,
|
static PyObject *pycurl_handle_setopt_long(struct pycurl_data *,
|
||||||
int, PyObject *);
|
int, PyObject *);
|
||||||
static PyObject *pycurl_handle_setopt_slist(struct pycurl_handle *,
|
static PyObject *pycurl_handle_setopt_slist(struct pycurl_data *,
|
||||||
int, PyObject *);
|
int, PyObject *);
|
||||||
|
|
||||||
static PyMethodDef pycurl_handle_methods[] = {
|
static PyMethodDef pycurl_handle_methods[] = {
|
||||||
@ -879,6 +928,7 @@ struct pyhttp_client {
|
|||||||
char *tlskey;
|
char *tlskey;
|
||||||
char *tlscert;
|
char *tlscert;
|
||||||
char *cabundle;
|
char *cabundle;
|
||||||
|
PyObject *curlopt;
|
||||||
int tlsverify;
|
int tlsverify;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -886,11 +936,12 @@ struct pyhttp_client_op {
|
|||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
int state;
|
int state;
|
||||||
int headers;
|
int headers;
|
||||||
struct kore_curl curl;
|
|
||||||
struct python_coro *coro;
|
struct python_coro *coro;
|
||||||
struct pyhttp_client *client;
|
struct pyhttp_client *client;
|
||||||
|
struct pycurl_data data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static PyObject *pyhttp_client_op_await(PyObject *);
|
static PyObject *pyhttp_client_op_await(PyObject *);
|
||||||
static PyObject *pyhttp_client_op_iternext(struct pyhttp_client_op *);
|
static PyObject *pyhttp_client_op_iternext(struct pyhttp_client_op *);
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@
|
|||||||
* KORE_SYSCALL_DENY_ERRNO(socket, EACCESS),
|
* KORE_SYSCALL_DENY_ERRNO(socket, EACCESS),
|
||||||
* KORE_SYSCALL_DENY_ERRNO(ioctl, EACCESS),
|
* KORE_SYSCALL_DENY_ERRNO(ioctl, EACCESS),
|
||||||
* KORE_SYSCALL_ALLOW(poll),
|
* KORE_SYSCALL_ALLOW(poll),
|
||||||
* );
|
* )
|
||||||
*/
|
*/
|
||||||
#define KORE_SECCOMP_FILTER(name, ...) \
|
#define KORE_SECCOMP_FILTER(name, ...) \
|
||||||
struct sock_filter _scfilt[] = { \
|
struct sock_filter _scfilt[] = { \
|
||||||
|
@ -28,8 +28,8 @@ endif
|
|||||||
|
|
||||||
OSNAME=$(shell uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
|
OSNAME=$(shell uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
|
||||||
ifeq ("$(OSNAME)", "darwin")
|
ifeq ("$(OSNAME)", "darwin")
|
||||||
CFLAGS+=-I/opt/local/include/ -I/usr/local/opt/openssl/include
|
CFLAGS+=$(shell pkg-config openssl --cflags)
|
||||||
LDFLAGS+=-L/opt/local/lib -L/usr/local/opt/openssl/lib
|
LDFLAGS+=$(shell pkg-config openssl --libs)
|
||||||
else ifeq ("$(OSNAME)", "linux")
|
else ifeq ("$(OSNAME)", "linux")
|
||||||
CFLAGS+=-D_GNU_SOURCE=1
|
CFLAGS+=-D_GNU_SOURCE=1
|
||||||
endif
|
endif
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
struct {
|
struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
int value;
|
int value;
|
||||||
PyObject *(*cb)(struct pycurl_handle *, int, PyObject *);
|
PyObject *(*cb)(struct pycurl_data *, int, PyObject *);
|
||||||
} py_curlopt[] = {
|
} py_curlopt[] = {
|
||||||
{ "CURLOPT_WRITEDATA", 1, NULL },
|
{ "CURLOPT_WRITEDATA", 1, NULL },
|
||||||
{ "CURLOPT_URL", 2, pycurl_handle_setopt_string },
|
{ "CURLOPT_URL", 2, pycurl_handle_setopt_string },
|
||||||
|
13
misc/ffdhe4096.pem
Normal file
13
misc/ffdhe4096.pem
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
-----BEGIN DH PARAMETERS-----
|
||||||
|
MIICCAKCAgEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
||||||
|
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
||||||
|
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
||||||
|
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
||||||
|
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
||||||
|
ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3
|
||||||
|
7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32
|
||||||
|
nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZp4e
|
||||||
|
8W5vUsMWTfT7eTDp5OWIV7asfV9C1p9tGHdjzx1VA0AEh/VbpX4xzHpxNciG77Qx
|
||||||
|
iu1qHgEtnmgyqQdgCpGBMMRtx3j5ca0AOAkpmaMzy4t6Gh25PXFAADwqTs6p+Y0K
|
||||||
|
zAqCkc3OyX3Pjsm1Wn+IpGtNtahR9EGC4caKAH5eZV9q//////////8CAQI=
|
||||||
|
-----END DH PARAMETERS-----
|
@ -2,7 +2,12 @@
|
|||||||
#
|
#
|
||||||
# Linux specific defines and system call maps.
|
# Linux specific defines and system call maps.
|
||||||
|
|
||||||
PLATFORM=$(uname -m)
|
if [ -z "$TARGET_PLATFORM" ]; then
|
||||||
|
PLATFORM=$(uname -m)
|
||||||
|
else
|
||||||
|
PLATFORM=$TARGET_PLATFORM
|
||||||
|
fi
|
||||||
|
|
||||||
BASE=$(dirname $0)
|
BASE=$(dirname $0)
|
||||||
|
|
||||||
case "$PLATFORM" in
|
case "$PLATFORM" in
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include "kore.h"
|
#include "kore.h"
|
||||||
@ -66,7 +67,7 @@ kore_accesslog(struct http_request *req)
|
|||||||
size_t avail;
|
size_t avail;
|
||||||
time_t curtime;
|
time_t curtime;
|
||||||
int len, attempts;
|
int len, attempts;
|
||||||
const char *ptr, *method, *cn, *referer;
|
const char *ptr, *method, *http_version, *cn, *referer;
|
||||||
char addr[INET6_ADDRSTRLEN], *cn_value;
|
char addr[INET6_ADDRSTRLEN], *cn_value;
|
||||||
|
|
||||||
switch (req->method) {
|
switch (req->method) {
|
||||||
@ -93,6 +94,12 @@ kore_accesslog(struct http_request *req)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req->flags & HTTP_VERSION_1_0)
|
||||||
|
http_version = "HTTP/1.0";
|
||||||
|
|
||||||
|
if (req->flags & HTTP_VERSION_1_1)
|
||||||
|
http_version = "HTTP/1.1";
|
||||||
|
|
||||||
if (req->referer != NULL)
|
if (req->referer != NULL)
|
||||||
referer = req->referer;
|
referer = req->referer;
|
||||||
else
|
else
|
||||||
@ -168,9 +175,9 @@ kore_accesslog(struct http_request *req)
|
|||||||
worker->lb.offset += sizeof(*hdr);
|
worker->lb.offset += sizeof(*hdr);
|
||||||
|
|
||||||
len = snprintf(worker->lb.buf + worker->lb.offset, avail,
|
len = snprintf(worker->lb.buf + worker->lb.offset, avail,
|
||||||
"%s - %s [%s] \"%s %s HTTP/1.1\" %d %zu \"%s\" \"%s\"\n",
|
"%s - %s [%s] \"%s %s %s\" %d %" PRIu64" \"%s\" \"%s\"\n",
|
||||||
addr, cn, tbuf, method, req->path, req->status,
|
addr, cn, tbuf, method, req->path, http_version,
|
||||||
req->content_length, referer, req->agent);
|
req->status, req->content_length, referer, req->agent);
|
||||||
if (len == -1)
|
if (len == -1)
|
||||||
fatal("failed to create log entry");
|
fatal("failed to create log entry");
|
||||||
|
|
||||||
@ -189,7 +196,7 @@ kore_accesslog(struct http_request *req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
hdr->loglen = len;
|
hdr->loglen = len;
|
||||||
hdr->domain = req->hdlr->dom->id;
|
hdr->domain = req->rt->dom->id;
|
||||||
|
|
||||||
worker->lb.offset += (size_t)len;
|
worker->lb.offset += (size_t)len;
|
||||||
break;
|
break;
|
||||||
|
34
src/acme.c
34
src/acme.c
@ -265,10 +265,10 @@ static char *account_url = NULL;
|
|||||||
static u_int8_t acme_alpn_name[] =
|
static u_int8_t acme_alpn_name[] =
|
||||||
{ 0xa, 'a', 'c', 'm', 'e', '-', 't', 'l', 's', '/', '1' };
|
{ 0xa, 'a', 'c', 'm', 'e', '-', 't', 'l', 's', '/', '1' };
|
||||||
|
|
||||||
|
struct kore_privsep acme_privsep;
|
||||||
|
int acme_domains = 0;
|
||||||
char *acme_email = NULL;
|
char *acme_email = NULL;
|
||||||
char *acme_provider = NULL;
|
char *acme_provider = NULL;
|
||||||
char *acme_root_path = NULL;
|
|
||||||
char *acme_runas_user = NULL;
|
|
||||||
u_int32_t acme_request_timeout = 8;
|
u_int32_t acme_request_timeout = 8;
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -310,7 +310,7 @@ kore_acme_run(void)
|
|||||||
#if defined(KORE_USE_PYTHON)
|
#if defined(KORE_USE_PYTHON)
|
||||||
kore_msg_unregister(KORE_PYTHON_SEND_OBJ);
|
kore_msg_unregister(KORE_PYTHON_SEND_OBJ);
|
||||||
#endif
|
#endif
|
||||||
kore_worker_privdrop(acme_runas_user, acme_root_path);
|
kore_worker_privsep();
|
||||||
|
|
||||||
#if defined(__OpenBSD__)
|
#if defined(__OpenBSD__)
|
||||||
if (unveil("/etc/ssl/", "r") == -1)
|
if (unveil("/etc/ssl/", "r") == -1)
|
||||||
@ -321,14 +321,10 @@ kore_acme_run(void)
|
|||||||
|
|
||||||
http_init();
|
http_init();
|
||||||
|
|
||||||
if (!kore_quiet) {
|
|
||||||
kore_log(LOG_NOTICE,
|
|
||||||
"acme worker started (pid#%d)", worker->pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
LIST_INIT(&orders);
|
LIST_INIT(&orders);
|
||||||
LIST_INIT(&signops);
|
LIST_INIT(&signops);
|
||||||
|
|
||||||
|
kore_worker_started();
|
||||||
acme_parse_directory();
|
acme_parse_directory();
|
||||||
|
|
||||||
while (quit != 1) {
|
while (quit != 1) {
|
||||||
@ -434,7 +430,7 @@ kore_acme_tls_challenge_use_cert(SSL *ssl, struct kore_domain *dom)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
kore_log(LOG_NOTICE, "[%s] acme-tls/1 challenge requested",
|
kore_log(LOG_INFO, "[%s] acme-tls/1 challenge requested",
|
||||||
dom->domain);
|
dom->domain);
|
||||||
|
|
||||||
if ((c = SSL_get_ex_data(ssl, 0)) == NULL)
|
if ((c = SSL_get_ex_data(ssl, 0)) == NULL)
|
||||||
@ -483,7 +479,7 @@ acme_parse_directory(void)
|
|||||||
if (!kore_json_parse(&json)) {
|
if (!kore_json_parse(&json)) {
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_NOTICE,
|
||||||
"failed to parse directory payload from ACME server (%s)",
|
"failed to parse directory payload from ACME server (%s)",
|
||||||
kore_json_strerror(&json));
|
kore_json_strerror());
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -688,7 +684,7 @@ acme_order_create_submit(struct acme_sign_op *op, struct kore_buf *payload)
|
|||||||
if (!kore_json_parse(&json)) {
|
if (!kore_json_parse(&json)) {
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_NOTICE,
|
||||||
"[%s] failed to parse order payload from ACME server (%s)",
|
"[%s] failed to parse order payload from ACME server (%s)",
|
||||||
domain, kore_json_strerror(&json));
|
domain, kore_json_strerror());
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,7 +802,7 @@ acme_order_update_submit(struct acme_sign_op *op, struct kore_buf *payload)
|
|||||||
if (!kore_json_parse(&json)) {
|
if (!kore_json_parse(&json)) {
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_NOTICE,
|
||||||
"[%s] failed to parse order payload from ACME server (%s)",
|
"[%s] failed to parse order payload from ACME server (%s)",
|
||||||
order->domain, kore_json_strerror(&json));
|
order->domain, kore_json_strerror());
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,7 +985,7 @@ acme_order_remove(struct acme_order *order, const char *reason)
|
|||||||
kore_free(auth);
|
kore_free(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
kore_log(LOG_NOTICE, "[%s] order removed (%s)", order->domain, reason);
|
kore_log(LOG_INFO, "[%s] order removed (%s)", order->domain, reason);
|
||||||
|
|
||||||
if (strcmp(reason, "completed"))
|
if (strcmp(reason, "completed"))
|
||||||
acme_order_retry(order->domain);
|
acme_order_retry(order->domain);
|
||||||
@ -1224,7 +1220,7 @@ acme_order_auth_update_submit(struct acme_sign_op *op, struct kore_buf *payload)
|
|||||||
if (!kore_json_parse(&json)) {
|
if (!kore_json_parse(&json)) {
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_NOTICE,
|
||||||
"[%s:auth] failed to parse payload from ACME server (%s)",
|
"[%s:auth] failed to parse payload from ACME server (%s)",
|
||||||
order->domain, kore_json_strerror(&json));
|
order->domain, kore_json_strerror());
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1366,7 +1362,7 @@ cleanup:
|
|||||||
} else {
|
} else {
|
||||||
order->auths--;
|
order->auths--;
|
||||||
if (order->auths == 0) {
|
if (order->auths == 0) {
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_INFO,
|
||||||
"[%s:auth] authentications done", order->domain);
|
"[%s:auth] authentications done", order->domain);
|
||||||
order->state = ACME_ORDER_STATE_RUNNING;
|
order->state = ACME_ORDER_STATE_RUNNING;
|
||||||
}
|
}
|
||||||
@ -1389,12 +1385,12 @@ acme_challenge_tls_alpn_01(struct acme_order *order,
|
|||||||
acme_challenge_tls_alpn_01_create(order, challenge);
|
acme_challenge_tls_alpn_01_create(order, challenge);
|
||||||
break;
|
break;
|
||||||
case ACME_STATUS_PROCESSING:
|
case ACME_STATUS_PROCESSING:
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_INFO,
|
||||||
"[%s:auth:challenge:tls-alpn-01] processing",
|
"[%s:auth:challenge:tls-alpn-01] processing",
|
||||||
order->domain);
|
order->domain);
|
||||||
break;
|
break;
|
||||||
case ACME_STATUS_VALID:
|
case ACME_STATUS_VALID:
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_INFO,
|
||||||
"[%s:auth:challenge:tls-alpn-01] valid",
|
"[%s:auth:challenge:tls-alpn-01] valid",
|
||||||
order->domain);
|
order->domain);
|
||||||
ret = KORE_RESULT_OK;
|
ret = KORE_RESULT_OK;
|
||||||
@ -1419,7 +1415,7 @@ acme_challenge_tls_alpn_01_create(struct acme_order *order,
|
|||||||
u_int8_t digest[SHA256_DIGEST_LENGTH];
|
u_int8_t digest[SHA256_DIGEST_LENGTH];
|
||||||
|
|
||||||
if (challenge->flags & ACME_FLAG_CHALLENGE_CREATED) {
|
if (challenge->flags & ACME_FLAG_CHALLENGE_CREATED) {
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_INFO,
|
||||||
"[%s:auth:challenge:tls-alpn-01] pending keymgr",
|
"[%s:auth:challenge:tls-alpn-01] pending keymgr",
|
||||||
order->domain);
|
order->domain);
|
||||||
return;
|
return;
|
||||||
@ -1427,7 +1423,7 @@ acme_challenge_tls_alpn_01_create(struct acme_order *order,
|
|||||||
|
|
||||||
challenge->flags |= ACME_FLAG_CHALLENGE_CREATED;
|
challenge->flags |= ACME_FLAG_CHALLENGE_CREATED;
|
||||||
|
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_INFO,
|
||||||
"[%s:auth:challenge:tls-alpn-01] requested from keymgr",
|
"[%s:auth:challenge:tls-alpn-01] requested from keymgr",
|
||||||
order->domain);
|
order->domain);
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ kore_auth_new(const char *name)
|
|||||||
{
|
{
|
||||||
struct kore_auth *auth;
|
struct kore_auth *auth;
|
||||||
|
|
||||||
if ((auth = kore_auth_lookup(name)) != NULL)
|
if (kore_auth_lookup(name) != NULL)
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
|
|
||||||
auth = kore_malloc(sizeof(*auth));
|
auth = kore_malloc(sizeof(*auth));
|
||||||
@ -90,12 +90,12 @@ kore_auth_run(struct http_request *req, struct kore_auth *auth)
|
|||||||
kore_debug("kore_auth_run() for %s failed", req->path);
|
kore_debug("kore_auth_run() for %s failed", req->path);
|
||||||
|
|
||||||
if (auth->redirect == NULL) {
|
if (auth->redirect == NULL) {
|
||||||
http_response(req, 403, NULL, 0);
|
http_response(req, HTTP_STATUS_FORBIDDEN, NULL, 0);
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
http_response_header(req, "location", auth->redirect);
|
http_response_header(req, "location", auth->redirect);
|
||||||
http_response(req, 302, NULL, 0);
|
http_response(req, HTTP_STATUS_FOUND, NULL, 0);
|
||||||
|
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
239
src/cli.c
239
src/cli.c
@ -187,9 +187,12 @@ static void cli_buildopt_kore_flavor(struct buildopt *,
|
|||||||
const char *);
|
const char *);
|
||||||
static void cli_buildopt_mime(struct buildopt *, const char *);
|
static void cli_buildopt_mime(struct buildopt *, const char *);
|
||||||
|
|
||||||
|
static void cli_build_flags_common(struct buildopt *,
|
||||||
|
struct cli_buf *);
|
||||||
|
|
||||||
static void cli_flavor_load(void);
|
static void cli_flavor_load(void);
|
||||||
static void cli_flavor_change(const char *);
|
static void cli_flavor_change(const char *);
|
||||||
static void cli_kore_features(struct buildopt *,
|
static void cli_kore_load_file(const char *, struct buildopt *,
|
||||||
char **, size_t *);
|
char **, size_t *);
|
||||||
|
|
||||||
static void cli_run(int, char **);
|
static void cli_run(int, char **);
|
||||||
@ -200,6 +203,10 @@ static void cli_clean(int, char **);
|
|||||||
static void cli_source(int, char **);
|
static void cli_source(int, char **);
|
||||||
static void cli_reload(int, char **);
|
static void cli_reload(int, char **);
|
||||||
static void cli_flavor(int, char **);
|
static void cli_flavor(int, char **);
|
||||||
|
static void cli_cflags(int, char **);
|
||||||
|
static void cli_ldflags(int, char **);
|
||||||
|
static void cli_genasset(int, char **);
|
||||||
|
static void cli_genasset_help(void);
|
||||||
|
|
||||||
#if !defined(KODEV_MINIMAL)
|
#if !defined(KODEV_MINIMAL)
|
||||||
static void cli_create(int, char **);
|
static void cli_create(int, char **);
|
||||||
@ -209,7 +216,6 @@ static void file_create_src(void);
|
|||||||
static void file_create_config(void);
|
static void file_create_config(void);
|
||||||
static void file_create_gitignore(void);
|
static void file_create_gitignore(void);
|
||||||
static void file_create_python_src(void);
|
static void file_create_python_src(void);
|
||||||
static void file_create_python_config(void);
|
|
||||||
|
|
||||||
static void cli_generate_certs(void);
|
static void cli_generate_certs(void);
|
||||||
static void cli_file_create(const char *, const char *, size_t);
|
static void cli_file_create(const char *, const char *, size_t);
|
||||||
@ -218,6 +224,7 @@ static void cli_file_create(const char *, const char *, size_t);
|
|||||||
static struct cmd cmds[] = {
|
static struct cmd cmds[] = {
|
||||||
{ "help", "this help text", cli_help },
|
{ "help", "this help text", cli_help },
|
||||||
{ "run", "run an application (-fnr implied)", cli_run },
|
{ "run", "run an application (-fnr implied)", cli_run },
|
||||||
|
{ "gen", "generate asset file for compilation", cli_genasset },
|
||||||
{ "reload", "reload the application (SIGHUP)", cli_reload },
|
{ "reload", "reload the application (SIGHUP)", cli_reload },
|
||||||
{ "info", "show info on kore on this system", cli_info },
|
{ "info", "show info on kore on this system", cli_info },
|
||||||
{ "build", "build an application", cli_build },
|
{ "build", "build an application", cli_build },
|
||||||
@ -227,6 +234,8 @@ static struct cmd cmds[] = {
|
|||||||
{ "create", "create a new application skeleton", cli_create },
|
{ "create", "create a new application skeleton", cli_create },
|
||||||
#endif
|
#endif
|
||||||
{ "flavor", "switch between build flavors", cli_flavor },
|
{ "flavor", "switch between build flavors", cli_flavor },
|
||||||
|
{ "cflags", "show kore CFLAGS", cli_cflags },
|
||||||
|
{ "ldflags", "show kore LDFLAGS", cli_ldflags },
|
||||||
{ NULL, NULL, NULL }
|
{ NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -253,7 +262,6 @@ static const char *python_gen_dirs[] = {
|
|||||||
|
|
||||||
static struct filegen python_gen_files[] = {
|
static struct filegen python_gen_files[] = {
|
||||||
{ file_create_python_src },
|
{ file_create_python_src },
|
||||||
{ file_create_python_config },
|
|
||||||
{ file_create_gitignore },
|
{ file_create_gitignore },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
@ -289,15 +297,16 @@ static const char *config_data =
|
|||||||
"\n"
|
"\n"
|
||||||
"load\t\t./%s.so\n"
|
"load\t\t./%s.so\n"
|
||||||
"\n"
|
"\n"
|
||||||
"tls_dhparam\tdh2048.pem\n"
|
|
||||||
"\n"
|
|
||||||
"domain * {\n"
|
"domain * {\n"
|
||||||
"\tattach\t\ttls\n"
|
"\tattach\t\ttls\n"
|
||||||
"\n"
|
"\n"
|
||||||
"\tcertfile\tcert/server.pem\n"
|
"\tcertfile\tcert/server.pem\n"
|
||||||
"\tcertkey\t\tcert/key.pem\n"
|
"\tcertkey\t\tcert/key.pem\n"
|
||||||
"\n"
|
"\n"
|
||||||
"\troute\t/\tpage\n"
|
"\troute / {\n"
|
||||||
|
"\t\thandler page\n"
|
||||||
|
"\t}\n"
|
||||||
|
"\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
static const char *build_data =
|
static const char *build_data =
|
||||||
@ -336,51 +345,29 @@ static const char *build_data =
|
|||||||
"# included if you build with the \"prod\" flavor.\n"
|
"# included if you build with the \"prod\" flavor.\n"
|
||||||
"#}\n";
|
"#}\n";
|
||||||
|
|
||||||
static const char *python_config_data =
|
|
||||||
"# %s configuration\n"
|
|
||||||
"\n"
|
|
||||||
"server tls {\n"
|
|
||||||
"\tbind 127.0.0.1 8888\n"
|
|
||||||
"}\n"
|
|
||||||
"tls_dhparam\tdh2048.pem\n"
|
|
||||||
"\n"
|
|
||||||
"domain * {\n"
|
|
||||||
"\tattach\t\ttls\n"
|
|
||||||
"\n"
|
|
||||||
"\tcertfile\tcert/server.pem\n"
|
|
||||||
"\tcertkey\t\tcert/key.pem\n"
|
|
||||||
"\n"
|
|
||||||
"\troute\t/\tkoreapp.index\n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
static const char *python_init_data =
|
static const char *python_init_data =
|
||||||
"from .app import koreapp\n";
|
"from .app import koreapp\n";
|
||||||
|
|
||||||
static const char *python_app_data =
|
static const char *python_app_data =
|
||||||
"import kore\n"
|
"import kore\n"
|
||||||
"\n"
|
"\n"
|
||||||
"class App:\n"
|
"class KoreApp:\n"
|
||||||
" def __init__(self):\n"
|
|
||||||
" pass\n"
|
|
||||||
"\n"
|
|
||||||
" def configure(self, args):\n"
|
" def configure(self, args):\n"
|
||||||
" kore.config.file = \"kore.conf\"\n"
|
|
||||||
" kore.config.deployment = \"development\"\n"
|
" kore.config.deployment = \"development\"\n"
|
||||||
|
" kore.server(\"default\", ip=\"127.0.0.1\", port=\"8888\")\n"
|
||||||
|
"\n"
|
||||||
|
" d = kore.domain(\"*\",\n"
|
||||||
|
" attach=\"default\",\n"
|
||||||
|
" key=\"cert/key.pem\",\n"
|
||||||
|
" cert=\"cert/server.pem\",\n"
|
||||||
|
" )\n"
|
||||||
|
"\n"
|
||||||
|
" d.route(\"/\", self.index, methods=[\"get\"])\n"
|
||||||
"\n"
|
"\n"
|
||||||
" async def index(self, req):\n"
|
" async def index(self, req):\n"
|
||||||
" req.response(200, b'')\n"
|
" req.response(200, b'')\n"
|
||||||
"\n"
|
"\n"
|
||||||
"koreapp = App()";
|
"koreapp = KoreApp()";
|
||||||
|
|
||||||
static const char *dh2048_data =
|
|
||||||
"-----BEGIN DH PARAMETERS-----\n"
|
|
||||||
"MIIBCAKCAQEAn4f4Qn5SudFjEYPWTbUaOTLUH85YWmmPFW1+b5bRa9ygr+1wfamv\n"
|
|
||||||
"VKVT7jO8c4msSNikUf6eEfoH0H4VTCaj+Habwu+Sj+I416r3mliMD4SjNsUJrBrY\n"
|
|
||||||
"Y0QV3ZUgZz4A8ARk/WwQcRl8+ZXJz34IaLwAcpyNhoV46iHVxW0ty8ND0U4DIku/\n"
|
|
||||||
"PNayKimu4BXWXk4RfwNVP59t8DQKqjshZ4fDnbotskmSZ+e+FHrd+Kvrq/WButvV\n"
|
|
||||||
"Bzy9fYgnUlJ82g/bziCI83R2xAdtH014fR63MpElkqdNeChb94pPbEdFlNUvYIBN\n"
|
|
||||||
"xx2vTUQMqRbB4UdG2zuzzr5j98HDdblQ+wIBAg==\n"
|
|
||||||
"-----END DH PARAMETERS-----";
|
|
||||||
|
|
||||||
static const char *gitignore = "*.o\n.flavor\n.objs\n%s.so\nassets.h\ncert\n";
|
static const char *gitignore = "*.o\n.flavor\n.objs\n%s.so\nassets.h\ncert\n";
|
||||||
|
|
||||||
@ -400,6 +387,7 @@ static int source_files_count;
|
|||||||
static int cxx_files_count;
|
static int cxx_files_count;
|
||||||
static struct cmd *command = NULL;
|
static struct cmd *command = NULL;
|
||||||
static int cflags_count = 0;
|
static int cflags_count = 0;
|
||||||
|
static int genasset_cmd = 0;
|
||||||
static int cxxflags_count = 0;
|
static int cxxflags_count = 0;
|
||||||
static int ldflags_count = 0;
|
static int ldflags_count = 0;
|
||||||
static char *flavor = NULL;
|
static char *flavor = NULL;
|
||||||
@ -546,8 +534,7 @@ cli_create(int argc, char **argv)
|
|||||||
cli_generate_certs();
|
cli_generate_certs();
|
||||||
|
|
||||||
printf("%s created successfully!\n", appl);
|
printf("%s created successfully!\n", appl);
|
||||||
printf("WARNING: DO NOT USE THE GENERATED DH PARAMETERS "
|
printf("WARNING: DO NOT USE THE GENERATED CERTIFICATE IN PRODUCTION\n");
|
||||||
"AND CERTIFICATES IN PRODUCTION\n");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -742,9 +729,9 @@ cli_build(int argc, char **argv)
|
|||||||
|
|
||||||
if (bopt->single_binary) {
|
if (bopt->single_binary) {
|
||||||
requires_relink++;
|
requires_relink++;
|
||||||
(void)cli_vasprintf(&sofile, "%s", appl);
|
(void)cli_vasprintf(&sofile, "%s/%s", out_dir, appl);
|
||||||
} else {
|
} else {
|
||||||
(void)cli_vasprintf(&sofile, "%s.so", appl);
|
(void)cli_vasprintf(&sofile, "%s/%s.so", out_dir, appl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cli_file_exists(sofile) && source_files_count > 0)
|
if (!cli_file_exists(sofile) && source_files_count > 0)
|
||||||
@ -772,7 +759,8 @@ cli_source(int argc, char **argv)
|
|||||||
static void
|
static void
|
||||||
cli_clean(int argc, char **argv)
|
cli_clean(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char pwd[PATH_MAX], *sofile;
|
struct buildopt *bopt;
|
||||||
|
char pwd[PATH_MAX], *bin;
|
||||||
|
|
||||||
if (cli_dir_exists(object_dir))
|
if (cli_dir_exists(object_dir))
|
||||||
cli_cleanup_files(object_dir);
|
cli_cleanup_files(object_dir);
|
||||||
@ -781,11 +769,23 @@ cli_clean(int argc, char **argv)
|
|||||||
fatal("could not get cwd: %s", errno_s);
|
fatal("could not get cwd: %s", errno_s);
|
||||||
|
|
||||||
appl = basename(pwd);
|
appl = basename(pwd);
|
||||||
(void)cli_vasprintf(&sofile, "%s.so", appl);
|
|
||||||
if (unlink(sofile) == -1 && errno != ENOENT)
|
|
||||||
printf("couldn't unlink %s: %s", sofile, errno_s);
|
|
||||||
|
|
||||||
free(sofile);
|
TAILQ_INIT(&mime_types);
|
||||||
|
TAILQ_INIT(&build_options);
|
||||||
|
|
||||||
|
cli_flavor_load();
|
||||||
|
bopt = cli_buildopt_new("_default");
|
||||||
|
cli_buildopt_parse("conf/build.conf");
|
||||||
|
|
||||||
|
if (bopt->single_binary)
|
||||||
|
(void)cli_vasprintf(&bin, "%s/%s", out_dir, appl);
|
||||||
|
else
|
||||||
|
(void)cli_vasprintf(&bin, "%s/%s.so", out_dir, appl);
|
||||||
|
|
||||||
|
if (unlink(bin) == -1 && errno != ENOENT)
|
||||||
|
printf("couldn't unlink %s: %s", bin, errno_s);
|
||||||
|
|
||||||
|
free(bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -853,13 +853,101 @@ cli_info(int argc, char **argv)
|
|||||||
printf("kore features\t %s\n", bopt->kore_flavor);
|
printf("kore features\t %s\n", bopt->kore_flavor);
|
||||||
printf("kore source \t %s\n", bopt->kore_source);
|
printf("kore source \t %s\n", bopt->kore_source);
|
||||||
} else {
|
} else {
|
||||||
cli_kore_features(bopt, &features, &len);
|
cli_kore_load_file("features", bopt, &features, &len);
|
||||||
printf("kore binary \t %s/bin/kore\n", prefix);
|
printf("kore binary \t %s/bin/kore\n", prefix);
|
||||||
printf("kore features\t %.*s\n", (int)len, features);
|
printf("kore features\t %.*s\n", (int)len, features);
|
||||||
free(features);
|
free(features);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cli_cflags(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct cli_buf *buf;
|
||||||
|
|
||||||
|
buf = cli_buf_alloc(128);
|
||||||
|
cli_build_flags_common(NULL, buf);
|
||||||
|
printf("%.*s\n", (int)buf->offset, buf->data);
|
||||||
|
cli_buf_free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cli_ldflags(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
cli_kore_load_file("linker", NULL, &p, &len);
|
||||||
|
printf("%.*s ", (int)len, p);
|
||||||
|
|
||||||
|
#if defined(__MACH__)
|
||||||
|
printf("-dynamiclib -undefined suppress -flat_namespace ");
|
||||||
|
#else
|
||||||
|
printf("-shared ");
|
||||||
|
#endif
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cli_genasset(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
struct dirent dp;
|
||||||
|
char *hdr;
|
||||||
|
|
||||||
|
genasset_cmd = 1;
|
||||||
|
TAILQ_INIT(&build_options);
|
||||||
|
(void)cli_buildopt_new("_default");
|
||||||
|
|
||||||
|
if (getenv("KORE_OBJDIR") == NULL)
|
||||||
|
object_dir = out_dir;
|
||||||
|
|
||||||
|
if (argv[0] == NULL)
|
||||||
|
cli_genasset_help();
|
||||||
|
|
||||||
|
(void)cli_vasprintf(&hdr, "%s/assets.h", out_dir);
|
||||||
|
(void)unlink(hdr);
|
||||||
|
|
||||||
|
cli_file_open(hdr, O_CREAT | O_TRUNC | O_WRONLY, &s_fd);
|
||||||
|
cli_file_writef(s_fd, "#ifndef __H_KORE_ASSETS_H\n");
|
||||||
|
cli_file_writef(s_fd, "#define __H_KORE_ASSETS_H\n");
|
||||||
|
|
||||||
|
if (stat(argv[0], &st) == -1)
|
||||||
|
fatal("%s: %s", argv[0], errno_s);
|
||||||
|
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
if (cli_dir_exists(argv[0]))
|
||||||
|
cli_find_files(argv[0], cli_build_asset);
|
||||||
|
} else if (S_ISREG(st.st_mode)) {
|
||||||
|
memset(&dp, 0, sizeof(dp));
|
||||||
|
dp.d_type = DT_REG;
|
||||||
|
(void)snprintf(dp.d_name, sizeof(dp.d_name), "%s",
|
||||||
|
basename(argv[0]));
|
||||||
|
cli_build_asset(argv[0], &dp);
|
||||||
|
} else {
|
||||||
|
fatal("%s is not a directory or regular file", argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_file_writef(s_fd, "\n#endif\n");
|
||||||
|
cli_file_close(s_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cli_genasset_help(void)
|
||||||
|
{
|
||||||
|
printf("Usage: kodev genasset [source]\n");
|
||||||
|
printf("Synopsis:\n");
|
||||||
|
printf(" Generates asset file(s) to be used for compilation.\n");
|
||||||
|
printf(" The source can be a single file or directory.\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("This command honors the KODEV_OUTPUT environment variable.\n");
|
||||||
|
printf("This command honors the KORE_OBJDIR environment variable.\n");
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(KODEV_MINIMAL)
|
#if !defined(KODEV_MINIMAL)
|
||||||
static void
|
static void
|
||||||
file_create_python_src(void)
|
file_create_python_src(void)
|
||||||
@ -875,19 +963,6 @@ file_create_python_src(void)
|
|||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
file_create_python_config(void)
|
|
||||||
{
|
|
||||||
int l;
|
|
||||||
char *name, *data;
|
|
||||||
|
|
||||||
(void)cli_vasprintf(&name, "%s/kore.conf", appl);
|
|
||||||
l = cli_vasprintf(&data, python_config_data, appl);
|
|
||||||
cli_file_create(name, data, l);
|
|
||||||
free(name);
|
|
||||||
free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
file_create_src(void)
|
file_create_src(void)
|
||||||
{
|
{
|
||||||
@ -1257,7 +1332,9 @@ cli_build_asset(char *fpath, struct dirent *dp)
|
|||||||
*--ext = '.';
|
*--ext = '.';
|
||||||
|
|
||||||
/* Register the .c file now (cpath is free'd later). */
|
/* Register the .c file now (cpath is free'd later). */
|
||||||
|
if (genasset_cmd == 0)
|
||||||
cli_add_source_file(name, cpath, opath, &st, BUILD_C);
|
cli_add_source_file(name, cpath, opath, &st, BUILD_C);
|
||||||
|
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1396,9 +1473,6 @@ cli_generate_certs(void)
|
|||||||
RSA *kpair;
|
RSA *kpair;
|
||||||
char issuer[64];
|
char issuer[64];
|
||||||
|
|
||||||
/* Write out DH parameters. */
|
|
||||||
cli_file_create("dh2048.pem", dh2048_data, strlen(dh2048_data));
|
|
||||||
|
|
||||||
/* Create new certificate. */
|
/* Create new certificate. */
|
||||||
if ((x509 = X509_new()) == NULL)
|
if ((x509 = X509_new()) == NULL)
|
||||||
fatal("X509_new(): %s", ssl_errno_s);
|
fatal("X509_new(): %s", ssl_errno_s);
|
||||||
@ -1616,10 +1690,8 @@ cli_run_kore_python(void)
|
|||||||
fatal("could not get cwd: %s", errno_s);
|
fatal("could not get cwd: %s", errno_s);
|
||||||
|
|
||||||
args[0] = cmd;
|
args[0] = cmd;
|
||||||
args[1] = "-frnc";
|
args[1] = pwd;
|
||||||
args[2] = "kore.conf";
|
args[2] = NULL;
|
||||||
args[3] = pwd;
|
|
||||||
args[4] = NULL;
|
|
||||||
|
|
||||||
execvp(args[0], args);
|
execvp(args[0], args);
|
||||||
fatal("failed to start '%s': %s", args[0], errno_s);
|
fatal("failed to start '%s': %s", args[0], errno_s);
|
||||||
@ -1935,20 +2007,18 @@ cli_build_flags_common(struct buildopt *bopt, struct cli_buf *buf)
|
|||||||
size_t len;
|
size_t len;
|
||||||
char *data;
|
char *data;
|
||||||
|
|
||||||
cli_buf_appendf(buf, "-fPIC -Isrc -Isrc/includes ");
|
cli_buf_appendf(buf, "-fPIC ");
|
||||||
|
|
||||||
if (bopt->single_binary == 0)
|
if (bopt != NULL)
|
||||||
|
cli_buf_appendf(buf, "-Isrc -Isrc/includes ");
|
||||||
|
|
||||||
|
if (bopt == NULL || bopt->single_binary == 0)
|
||||||
cli_buf_appendf(buf, "-I%s/include ", prefix);
|
cli_buf_appendf(buf, "-I%s/include ", prefix);
|
||||||
else
|
else
|
||||||
cli_buf_appendf(buf, "-I%s/include ", bopt->kore_source);
|
cli_buf_appendf(buf, "-I%s/include ", bopt->kore_source);
|
||||||
|
|
||||||
#if defined(__MACH__)
|
if (bopt == NULL || bopt->single_binary == 0) {
|
||||||
/* Add default openssl include path from homebrew / ports under OSX. */
|
cli_kore_load_file("features", bopt, &data, &len);
|
||||||
cli_buf_appendf(buf, "-I/opt/local/include ");
|
|
||||||
cli_buf_appendf(buf, "-I/usr/local/opt/openssl/include ");
|
|
||||||
#endif
|
|
||||||
if (bopt->single_binary == 0) {
|
|
||||||
cli_kore_features(bopt, &data, &len);
|
|
||||||
cli_buf_append(buf, data, len);
|
cli_buf_append(buf, data, len);
|
||||||
cli_buf_appendf(buf, " ");
|
cli_buf_appendf(buf, " ");
|
||||||
free(data);
|
free(data);
|
||||||
@ -1976,7 +2046,7 @@ cli_build_cflags(struct buildopt *bopt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bopt->single_binary) {
|
if (bopt->single_binary) {
|
||||||
cli_kore_features(bopt, &buf, &len);
|
cli_kore_load_file("features", bopt, &buf, &len);
|
||||||
cli_buf_append(bopt->cflags, buf, len);
|
cli_buf_append(bopt->cflags, buf, len);
|
||||||
cli_buf_appendf(bopt->cflags, " ");
|
cli_buf_appendf(bopt->cflags, " ");
|
||||||
free(buf);
|
free(buf);
|
||||||
@ -2106,16 +2176,17 @@ cli_flavor_load(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cli_kore_features(struct buildopt *bopt, char **out, size_t *outlen)
|
cli_kore_load_file(const char *name, struct buildopt *bopt,
|
||||||
|
char **out, size_t *outlen)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
size_t len;
|
size_t len;
|
||||||
char *path, *data;
|
char *path, *data;
|
||||||
|
|
||||||
if (bopt->single_binary) {
|
if (bopt != NULL && bopt->single_binary) {
|
||||||
(void)cli_vasprintf(&path, "%s/features", object_dir);
|
(void)cli_vasprintf(&path, "%s/%s", object_dir, name);
|
||||||
} else {
|
} else {
|
||||||
(void)cli_vasprintf(&path, "%s/share/kore/features", prefix);
|
(void)cli_vasprintf(&path, "%s/share/kore/%s", prefix, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
cli_file_open(path, O_RDONLY, &fd);
|
cli_file_open(path, O_RDONLY, &fd);
|
||||||
@ -2124,7 +2195,7 @@ cli_kore_features(struct buildopt *bopt, char **out, size_t *outlen)
|
|||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
fatal("features is empty");
|
fatal("%s is empty", name);
|
||||||
|
|
||||||
len--;
|
len--;
|
||||||
|
|
||||||
|
792
src/config.c
792
src/config.c
File diff suppressed because it is too large
Load Diff
@ -258,6 +258,12 @@ kore_connection_handle(struct connection *c)
|
|||||||
|
|
||||||
switch (c->state) {
|
switch (c->state) {
|
||||||
case CONN_STATE_TLS_SHAKE:
|
case CONN_STATE_TLS_SHAKE:
|
||||||
|
if (primary_dom == NULL) {
|
||||||
|
kore_log(LOG_NOTICE,
|
||||||
|
"TLS handshake but no TLS configured on server");
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
if (primary_dom->ssl_ctx == NULL) {
|
if (primary_dom->ssl_ctx == NULL) {
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_NOTICE,
|
||||||
"TLS configuration for %s not yet complete",
|
"TLS configuration for %s not yet complete",
|
||||||
|
@ -407,18 +407,17 @@ kore_curl_http_setup(struct kore_curl *client, int method, const void *data,
|
|||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case HTTP_METHOD_GET:
|
case HTTP_METHOD_GET:
|
||||||
|
case HTTP_METHOD_OPTIONS:
|
||||||
break;
|
break;
|
||||||
case HTTP_METHOD_HEAD:
|
case HTTP_METHOD_HEAD:
|
||||||
curl_easy_setopt(client->handle, CURLOPT_NOBODY, 1);
|
curl_easy_setopt(client->handle, CURLOPT_NOBODY, 1);
|
||||||
break;
|
break;
|
||||||
case HTTP_METHOD_DELETE:
|
|
||||||
case HTTP_METHOD_OPTIONS:
|
|
||||||
break;
|
|
||||||
case HTTP_METHOD_PUT:
|
case HTTP_METHOD_PUT:
|
||||||
has_body = 1;
|
has_body = 1;
|
||||||
curl_easy_setopt(client->handle, CURLOPT_UPLOAD, 1);
|
curl_easy_setopt(client->handle, CURLOPT_UPLOAD, 1);
|
||||||
break;
|
break;
|
||||||
case HTTP_METHOD_PATCH:
|
case HTTP_METHOD_PATCH:
|
||||||
|
case HTTP_METHOD_DELETE:
|
||||||
mname = http_method_text(method);
|
mname = http_method_text(method);
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case HTTP_METHOD_POST:
|
case HTTP_METHOD_POST:
|
||||||
|
135
src/domain.c
135
src/domain.c
@ -14,12 +14,6 @@
|
|||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX - Lots of OPENSSL ifdefs here for 1.0.2 and 1.1.0 release lines.
|
|
||||||
* The idea is to only support 1.1.1 down the line and remove the rest.
|
|
||||||
* (although we have to remain compat with 1.0.2 due to LibreSSL).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -68,54 +62,8 @@ static int keymgr_rsa_privenc(int, const unsigned char *,
|
|||||||
static ECDSA_SIG *keymgr_ecdsa_sign(const unsigned char *, int,
|
static ECDSA_SIG *keymgr_ecdsa_sign(const unsigned char *, int,
|
||||||
const BIGNUM *, const BIGNUM *, EC_KEY *);
|
const BIGNUM *, const BIGNUM *, EC_KEY *);
|
||||||
|
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
static RSA_METHOD *keymgr_rsa_meth = NULL;
|
static RSA_METHOD *keymgr_rsa_meth = NULL;
|
||||||
static EC_KEY_METHOD *keymgr_ec_meth = NULL;
|
static EC_KEY_METHOD *keymgr_ec_meth = NULL;
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* Run own ecdsa_method data structure as OpenSSL has this in ecs_locl.h
|
|
||||||
* and does not export this on systems.
|
|
||||||
*/
|
|
||||||
struct ecdsa_method {
|
|
||||||
const char *name;
|
|
||||||
ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *,
|
|
||||||
int, const BIGNUM *, const BIGNUM *, EC_KEY *);
|
|
||||||
int (*ecdsa_sign_setup)(EC_KEY *, BN_CTX *, BIGNUM **,
|
|
||||||
BIGNUM **);
|
|
||||||
int (*ecdsa_do_verify)(const unsigned char *, int,
|
|
||||||
const ECDSA_SIG *, EC_KEY *);
|
|
||||||
int flags;
|
|
||||||
char *app_data;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
static ECDSA_METHOD keymgr_ecdsa = {
|
|
||||||
"kore ECDSA keymgr method",
|
|
||||||
keymgr_ecdsa_sign,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static RSA_METHOD keymgr_rsa = {
|
|
||||||
"kore RSA keymgr method",
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
keymgr_rsa_privenc,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
keymgr_rsa_init,
|
|
||||||
keymgr_rsa_finish,
|
|
||||||
RSA_METHOD_FLAG_NO_CHECK,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static u_int16_t domain_id = 0;
|
static u_int16_t domain_id = 0;
|
||||||
static struct kore_domain *cached[KORE_DOMAIN_CACHE];
|
static struct kore_domain *cached[KORE_DOMAIN_CACHE];
|
||||||
@ -128,7 +76,6 @@ kore_domain_init(void)
|
|||||||
for (i = 0; i < KORE_DOMAIN_CACHE; i++)
|
for (i = 0; i < KORE_DOMAIN_CACHE; i++)
|
||||||
cached[i] = NULL;
|
cached[i] = NULL;
|
||||||
|
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
if (keymgr_rsa_meth == NULL) {
|
if (keymgr_rsa_meth == NULL) {
|
||||||
if ((keymgr_rsa_meth = RSA_meth_new("kore RSA keymgr method",
|
if ((keymgr_rsa_meth = RSA_meth_new("kore RSA keymgr method",
|
||||||
RSA_METHOD_FLAG_NO_CHECK)) == NULL)
|
RSA_METHOD_FLAG_NO_CHECK)) == NULL)
|
||||||
@ -145,7 +92,6 @@ kore_domain_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
EC_KEY_METHOD_set_sign(keymgr_ec_meth, NULL, NULL, keymgr_ecdsa_sign);
|
EC_KEY_METHOD_set_sign(keymgr_ec_meth, NULL, NULL, keymgr_ecdsa_sign);
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(TLS1_3_VERSION)
|
#if !defined(TLS1_3_VERSION)
|
||||||
if (!kore_quiet) {
|
if (!kore_quiet) {
|
||||||
@ -159,7 +105,6 @@ kore_domain_init(void)
|
|||||||
void
|
void
|
||||||
kore_domain_cleanup(void)
|
kore_domain_cleanup(void)
|
||||||
{
|
{
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
if (keymgr_rsa_meth != NULL) {
|
if (keymgr_rsa_meth != NULL) {
|
||||||
RSA_meth_free(keymgr_rsa_meth);
|
RSA_meth_free(keymgr_rsa_meth);
|
||||||
keymgr_rsa_meth = NULL;
|
keymgr_rsa_meth = NULL;
|
||||||
@ -169,7 +114,6 @@ kore_domain_cleanup(void)
|
|||||||
EC_KEY_METHOD_free(keymgr_ec_meth);
|
EC_KEY_METHOD_free(keymgr_ec_meth);
|
||||||
keymgr_ec_meth = NULL;
|
keymgr_ec_meth = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct kore_domain *
|
struct kore_domain *
|
||||||
@ -187,8 +131,8 @@ kore_domain_new(const char *domain)
|
|||||||
dom->domain = kore_strdup(domain);
|
dom->domain = kore_strdup(domain);
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
TAILQ_INIT(&(dom->handlers));
|
TAILQ_INIT(&dom->routes);
|
||||||
TAILQ_INIT(&(dom->redirects));
|
TAILQ_INIT(&dom->redirects);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dom->id < KORE_DOMAIN_CACHE) {
|
if (dom->id < KORE_DOMAIN_CACHE) {
|
||||||
@ -230,8 +174,8 @@ void
|
|||||||
kore_domain_free(struct kore_domain *dom)
|
kore_domain_free(struct kore_domain *dom)
|
||||||
{
|
{
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
|
struct kore_route *rt;
|
||||||
struct http_redirect *rdr;
|
struct http_redirect *rdr;
|
||||||
struct kore_module_handle *hdlr;
|
|
||||||
#endif
|
#endif
|
||||||
if (dom == NULL)
|
if (dom == NULL)
|
||||||
return;
|
return;
|
||||||
@ -246,20 +190,17 @@ kore_domain_free(struct kore_domain *dom)
|
|||||||
|
|
||||||
if (dom->ssl_ctx != NULL)
|
if (dom->ssl_ctx != NULL)
|
||||||
SSL_CTX_free(dom->ssl_ctx);
|
SSL_CTX_free(dom->ssl_ctx);
|
||||||
if (dom->cafile != NULL)
|
|
||||||
kore_free(dom->cafile);
|
kore_free(dom->cafile);
|
||||||
if (dom->certkey != NULL)
|
|
||||||
kore_free(dom->certkey);
|
kore_free(dom->certkey);
|
||||||
if (dom->certfile != NULL)
|
|
||||||
kore_free(dom->certfile);
|
kore_free(dom->certfile);
|
||||||
if (dom->crlfile != NULL)
|
|
||||||
kore_free(dom->crlfile);
|
kore_free(dom->crlfile);
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
/* Drop all handlers associated with this domain */
|
/* Drop all handlers associated with this domain */
|
||||||
while ((hdlr = TAILQ_FIRST(&(dom->handlers))) != NULL) {
|
while ((rt = TAILQ_FIRST(&dom->routes)) != NULL) {
|
||||||
TAILQ_REMOVE(&(dom->handlers), hdlr, list);
|
TAILQ_REMOVE(&dom->routes, rt, list);
|
||||||
kore_module_handler_free(hdlr);
|
kore_route_free(rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((rdr = TAILQ_FIRST(&(dom->redirects))) != NULL) {
|
while ((rdr = TAILQ_FIRST(&(dom->redirects))) != NULL) {
|
||||||
@ -283,35 +224,18 @@ kore_domain_tlsinit(struct kore_domain *dom, int type,
|
|||||||
STACK_OF(X509_NAME) *certs;
|
STACK_OF(X509_NAME) *certs;
|
||||||
EC_KEY *eckey;
|
EC_KEY *eckey;
|
||||||
const SSL_METHOD *method;
|
const SSL_METHOD *method;
|
||||||
#if !defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
EC_KEY *ecdh;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
kore_debug("kore_domain_tlsinit(%s)", dom->domain);
|
kore_debug("kore_domain_tlsinit(%s)", dom->domain);
|
||||||
|
|
||||||
if (dom->ssl_ctx != NULL)
|
if (dom->ssl_ctx != NULL)
|
||||||
SSL_CTX_free(dom->ssl_ctx);
|
SSL_CTX_free(dom->ssl_ctx);
|
||||||
|
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
if ((method = TLS_method()) == NULL)
|
if ((method = TLS_method()) == NULL)
|
||||||
fatalx("TLS_method(): %s", ssl_errno_s);
|
fatalx("TLS_method(): %s", ssl_errno_s);
|
||||||
#else
|
|
||||||
switch (tls_version) {
|
|
||||||
case KORE_TLS_VERSION_1_3:
|
|
||||||
case KORE_TLS_VERSION_1_2:
|
|
||||||
case KORE_TLS_VERSION_BOTH:
|
|
||||||
method = TLSv1_2_server_method();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fatalx("unknown tls_version: %d", tls_version);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((dom->ssl_ctx = SSL_CTX_new(method)) == NULL)
|
if ((dom->ssl_ctx = SSL_CTX_new(method)) == NULL)
|
||||||
fatalx("SSL_ctx_new(): %s", ssl_errno_s);
|
fatalx("SSL_ctx_new(): %s", ssl_errno_s);
|
||||||
|
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
if (!SSL_CTX_set_min_proto_version(dom->ssl_ctx, TLS1_2_VERSION))
|
if (!SSL_CTX_set_min_proto_version(dom->ssl_ctx, TLS1_2_VERSION))
|
||||||
fatalx("SSL_CTX_set_min_proto_version: %s", ssl_errno_s);
|
fatalx("SSL_CTX_set_min_proto_version: %s", ssl_errno_s);
|
||||||
|
|
||||||
@ -346,7 +270,6 @@ kore_domain_tlsinit(struct kore_domain *dom, int type,
|
|||||||
fatalx("unknown tls_version: %d", tls_version);
|
fatalx("unknown tls_version: %d", tls_version);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case KORE_PEM_CERT_CHAIN:
|
case KORE_PEM_CERT_CHAIN:
|
||||||
@ -380,22 +303,13 @@ kore_domain_tlsinit(struct kore_domain *dom, int type,
|
|||||||
if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL)
|
if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL)
|
||||||
fatalx("no RSA public key present");
|
fatalx("no RSA public key present");
|
||||||
RSA_set_app_data(rsa, dom);
|
RSA_set_app_data(rsa, dom);
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
RSA_set_method(rsa, keymgr_rsa_meth);
|
RSA_set_method(rsa, keymgr_rsa_meth);
|
||||||
#else
|
|
||||||
RSA_set_method(rsa, &keymgr_rsa);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case EVP_PKEY_EC:
|
case EVP_PKEY_EC:
|
||||||
if ((eckey = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
|
if ((eckey = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
|
||||||
fatalx("no EC public key present");
|
fatalx("no EC public key present");
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
EC_KEY_set_ex_data(eckey, 0, dom);
|
EC_KEY_set_ex_data(eckey, 0, dom);
|
||||||
EC_KEY_set_method(eckey, keymgr_ec_meth);
|
EC_KEY_set_method(eckey, keymgr_ec_meth);
|
||||||
#else
|
|
||||||
ECDSA_set_ex_data(eckey, 0, dom);
|
|
||||||
ECDSA_set_method(eckey, &keymgr_ecdsa);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fatalx("unknown public key in certificate");
|
fatalx("unknown public key in certificate");
|
||||||
@ -410,21 +324,13 @@ kore_domain_tlsinit(struct kore_domain *dom, int type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tls_dhparam == NULL)
|
if (tls_dhparam == NULL)
|
||||||
fatalx("No DH parameters given");
|
fatal("no DH parameters specified");
|
||||||
|
|
||||||
SSL_CTX_set_tmp_dh(dom->ssl_ctx, tls_dhparam);
|
SSL_CTX_set_tmp_dh(dom->ssl_ctx, tls_dhparam);
|
||||||
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_SINGLE_DH_USE);
|
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_SINGLE_DH_USE);
|
||||||
|
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
if (!SSL_CTX_set_ecdh_auto(dom->ssl_ctx, 1))
|
if (!SSL_CTX_set_ecdh_auto(dom->ssl_ctx, 1))
|
||||||
fatalx("SSL_CTX_set_ecdh_auto: %s", ssl_errno_s);
|
fatalx("SSL_CTX_set_ecdh_auto: %s", ssl_errno_s);
|
||||||
#else
|
|
||||||
if ((ecdh = EC_KEY_new_by_curve_name(NID_secp384r1)) == NULL)
|
|
||||||
fatalx("EC_KEY_new_by_curve_name: %s", ssl_errno_s);
|
|
||||||
|
|
||||||
SSL_CTX_set_tmp_ecdh(dom->ssl_ctx, ecdh);
|
|
||||||
EC_KEY_free(ecdh);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
|
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
|
||||||
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_COMPRESSION);
|
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_COMPRESSION);
|
||||||
@ -605,27 +511,17 @@ keymgr_init(void)
|
|||||||
if ((meth = RSA_get_default_method()) == NULL)
|
if ((meth = RSA_get_default_method()) == NULL)
|
||||||
fatal("failed to obtain RSA method");
|
fatal("failed to obtain RSA method");
|
||||||
|
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
RSA_meth_set_pub_enc(keymgr_rsa_meth, RSA_meth_get_pub_enc(meth));
|
RSA_meth_set_pub_enc(keymgr_rsa_meth, RSA_meth_get_pub_enc(meth));
|
||||||
RSA_meth_set_pub_dec(keymgr_rsa_meth, RSA_meth_get_pub_dec(meth));
|
RSA_meth_set_pub_dec(keymgr_rsa_meth, RSA_meth_get_pub_dec(meth));
|
||||||
RSA_meth_set_bn_mod_exp(keymgr_rsa_meth, RSA_meth_get_bn_mod_exp(meth));
|
RSA_meth_set_bn_mod_exp(keymgr_rsa_meth, RSA_meth_get_bn_mod_exp(meth));
|
||||||
#else
|
|
||||||
keymgr_rsa.rsa_pub_enc = meth->rsa_pub_enc;
|
|
||||||
keymgr_rsa.rsa_pub_dec = meth->rsa_pub_dec;
|
|
||||||
keymgr_rsa.bn_mod_exp = meth->bn_mod_exp;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
keymgr_rsa_init(RSA *rsa)
|
keymgr_rsa_init(RSA *rsa)
|
||||||
{
|
{
|
||||||
if (rsa != NULL) {
|
if (rsa != NULL) {
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
RSA_set_flags(rsa, RSA_flags(rsa) |
|
RSA_set_flags(rsa, RSA_flags(rsa) |
|
||||||
RSA_FLAG_EXT_PKEY | RSA_METHOD_FLAG_NO_CHECK);
|
RSA_FLAG_EXT_PKEY | RSA_METHOD_FLAG_NO_CHECK);
|
||||||
#else
|
|
||||||
rsa->flags |= RSA_FLAG_EXT_PKEY | RSA_METHOD_FLAG_NO_CHECK;
|
|
||||||
#endif
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -702,13 +598,8 @@ keymgr_ecdsa_sign(const unsigned char *dgst, int dgst_len,
|
|||||||
if (len > sizeof(keymgr_buf))
|
if (len > sizeof(keymgr_buf))
|
||||||
fatal("keymgr_buf too small");
|
fatal("keymgr_buf too small");
|
||||||
|
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
if ((dom = EC_KEY_get_ex_data(eckey, 0)) == NULL)
|
if ((dom = EC_KEY_get_ex_data(eckey, 0)) == NULL)
|
||||||
fatal("EC_KEY has no domain");
|
fatal("EC_KEY has no domain");
|
||||||
#else
|
|
||||||
if ((dom = ECDSA_get_ex_data(eckey, 0)) == NULL)
|
|
||||||
fatal("EC_KEY has no domain");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memset(keymgr_buf, 0, sizeof(keymgr_buf));
|
memset(keymgr_buf, 0, sizeof(keymgr_buf));
|
||||||
req = (struct kore_keyreq *)keymgr_buf;
|
req = (struct kore_keyreq *)keymgr_buf;
|
||||||
@ -890,23 +781,13 @@ domain_load_certificate_chain(SSL_CTX *ctx, const void *data, size_t len)
|
|||||||
if (SSL_CTX_use_certificate(ctx, x) == 0)
|
if (SSL_CTX_use_certificate(ctx, x) == 0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
SSL_CTX_clear_chain_certs(ctx);
|
SSL_CTX_clear_chain_certs(ctx);
|
||||||
#else
|
|
||||||
sk_X509_pop_free(ctx->extra_certs, X509_free);
|
|
||||||
ctx->extra_certs = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL)) != NULL) {
|
while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL)) != NULL) {
|
||||||
/* ca its reference count won't be increased. */
|
/* ca its reference count won't be increased. */
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
if (SSL_CTX_add0_chain_cert(ctx, ca) == 0)
|
if (SSL_CTX_add0_chain_cert(ctx, ca) == 0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
#else
|
|
||||||
if (SSL_CTX_add_extra_chain_cert(ctx, ca) == 0)
|
|
||||||
return (NULL);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ERR_peek_last_error();
|
err = ERR_peek_last_error();
|
||||||
|
@ -58,7 +58,7 @@ kore_filemap_create(struct kore_domain *dom, const char *path, const char *root)
|
|||||||
size_t sz;
|
size_t sz;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int len;
|
int len;
|
||||||
struct kore_module_handle *hdlr;
|
struct kore_route *rt;
|
||||||
struct filemap_entry *entry;
|
struct filemap_entry *entry;
|
||||||
char regex[1024], fpath[PATH_MAX];
|
char regex[1024], fpath[PATH_MAX];
|
||||||
|
|
||||||
@ -69,9 +69,9 @@ kore_filemap_create(struct kore_domain *dom, const char *path, const char *root)
|
|||||||
if (root[0] != '/' || root[sz - 1] != '/')
|
if (root[0] != '/' || root[sz - 1] != '/')
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
|
|
||||||
if (kore_root_path != NULL) {
|
if (worker_privsep.root != NULL) {
|
||||||
len = snprintf(fpath, sizeof(fpath), "%s/%s",
|
len = snprintf(fpath, sizeof(fpath), "%s/%s",
|
||||||
kore_root_path, path);
|
worker_privsep.root, path);
|
||||||
if (len == -1 || (size_t)len >= sizeof(fpath))
|
if (len == -1 || (size_t)len >= sizeof(fpath))
|
||||||
fatal("kore_filemap_create: failed to concat paths");
|
fatal("kore_filemap_create: failed to concat paths");
|
||||||
} else {
|
} else {
|
||||||
@ -79,27 +79,21 @@ kore_filemap_create(struct kore_domain *dom, const char *path, const char *root)
|
|||||||
fatal("kore_filemap_create: failed to copy path");
|
fatal("kore_filemap_create: failed to copy path");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat(fpath, &st) == -1)
|
if (stat(fpath, &st) == -1) {
|
||||||
|
kore_log(LOG_ERR, "%s: failed to stat '%s': %s", __func__,
|
||||||
|
fpath, errno_s);
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
len = snprintf(regex, sizeof(regex), "^%s.*$", root);
|
len = snprintf(regex, sizeof(regex), "^%s.*$", root);
|
||||||
if (len == -1 || (size_t)len >= sizeof(regex))
|
if (len == -1 || (size_t)len >= sizeof(regex))
|
||||||
fatal("kore_filemap_create: buffer too small");
|
fatal("kore_filemap_create: buffer too small");
|
||||||
|
|
||||||
if (!kore_module_handler_new(dom, regex, "filemap_resolve",
|
if ((rt = kore_route_create(dom, regex, HANDLER_TYPE_DYNAMIC)) == NULL)
|
||||||
NULL, HANDLER_TYPE_DYNAMIC))
|
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
|
|
||||||
hdlr = NULL;
|
kore_route_callback(rt, "filemap_resolve");
|
||||||
TAILQ_FOREACH(hdlr, &dom->handlers, list) {
|
rt->methods = HTTP_METHOD_GET | HTTP_METHOD_HEAD;
|
||||||
if (!strcmp(hdlr->path, regex))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hdlr == NULL)
|
|
||||||
fatal("couldn't find newly created handler for filemap");
|
|
||||||
|
|
||||||
hdlr->methods = HTTP_METHOD_GET | HTTP_METHOD_HEAD;
|
|
||||||
|
|
||||||
entry = kore_calloc(1, sizeof(*entry));
|
entry = kore_calloc(1, sizeof(*entry));
|
||||||
entry->domain = dom;
|
entry->domain = dom;
|
||||||
@ -151,7 +145,7 @@ filemap_resolve(struct http_request *req)
|
|||||||
best_len = 0;
|
best_len = 0;
|
||||||
|
|
||||||
TAILQ_FOREACH(entry, &maps, list) {
|
TAILQ_FOREACH(entry, &maps, list) {
|
||||||
if (entry->domain != req->hdlr->dom)
|
if (entry->domain != req->rt->dom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!strncmp(entry->root, req->path, entry->root_len)) {
|
if (!strncmp(entry->root, req->path, entry->root_len)) {
|
||||||
|
@ -79,7 +79,7 @@ kore_fileref_create(struct kore_server *srv, const char *path, int fd,
|
|||||||
if (srv->tls == 0) {
|
if (srv->tls == 0) {
|
||||||
ref->fd = fd;
|
ref->fd = fd;
|
||||||
} else {
|
} else {
|
||||||
if ((uintmax_t)size> SIZE_MAX) {
|
if ((uintmax_t)size > SIZE_MAX) {
|
||||||
kore_pool_put(&ref_pool, ref);
|
kore_pool_put(&ref_pool, ref);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
1753
src/http.c
1753
src/http.c
File diff suppressed because it is too large
Load Diff
116
src/json.c
116
src/json.c
@ -49,6 +49,8 @@ static u_int8_t json_null_literal[] = { 'n', 'u', 'l', 'l' };
|
|||||||
static u_int8_t json_true_literal[] = { 't', 'r', 'u', 'e' };
|
static u_int8_t json_true_literal[] = { 't', 'r', 'u', 'e' };
|
||||||
static u_int8_t json_false_literal[] = { 'f', 'a', 'l', 's', 'e' };
|
static u_int8_t json_false_literal[] = { 'f', 'a', 'l', 's', 'e' };
|
||||||
|
|
||||||
|
static int json_errno = 0;
|
||||||
|
|
||||||
static const char *json_errtab[] = {
|
static const char *json_errtab[] = {
|
||||||
"no error",
|
"no error",
|
||||||
"invalid JSON object",
|
"invalid JSON object",
|
||||||
@ -84,8 +86,10 @@ kore_json_parse(struct kore_json *json)
|
|||||||
if (json->root)
|
if (json->root)
|
||||||
return (KORE_RESULT_OK);
|
return (KORE_RESULT_OK);
|
||||||
|
|
||||||
|
json_errno = 0;
|
||||||
|
|
||||||
if (json_consume_whitespace(json) == -1) {
|
if (json_consume_whitespace(json) == -1) {
|
||||||
json->error = KORE_JSON_ERR_INVALID_JSON;
|
json_errno = KORE_JSON_ERR_INVALID_JSON;
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,22 +97,22 @@ kore_json_parse(struct kore_json *json)
|
|||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
|
|
||||||
if (!json_guess_type(ch, &type)) {
|
if (!json_guess_type(ch, &type)) {
|
||||||
json->error = KORE_JSON_ERR_INVALID_JSON;
|
json_errno = KORE_JSON_ERR_INVALID_JSON;
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
json->root = json_item_alloc(type, NULL, NULL);
|
json->root = json_item_alloc(type, NULL, NULL);
|
||||||
|
|
||||||
if (!json->root->parse(json, json->root)) {
|
if (!json->root->parse(json, json->root)) {
|
||||||
if (json->error == 0)
|
if (json_errno == 0)
|
||||||
json->error = KORE_JSON_ERR_INVALID_JSON;
|
json_errno = KORE_JSON_ERR_INVALID_JSON;
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't allow garbage at the end. */
|
/* Don't allow garbage at the end. */
|
||||||
(void)json_consume_whitespace(json);
|
(void)json_consume_whitespace(json);
|
||||||
if (json->offset != json->length) {
|
if (json->offset != json->length) {
|
||||||
json->error = KORE_JSON_ERR_INVALID_JSON;
|
json_errno = KORE_JSON_ERR_INVALID_JSON;
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,16 +126,21 @@ kore_json_find(struct kore_json_item *root, const char *path, u_int32_t type)
|
|||||||
char *copy;
|
char *copy;
|
||||||
char *tokens[KORE_JSON_DEPTH_MAX + 1];
|
char *tokens[KORE_JSON_DEPTH_MAX + 1];
|
||||||
|
|
||||||
|
json_errno = 0;
|
||||||
copy = kore_strdup(path);
|
copy = kore_strdup(path);
|
||||||
|
|
||||||
if (!kore_split_string(copy, "/", tokens, KORE_JSON_DEPTH_MAX)) {
|
if (!kore_split_string(copy, "/", tokens, KORE_JSON_DEPTH_MAX)) {
|
||||||
kore_free(copy);
|
kore_free(copy);
|
||||||
|
json_errno = KORE_JSON_ERR_INVALID_SEARCH;
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
item = json_find_item(root, tokens, type, 0);
|
item = json_find_item(root, tokens, type, 0);
|
||||||
kore_free(copy);
|
kore_free(copy);
|
||||||
|
|
||||||
|
if (item == NULL && json_errno == 0)
|
||||||
|
json_errno = KORE_JSON_ERR_INVALID_SEARCH;
|
||||||
|
|
||||||
return (item);
|
return (item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,11 +154,17 @@ kore_json_cleanup(struct kore_json *json)
|
|||||||
kore_json_item_free(json->root);
|
kore_json_item_free(json->root);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
int
|
||||||
kore_json_strerror(struct kore_json *json)
|
kore_json_errno(void)
|
||||||
{
|
{
|
||||||
if (json->error >= 0 && json->error <= KORE_JSON_ERR_LAST)
|
return (json_errno);
|
||||||
return (json_errtab[json->error]);
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
kore_json_strerror(void)
|
||||||
|
{
|
||||||
|
if (json_errno >= 0 && json_errno <= KORE_JSON_ERR_LAST)
|
||||||
|
return (json_errtab[json_errno]);
|
||||||
|
|
||||||
return ("unknown JSON error");
|
return ("unknown JSON error");
|
||||||
}
|
}
|
||||||
@ -182,7 +197,7 @@ kore_json_create_item(struct kore_json_item *parent, const char *name,
|
|||||||
item->data.number = va_arg(args, double);
|
item->data.number = va_arg(args, double);
|
||||||
break;
|
break;
|
||||||
case KORE_JSON_TYPE_INTEGER:
|
case KORE_JSON_TYPE_INTEGER:
|
||||||
item->data.s64 = va_arg(args, int64_t);
|
item->data.integer = va_arg(args, int64_t);
|
||||||
break;
|
break;
|
||||||
case KORE_JSON_TYPE_INTEGER_U64:
|
case KORE_JSON_TYPE_INTEGER_U64:
|
||||||
item->data.u64 = va_arg(args, u_int64_t);
|
item->data.u64 = va_arg(args, u_int64_t);
|
||||||
@ -248,7 +263,7 @@ kore_json_item_tobuf(struct kore_json_item *item, struct kore_buf *buf)
|
|||||||
kore_buf_appendf(buf, "%f", item->data.number);
|
kore_buf_appendf(buf, "%f", item->data.number);
|
||||||
break;
|
break;
|
||||||
case KORE_JSON_TYPE_INTEGER:
|
case KORE_JSON_TYPE_INTEGER:
|
||||||
kore_buf_appendf(buf, "%" PRId64, item->data.s64);
|
kore_buf_appendf(buf, "%" PRId64, item->data.integer);
|
||||||
break;
|
break;
|
||||||
case KORE_JSON_TYPE_INTEGER_U64:
|
case KORE_JSON_TYPE_INTEGER_U64:
|
||||||
kore_buf_appendf(buf, "%" PRIu64, item->data.u64);
|
kore_buf_appendf(buf, "%" PRIu64, item->data.u64);
|
||||||
@ -277,6 +292,24 @@ kore_json_item_tobuf(struct kore_json_item *item, struct kore_buf *buf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_json_item_attach(struct kore_json_item *parent,
|
||||||
|
struct kore_json_item *item)
|
||||||
|
{
|
||||||
|
if (item->parent != NULL)
|
||||||
|
fatal("%s: item already has parent", __func__);
|
||||||
|
|
||||||
|
item->parent = parent;
|
||||||
|
|
||||||
|
if (parent->type != KORE_JSON_TYPE_OBJECT &&
|
||||||
|
parent->type != KORE_JSON_TYPE_ARRAY) {
|
||||||
|
fatal("%s: invalid parent type (%d)",
|
||||||
|
__func__, parent->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
TAILQ_INSERT_TAIL(&parent->data.items, item, list);
|
||||||
|
}
|
||||||
|
|
||||||
static struct kore_json_item *
|
static struct kore_json_item *
|
||||||
json_find_item(struct kore_json_item *object, char **tokens,
|
json_find_item(struct kore_json_item *object, char **tokens,
|
||||||
u_int32_t type, int pos)
|
u_int32_t type, int pos)
|
||||||
@ -321,15 +354,33 @@ json_find_item(struct kore_json_item *object, char **tokens,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nitem == NULL)
|
if (nitem == NULL) {
|
||||||
|
json_errno = KORE_JSON_ERR_NOT_FOUND;
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
item = nitem;
|
item = nitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokens[pos + 1] == NULL) {
|
if (tokens[pos + 1] == NULL) {
|
||||||
|
/*
|
||||||
|
* If an uint64 was required and we find an item
|
||||||
|
* with the same name but marked as an integer check
|
||||||
|
* if it can be represented as a uint64.
|
||||||
|
*
|
||||||
|
* If it can, reduce the type to integer so we match
|
||||||
|
* on it as well.
|
||||||
|
*/
|
||||||
|
if (type == KORE_JSON_TYPE_INTEGER_U64 &&
|
||||||
|
item->type == KORE_JSON_TYPE_INTEGER) {
|
||||||
|
if (item->data.integer >= 0)
|
||||||
|
type = KORE_JSON_TYPE_INTEGER;
|
||||||
|
}
|
||||||
|
|
||||||
if (item->type == type)
|
if (item->type == type)
|
||||||
return (item);
|
return (item);
|
||||||
|
|
||||||
|
json_errno = KORE_JSON_ERR_TYPE_MISMATCH;
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,6 +394,9 @@ json_find_item(struct kore_json_item *object, char **tokens,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item == NULL && json_errno == 0)
|
||||||
|
json_errno = KORE_JSON_ERR_NOT_FOUND;
|
||||||
|
|
||||||
return (item);
|
return (item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,7 +497,7 @@ static int
|
|||||||
json_next_byte(struct kore_json *json, u_int8_t *ch, int peek)
|
json_next_byte(struct kore_json *json, u_int8_t *ch, int peek)
|
||||||
{
|
{
|
||||||
if (json->offset >= json->length) {
|
if (json->offset >= json->length) {
|
||||||
json->error = KORE_JSON_ERR_EOF;
|
json_errno = KORE_JSON_ERR_EOF;
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,7 +567,7 @@ json_parse_object(struct kore_json *json, struct kore_json_item *object)
|
|||||||
int ret, hasnext;
|
int ret, hasnext;
|
||||||
|
|
||||||
if (json->depth++ >= KORE_JSON_DEPTH_MAX) {
|
if (json->depth++ >= KORE_JSON_DEPTH_MAX) {
|
||||||
json->error = KORE_JSON_ERR_DEPTH;
|
json_errno = KORE_JSON_ERR_DEPTH;
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,7 +591,7 @@ json_parse_object(struct kore_json *json, struct kore_json_item *object)
|
|||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '}':
|
case '}':
|
||||||
if (hasnext) {
|
if (hasnext) {
|
||||||
json->error = KORE_JSON_ERR_INVALID_JSON;
|
json_errno = KORE_JSON_ERR_INVALID_JSON;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
json->offset++;
|
json->offset++;
|
||||||
@ -596,8 +650,8 @@ json_parse_object(struct kore_json *json, struct kore_json_item *object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (ret == KORE_RESULT_ERROR && json->error == 0)
|
if (ret == KORE_RESULT_ERROR && json_errno == 0)
|
||||||
json->error = KORE_JSON_ERR_INVALID_OBJECT;
|
json_errno = KORE_JSON_ERR_INVALID_OBJECT;
|
||||||
|
|
||||||
json->depth--;
|
json->depth--;
|
||||||
|
|
||||||
@ -614,7 +668,7 @@ json_parse_array(struct kore_json *json, struct kore_json_item *array)
|
|||||||
int ret, hasnext;
|
int ret, hasnext;
|
||||||
|
|
||||||
if (json->depth++ >= KORE_JSON_DEPTH_MAX) {
|
if (json->depth++ >= KORE_JSON_DEPTH_MAX) {
|
||||||
json->error = KORE_JSON_ERR_DEPTH;
|
json_errno = KORE_JSON_ERR_DEPTH;
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,7 +691,7 @@ json_parse_array(struct kore_json *json, struct kore_json_item *array)
|
|||||||
|
|
||||||
if (ch == ']') {
|
if (ch == ']') {
|
||||||
if (hasnext) {
|
if (hasnext) {
|
||||||
json->error = KORE_JSON_ERR_INVALID_JSON;
|
json_errno = KORE_JSON_ERR_INVALID_JSON;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
json->offset++;
|
json->offset++;
|
||||||
@ -675,8 +729,8 @@ json_parse_array(struct kore_json *json, struct kore_json_item *array)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (ret == KORE_RESULT_ERROR && json->error == 0)
|
if (ret == KORE_RESULT_ERROR && json_errno == 0)
|
||||||
json->error = KORE_JSON_ERR_INVALID_ARRAY;
|
json_errno = KORE_JSON_ERR_INVALID_ARRAY;
|
||||||
|
|
||||||
json->depth--;
|
json->depth--;
|
||||||
|
|
||||||
@ -762,10 +816,14 @@ json_parse_number(struct kore_json *json, struct kore_json_item *number)
|
|||||||
kore_strtodouble(str, -DBL_MAX, DBL_MAX, &ret);
|
kore_strtodouble(str, -DBL_MAX, DBL_MAX, &ret);
|
||||||
break;
|
break;
|
||||||
case KORE_JSON_TYPE_INTEGER:
|
case KORE_JSON_TYPE_INTEGER:
|
||||||
number->data.s64 = (int64_t)kore_strtonum64(str, 1, &ret);
|
number->data.integer = (int64_t)kore_strtonum64(str, 1, &ret);
|
||||||
break;
|
break;
|
||||||
case KORE_JSON_TYPE_INTEGER_U64:
|
case KORE_JSON_TYPE_INTEGER_U64:
|
||||||
number->data.s64 = kore_strtonum64(str, 0, &ret);
|
number->data.u64 = kore_strtonum64(str, 0, &ret);
|
||||||
|
if (number->data.u64 <= INT64_MAX) {
|
||||||
|
type = KORE_JSON_TYPE_INTEGER;
|
||||||
|
number->data.integer = number->data.u64;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -774,8 +832,8 @@ json_parse_number(struct kore_json *json, struct kore_json_item *number)
|
|||||||
number->type = type;
|
number->type = type;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (ret == KORE_RESULT_ERROR && json->error == 0)
|
if (ret == KORE_RESULT_ERROR && json_errno == 0)
|
||||||
json->error = KORE_JSON_ERR_INVALID_NUMBER;
|
json_errno = KORE_JSON_ERR_INVALID_NUMBER;
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
@ -826,8 +884,8 @@ json_parse_literal(struct kore_json *json, struct kore_json_item *literal)
|
|||||||
ret = KORE_RESULT_OK;
|
ret = KORE_RESULT_OK;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (ret == KORE_RESULT_ERROR && json->error == 0)
|
if (ret == KORE_RESULT_ERROR && json_errno == 0)
|
||||||
json->error = KORE_JSON_ERR_INVALID_LITERAL;
|
json_errno = KORE_JSON_ERR_INVALID_LITERAL;
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
@ -895,8 +953,8 @@ json_get_string(struct kore_json *json)
|
|||||||
res = kore_buf_stringify(&json->tmpbuf, NULL);
|
res = kore_buf_stringify(&json->tmpbuf, NULL);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (res == NULL && json->error == 0)
|
if (res == NULL && json_errno == 0)
|
||||||
json->error = KORE_JSON_ERR_INVALID_STRING;
|
json_errno = KORE_JSON_ERR_INVALID_STRING;
|
||||||
|
|
||||||
return (res);
|
return (res);
|
||||||
}
|
}
|
||||||
|
@ -423,13 +423,13 @@ jsonrpc_error(struct jsonrpc_request *req, int code, const char *msg)
|
|||||||
http_response_header(req->http, "content-type", "application/json");
|
http_response_header(req->http, "content-type", "application/json");
|
||||||
yajl_gen_get_buf(req->gen, &body, &body_len);
|
yajl_gen_get_buf(req->gen, &body, &body_len);
|
||||||
succeeded:
|
succeeded:
|
||||||
http_response(req->http, 200, body, body_len);
|
http_response(req->http, HTTP_STATUS_OK, body, body_len);
|
||||||
if (req->gen != NULL)
|
if (req->gen != NULL)
|
||||||
yajl_gen_clear(req->gen);
|
yajl_gen_clear(req->gen);
|
||||||
jsonrpc_destroy_request(req);
|
jsonrpc_destroy_request(req);
|
||||||
return (KORE_RESULT_OK);
|
return (KORE_RESULT_OK);
|
||||||
failed:
|
failed:
|
||||||
http_response(req->http, 500, NULL, 0);
|
http_response(req->http, HTTP_STATUS_INTERNAL_ERROR, NULL, 0);
|
||||||
jsonrpc_destroy_request(req);
|
jsonrpc_destroy_request(req);
|
||||||
return (KORE_RESULT_OK);
|
return (KORE_RESULT_OK);
|
||||||
}
|
}
|
||||||
@ -466,13 +466,13 @@ jsonrpc_result(struct jsonrpc_request *req,
|
|||||||
http_response_header(req->http, "content-type", "application/json");
|
http_response_header(req->http, "content-type", "application/json");
|
||||||
yajl_gen_get_buf(req->gen, &body, &body_len);
|
yajl_gen_get_buf(req->gen, &body, &body_len);
|
||||||
succeeded:
|
succeeded:
|
||||||
http_response(req->http, 200, body, body_len);
|
http_response(req->http, HTTP_STATUS_OK, body, body_len);
|
||||||
if (req->gen != NULL)
|
if (req->gen != NULL)
|
||||||
yajl_gen_clear(req->gen);
|
yajl_gen_clear(req->gen);
|
||||||
jsonrpc_destroy_request(req);
|
jsonrpc_destroy_request(req);
|
||||||
return (KORE_RESULT_OK);
|
return (KORE_RESULT_OK);
|
||||||
failed:
|
failed:
|
||||||
http_response(req->http, 500, NULL, 0);
|
http_response(req->http, HTTP_STATUS_INTERNAL_ERROR, NULL, 0);
|
||||||
jsonrpc_destroy_request(req);
|
jsonrpc_destroy_request(req);
|
||||||
return (KORE_RESULT_OK);
|
return (KORE_RESULT_OK);
|
||||||
}
|
}
|
||||||
|
51
src/keymgr.c
51
src/keymgr.c
@ -87,6 +87,9 @@ static struct sock_filter filter_keymgr[] = {
|
|||||||
KORE_SYSCALL_ALLOW(fstat),
|
KORE_SYSCALL_ALLOW(fstat),
|
||||||
#if defined(SYS_fstat64)
|
#if defined(SYS_fstat64)
|
||||||
KORE_SYSCALL_ALLOW(fstat64),
|
KORE_SYSCALL_ALLOW(fstat64),
|
||||||
|
#endif
|
||||||
|
#if defined(SYS_newfstatat)
|
||||||
|
KORE_SYSCALL_ALLOW(newfstatat),
|
||||||
#endif
|
#endif
|
||||||
KORE_SYSCALL_ALLOW(futex),
|
KORE_SYSCALL_ALLOW(futex),
|
||||||
KORE_SYSCALL_ALLOW(writev),
|
KORE_SYSCALL_ALLOW(writev),
|
||||||
@ -137,6 +140,9 @@ static struct sock_filter filter_keymgr[] = {
|
|||||||
#endif
|
#endif
|
||||||
#if defined(SYS_mmap2)
|
#if defined(SYS_mmap2)
|
||||||
KORE_SYSCALL_ALLOW(mmap2),
|
KORE_SYSCALL_ALLOW(mmap2),
|
||||||
|
#endif
|
||||||
|
#if defined(SYS_madvise)
|
||||||
|
KORE_SYSCALL_ALLOW(madvise),
|
||||||
#endif
|
#endif
|
||||||
KORE_SYSCALL_ALLOW(munmap),
|
KORE_SYSCALL_ALLOW(munmap),
|
||||||
KORE_SYSCALL_ALLOW(clock_gettime),
|
KORE_SYSCALL_ALLOW(clock_gettime),
|
||||||
@ -245,9 +251,8 @@ static void keymgr_rsa_encrypt(struct kore_msg *, const void *,
|
|||||||
static void keymgr_ecdsa_sign(struct kore_msg *, const void *,
|
static void keymgr_ecdsa_sign(struct kore_msg *, const void *,
|
||||||
struct key *);
|
struct key *);
|
||||||
|
|
||||||
|
struct kore_privsep keymgr_privsep;
|
||||||
int keymgr_active = 0;
|
int keymgr_active = 0;
|
||||||
char *keymgr_root_path = NULL;
|
|
||||||
char *keymgr_runas_user = NULL;
|
|
||||||
|
|
||||||
#if defined(__OpenBSD__)
|
#if defined(__OpenBSD__)
|
||||||
#if defined(KORE_USE_ACME)
|
#if defined(KORE_USE_ACME)
|
||||||
@ -290,10 +295,7 @@ kore_keymgr_run(void)
|
|||||||
#if defined(KORE_USE_PYTHON)
|
#if defined(KORE_USE_PYTHON)
|
||||||
kore_msg_unregister(KORE_PYTHON_SEND_OBJ);
|
kore_msg_unregister(KORE_PYTHON_SEND_OBJ);
|
||||||
#endif
|
#endif
|
||||||
kore_worker_privdrop(keymgr_runas_user, keymgr_root_path);
|
kore_worker_privsep();
|
||||||
|
|
||||||
if (!kore_quiet)
|
|
||||||
kore_log(LOG_NOTICE, "key manager started (pid#%d)", getpid());
|
|
||||||
|
|
||||||
if (rand_file != NULL) {
|
if (rand_file != NULL) {
|
||||||
keymgr_load_randfile();
|
keymgr_load_randfile();
|
||||||
@ -318,6 +320,8 @@ kore_keymgr_run(void)
|
|||||||
X509V3_EXT_add_alias(acme_oid, NID_subject_key_identifier);
|
X509V3_EXT_add_alias(acme_oid, NID_subject_key_identifier);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
kore_worker_started();
|
||||||
|
|
||||||
while (quit != 1) {
|
while (quit != 1) {
|
||||||
now = kore_time_ms();
|
now = kore_time_ms();
|
||||||
if ((now - last_seed) > RAND_POLL_INTERVAL) {
|
if ((now - last_seed) > RAND_POLL_INTERVAL) {
|
||||||
@ -363,9 +367,6 @@ kore_keymgr_cleanup(int final)
|
|||||||
{
|
{
|
||||||
struct key *key, *next;
|
struct key *key, *next;
|
||||||
|
|
||||||
if (final && !kore_quiet)
|
|
||||||
kore_log(LOG_NOTICE, "cleaning up keys");
|
|
||||||
|
|
||||||
if (initialized == 0)
|
if (initialized == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -574,6 +575,7 @@ keymgr_load_domain_privatekey(struct kore_domain *dom)
|
|||||||
|
|
||||||
key->dom = dom;
|
key->dom = dom;
|
||||||
|
|
||||||
|
if (!kore_quiet)
|
||||||
kore_log(LOG_INFO, "loaded private key for '%s'", dom->domain);
|
kore_log(LOG_INFO, "loaded private key for '%s'", dom->domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -690,12 +692,8 @@ keymgr_rsa_encrypt(struct kore_msg *msg, const void *data, struct key *key)
|
|||||||
u_int8_t buf[1024];
|
u_int8_t buf[1024];
|
||||||
|
|
||||||
req = (const struct kore_keyreq *)data;
|
req = (const struct kore_keyreq *)data;
|
||||||
|
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
rsa = EVP_PKEY_get0_RSA(key->pkey);
|
rsa = EVP_PKEY_get0_RSA(key->pkey);
|
||||||
#else
|
|
||||||
rsa = key->pkey->pkey.rsa;
|
|
||||||
#endif
|
|
||||||
keylen = RSA_size(rsa);
|
keylen = RSA_size(rsa);
|
||||||
if (req->data_len > keylen || keylen > sizeof(buf))
|
if (req->data_len > keylen || keylen > sizeof(buf))
|
||||||
return;
|
return;
|
||||||
@ -718,11 +716,8 @@ keymgr_ecdsa_sign(struct kore_msg *msg, const void *data, struct key *key)
|
|||||||
u_int8_t sig[1024];
|
u_int8_t sig[1024];
|
||||||
|
|
||||||
req = (const struct kore_keyreq *)data;
|
req = (const struct kore_keyreq *)data;
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
ec = EVP_PKEY_get0_EC_KEY(key->pkey);
|
ec = EVP_PKEY_get0_EC_KEY(key->pkey);
|
||||||
#else
|
|
||||||
ec = key->pkey->pkey.ec;
|
|
||||||
#endif
|
|
||||||
len = ECDSA_size(ec);
|
len = ECDSA_size(ec);
|
||||||
if (req->data_len > len || len > sizeof(sig))
|
if (req->data_len > len || len > sizeof(sig))
|
||||||
return;
|
return;
|
||||||
@ -791,21 +786,15 @@ keymgr_acme_init(void)
|
|||||||
ACME_RENEWAL_TIMER, NULL, 0);
|
ACME_RENEWAL_TIMER, NULL, 0);
|
||||||
|
|
||||||
if (key->pkey == NULL) {
|
if (key->pkey == NULL) {
|
||||||
kore_log(LOG_NOTICE, "generating new ACME account key");
|
kore_log(LOG_INFO, "generating new ACME account key");
|
||||||
key->pkey = kore_rsakey_generate(KORE_ACME_ACCOUNT_KEY);
|
key->pkey = kore_rsakey_generate(KORE_ACME_ACCOUNT_KEY);
|
||||||
needsreg = 1;
|
needsreg = 1;
|
||||||
} else {
|
} else {
|
||||||
kore_log(LOG_INFO, "loaded existing ACME account key");
|
kore_log(LOG_INFO, "loaded existing ACME account key");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(KORE_OPENSSL_NEWER_API)
|
|
||||||
rsa = EVP_PKEY_get0_RSA(key->pkey);
|
rsa = EVP_PKEY_get0_RSA(key->pkey);
|
||||||
RSA_get0_key(rsa, &bn, &be, NULL);
|
RSA_get0_key(rsa, &bn, &be, NULL);
|
||||||
#else
|
|
||||||
rsa = key->pkey->pkey.rsa;
|
|
||||||
be = rsa->e;
|
|
||||||
bn = rsa->n;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
e = keymgr_bignum_base64(be);
|
e = keymgr_bignum_base64(be);
|
||||||
n = keymgr_bignum_base64(bn);
|
n = keymgr_bignum_base64(bn);
|
||||||
@ -837,7 +826,7 @@ keymgr_acme_domainkey(struct kore_domain *dom, struct key *key)
|
|||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
kore_log(LOG_NOTICE, "generated new domain key for %s", dom->domain);
|
kore_log(LOG_INFO, "generated new domain key for %s", dom->domain);
|
||||||
|
|
||||||
if ((p = strrchr(dom->certkey, '/')) == NULL)
|
if ((p = strrchr(dom->certkey, '/')) == NULL)
|
||||||
fatalx("invalid certkey path '%s'", dom->certkey);
|
fatalx("invalid certkey path '%s'", dom->certkey);
|
||||||
@ -1038,7 +1027,7 @@ keymgr_acme_install_cert(const void *data, size_t len, struct key *key)
|
|||||||
|
|
||||||
fd = open(key->dom->certfile, O_CREAT | O_TRUNC | O_WRONLY, 0700);
|
fd = open(key->dom->certfile, O_CREAT | O_TRUNC | O_WRONLY, 0700);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
fatal("open(%s): %s", key->dom->certfile, errno_s);
|
fatalx("open(%s): %s", key->dom->certfile, errno_s);
|
||||||
|
|
||||||
kore_log(LOG_INFO, "writing %zu bytes of data", len);
|
kore_log(LOG_INFO, "writing %zu bytes of data", len);
|
||||||
|
|
||||||
@ -1047,14 +1036,14 @@ keymgr_acme_install_cert(const void *data, size_t len, struct key *key)
|
|||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
fatal("write(%s): %s", key->dom->certfile, errno_s);
|
fatalx("write(%s): %s", key->dom->certfile, errno_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((size_t)ret != len) {
|
if ((size_t)ret != len) {
|
||||||
fatal("incorrect write on %s (%zd/%zu)",
|
fatalx("incorrect write on %s (%zd/%zu)",
|
||||||
key->dom->certfile, ret, len);
|
key->dom->certfile, ret, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1111,7 +1100,7 @@ keymgr_acme_challenge_cert(const void *data, size_t len, struct key *key)
|
|||||||
slen = snprintf(hex + (idx * 2), sizeof(hex) - (idx * 2),
|
slen = snprintf(hex + (idx * 2), sizeof(hex) - (idx * 2),
|
||||||
"%02x", digest[idx]);
|
"%02x", digest[idx]);
|
||||||
if (slen == -1 || (size_t)slen >= sizeof(hex))
|
if (slen == -1 || (size_t)slen >= sizeof(hex))
|
||||||
fatal("failed to convert digest to hex");
|
fatalx("failed to convert digest to hex");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((x509 = X509_new()) == NULL)
|
if ((x509 = X509_new()) == NULL)
|
||||||
@ -1185,7 +1174,7 @@ keymgr_acme_csr(const struct kore_keyreq *req, struct key *key)
|
|||||||
kore_log(LOG_INFO, "[%s] creating CSR", req->domain);
|
kore_log(LOG_INFO, "[%s] creating CSR", req->domain);
|
||||||
|
|
||||||
if ((csr = X509_REQ_new()) == NULL)
|
if ((csr = X509_REQ_new()) == NULL)
|
||||||
fatal("X509_REQ_new: %s", ssl_errno_s);
|
fatalx("X509_REQ_new: %s", ssl_errno_s);
|
||||||
|
|
||||||
if (!X509_REQ_set_version(csr, 3))
|
if (!X509_REQ_set_version(csr, 3))
|
||||||
fatalx("X509_REQ_set_version(): %s", ssl_errno_s);
|
fatalx("X509_REQ_set_version(): %s", ssl_errno_s);
|
||||||
|
189
src/kore.c
189
src/kore.c
@ -54,6 +54,7 @@ volatile sig_atomic_t sig_recv;
|
|||||||
struct kore_server_list kore_servers;
|
struct kore_server_list kore_servers;
|
||||||
u_int8_t nlisteners;
|
u_int8_t nlisteners;
|
||||||
int kore_argc = 0;
|
int kore_argc = 0;
|
||||||
|
int kore_quit = 0;
|
||||||
pid_t kore_pid = -1;
|
pid_t kore_pid = -1;
|
||||||
u_int16_t cpu_count = 1;
|
u_int16_t cpu_count = 1;
|
||||||
int kore_debug = 0;
|
int kore_debug = 0;
|
||||||
@ -64,12 +65,12 @@ u_int8_t worker_count = 0;
|
|||||||
char **kore_argv = NULL;
|
char **kore_argv = NULL;
|
||||||
int kore_foreground = 0;
|
int kore_foreground = 0;
|
||||||
char *kore_progname = NULL;
|
char *kore_progname = NULL;
|
||||||
char *kore_root_path = NULL;
|
|
||||||
char *kore_runas_user = NULL;
|
|
||||||
u_int32_t kore_socket_backlog = 5000;
|
u_int32_t kore_socket_backlog = 5000;
|
||||||
char *kore_pidfile = KORE_PIDFILE_DEFAULT;
|
char *kore_pidfile = KORE_PIDFILE_DEFAULT;
|
||||||
char *kore_tls_cipher_list = KORE_DEFAULT_CIPHER_LIST;
|
char *kore_tls_cipher_list = KORE_DEFAULT_CIPHER_LIST;
|
||||||
|
|
||||||
|
struct kore_privsep worker_privsep;
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
static size_t proctitle_maxlen = 0;
|
static size_t proctitle_maxlen = 0;
|
||||||
@ -80,6 +81,7 @@ static void version(void);
|
|||||||
static void kore_write_kore_pid(void);
|
static void kore_write_kore_pid(void);
|
||||||
static void kore_proctitle_setup(void);
|
static void kore_proctitle_setup(void);
|
||||||
static void kore_server_sslstart(void);
|
static void kore_server_sslstart(void);
|
||||||
|
static void kore_server_shutdown(void);
|
||||||
static void kore_server_start(int, char *[]);
|
static void kore_server_start(int, char *[]);
|
||||||
static void kore_call_parent_configure(int, char **);
|
static void kore_call_parent_configure(int, char **);
|
||||||
|
|
||||||
@ -113,9 +115,9 @@ usage(void)
|
|||||||
#endif
|
#endif
|
||||||
printf("\t-f\tstart in foreground\n");
|
printf("\t-f\tstart in foreground\n");
|
||||||
printf("\t-h\tthis help text\n");
|
printf("\t-h\tthis help text\n");
|
||||||
printf("\t-n\tdo not chroot\n");
|
printf("\t-n\tdo not chroot on any worker\n");
|
||||||
printf("\t-q\tonly log errors\n");
|
printf("\t-q\tonly log errors\n");
|
||||||
printf("\t-r\tdo not drop privileges\n");
|
printf("\t-r\tdo not change user on any worker\n");
|
||||||
printf("\t-v\tdisplay %s build information\n", __progname);
|
printf("\t-v\tdisplay %s build information\n", __progname);
|
||||||
|
|
||||||
printf("\nFind more information on https://kore.io\n");
|
printf("\nFind more information on https://kore.io\n");
|
||||||
@ -168,6 +170,9 @@ main(int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
kore_mem_init();
|
kore_mem_init();
|
||||||
|
kore_msg_init();
|
||||||
|
kore_log_init();
|
||||||
|
|
||||||
kore_progname = kore_strdup(argv[0]);
|
kore_progname = kore_strdup(argv[0]);
|
||||||
kore_proctitle_setup();
|
kore_proctitle_setup();
|
||||||
|
|
||||||
@ -194,10 +199,6 @@ main(int argc, char *argv[])
|
|||||||
if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
|
if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
|
||||||
fatal("%s: not a directory or file", kore_pymodule);
|
fatal("%s: not a directory or file", kore_pymodule);
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif !defined(KORE_SINGLE_BINARY)
|
|
||||||
if (argc > 0)
|
|
||||||
fatal("did you mean to run `kodev' instead?");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
kore_pid = getpid();
|
kore_pid = getpid();
|
||||||
@ -205,8 +206,6 @@ main(int argc, char *argv[])
|
|||||||
LIST_INIT(&kore_servers);
|
LIST_INIT(&kore_servers);
|
||||||
|
|
||||||
kore_platform_init();
|
kore_platform_init();
|
||||||
kore_log_init();
|
|
||||||
kore_msg_init();
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
http_parent_init();
|
http_parent_init();
|
||||||
#if defined(KORE_USE_CURL)
|
#if defined(KORE_USE_CURL)
|
||||||
@ -274,11 +273,7 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
kore_signal_setup();
|
kore_signal_setup();
|
||||||
kore_server_start(argc, argv);
|
kore_server_start(argc, argv);
|
||||||
|
kore_server_shutdown();
|
||||||
if (!kore_quiet)
|
|
||||||
kore_log(LOG_NOTICE, "server shutting down");
|
|
||||||
|
|
||||||
kore_worker_shutdown();
|
|
||||||
|
|
||||||
rcall = kore_runtime_getcall(parent_teardown_hook);
|
rcall = kore_runtime_getcall(parent_teardown_hook);
|
||||||
if (rcall != NULL) {
|
if (rcall != NULL) {
|
||||||
@ -292,7 +287,7 @@ main(int argc, char *argv[])
|
|||||||
kore_server_cleanup();
|
kore_server_cleanup();
|
||||||
|
|
||||||
if (!kore_quiet)
|
if (!kore_quiet)
|
||||||
kore_log(LOG_NOTICE, "goodbye");
|
kore_log(LOG_INFO, "goodbye");
|
||||||
|
|
||||||
#if defined(KORE_USE_PYTHON)
|
#if defined(KORE_USE_PYTHON)
|
||||||
kore_python_cleanup();
|
kore_python_cleanup();
|
||||||
@ -497,6 +492,15 @@ kore_server_bind_unix(struct kore_server *srv, const char *path,
|
|||||||
if (!kore_listener_init(l, AF_UNIX, ccb))
|
if (!kore_listener_init(l, AF_UNIX, ccb))
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
|
|
||||||
|
if (sun.sun_path[0] != '\0') {
|
||||||
|
if (unlink(sun.sun_path) == -1 && errno != ENOENT) {
|
||||||
|
kore_log(LOG_ERR, "unlink: %s: %s",
|
||||||
|
sun.sun_path, errno_s);
|
||||||
|
kore_listener_free(l);
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (bind(l->fd, (struct sockaddr *)&sun, socklen) == -1) {
|
if (bind(l->fd, (struct sockaddr *)&sun, socklen) == -1) {
|
||||||
kore_log(LOG_ERR, "bind: %s", errno_s);
|
kore_log(LOG_ERR, "bind: %s", errno_s);
|
||||||
kore_listener_free(l);
|
kore_listener_free(l);
|
||||||
@ -545,10 +549,10 @@ kore_server_finalize(struct kore_server *srv)
|
|||||||
proto = "http";
|
proto = "http";
|
||||||
|
|
||||||
if (l->family == AF_UNIX) {
|
if (l->family == AF_UNIX) {
|
||||||
kore_log(LOG_NOTICE, "%s serving %s on %s",
|
kore_log(LOG_INFO, "%s serving %s on %s",
|
||||||
srv->name, proto, l->host);
|
srv->name, proto, l->host);
|
||||||
} else {
|
} else {
|
||||||
kore_log(LOG_NOTICE, "%s serving %s on %s:%s",
|
kore_log(LOG_INFO, "%s serving %s on %s:%s",
|
||||||
srv->name, proto, l->host, l->port);
|
srv->name, proto, l->host, l->port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -657,11 +661,30 @@ kore_server_free(struct kore_server *srv)
|
|||||||
void
|
void
|
||||||
kore_listener_free(struct listener *l)
|
kore_listener_free(struct listener *l)
|
||||||
{
|
{
|
||||||
|
int rm;
|
||||||
|
|
||||||
LIST_REMOVE(l, list);
|
LIST_REMOVE(l, list);
|
||||||
|
|
||||||
if (l->fd != -1)
|
if (l->fd != -1)
|
||||||
close(l->fd);
|
close(l->fd);
|
||||||
|
|
||||||
|
rm = 0;
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
if (worker == NULL && l->family == AF_UNIX && l->host[0] != '@')
|
||||||
|
rm++;
|
||||||
|
#else
|
||||||
|
if (worker == NULL && l->family == AF_UNIX)
|
||||||
|
rm++;
|
||||||
|
#endif
|
||||||
|
if (rm) {
|
||||||
|
if (unlink(l->host) == -1) {
|
||||||
|
kore_log(LOG_NOTICE,
|
||||||
|
"failed to remove unix socket %s (%s)", l->host,
|
||||||
|
errno_s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
kore_free(l->host);
|
kore_free(l->host);
|
||||||
kore_free(l->port);
|
kore_free(l->port);
|
||||||
|
|
||||||
@ -717,6 +740,23 @@ kore_sockopt(int fd, int what, int opt)
|
|||||||
|
|
||||||
void
|
void
|
||||||
kore_signal_setup(void)
|
kore_signal_setup(void)
|
||||||
|
{
|
||||||
|
kore_signal_trap(SIGHUP);
|
||||||
|
kore_signal_trap(SIGQUIT);
|
||||||
|
kore_signal_trap(SIGTERM);
|
||||||
|
kore_signal_trap(SIGUSR1);
|
||||||
|
kore_signal_trap(SIGCHLD);
|
||||||
|
|
||||||
|
if (kore_foreground)
|
||||||
|
kore_signal_trap(SIGINT);
|
||||||
|
else
|
||||||
|
(void)signal(SIGINT, SIG_IGN);
|
||||||
|
|
||||||
|
(void)signal(SIGPIPE, SIG_IGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_signal_trap(int sig)
|
||||||
{
|
{
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
|
||||||
@ -727,25 +767,8 @@ kore_signal_setup(void)
|
|||||||
if (sigfillset(&sa.sa_mask) == -1)
|
if (sigfillset(&sa.sa_mask) == -1)
|
||||||
fatal("sigfillset: %s", errno_s);
|
fatal("sigfillset: %s", errno_s);
|
||||||
|
|
||||||
if (sigaction(SIGHUP, &sa, NULL) == -1)
|
if (sigaction(sig, &sa, NULL) == -1)
|
||||||
fatal("sigaction: %s", errno_s);
|
fatal("sigaction: %s", errno_s);
|
||||||
if (sigaction(SIGQUIT, &sa, NULL) == -1)
|
|
||||||
fatal("sigaction: %s", errno_s);
|
|
||||||
if (sigaction(SIGTERM, &sa, NULL) == -1)
|
|
||||||
fatal("sigaction: %s", errno_s);
|
|
||||||
if (sigaction(SIGUSR1, &sa, NULL) == -1)
|
|
||||||
fatal("sigaction: %s", errno_s);
|
|
||||||
if (sigaction(SIGCHLD, &sa, NULL) == -1)
|
|
||||||
fatal("sigaction: %s", errno_s);
|
|
||||||
|
|
||||||
if (kore_foreground) {
|
|
||||||
if (sigaction(SIGINT, &sa, NULL) == -1)
|
|
||||||
fatal("sigaction: %s", errno_s);
|
|
||||||
} else {
|
|
||||||
(void)signal(SIGINT, SIG_IGN);
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)signal(SIGPIPE, SIG_IGN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -833,11 +856,39 @@ kore_server_start(int argc, char *argv[])
|
|||||||
u_int32_t tmp;
|
u_int32_t tmp;
|
||||||
struct kore_server *srv;
|
struct kore_server *srv;
|
||||||
u_int64_t netwait;
|
u_int64_t netwait;
|
||||||
int quit, last_sig;
|
int last_sig;
|
||||||
#if defined(KORE_SINGLE_BINARY)
|
#if defined(KORE_SINGLE_BINARY)
|
||||||
struct kore_runtime_call *rcall;
|
struct kore_runtime_call *rcall;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!kore_quiet) {
|
||||||
|
kore_log(LOG_INFO, "%s %s starting, built=%s",
|
||||||
|
__progname, kore_version, kore_build_date);
|
||||||
|
kore_log(LOG_INFO, "built-ins: "
|
||||||
|
#if defined(__linux__)
|
||||||
|
"seccomp "
|
||||||
|
#endif
|
||||||
|
#if defined(KORE_USE_PGSQL)
|
||||||
|
"pgsql "
|
||||||
|
#endif
|
||||||
|
#if defined(KORE_USE_TASKS)
|
||||||
|
"tasks "
|
||||||
|
#endif
|
||||||
|
#if defined(KORE_USE_JSONRPC)
|
||||||
|
"jsonrpc "
|
||||||
|
#endif
|
||||||
|
#if defined(KORE_USE_PYTHON)
|
||||||
|
"python "
|
||||||
|
#endif
|
||||||
|
#if defined(KORE_USE_ACME)
|
||||||
|
"acme "
|
||||||
|
#endif
|
||||||
|
#if defined(KORE_USE_CURL)
|
||||||
|
"curl "
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (kore_foreground == 0) {
|
if (kore_foreground == 0) {
|
||||||
if (daemon(1, 0) == -1)
|
if (daemon(1, 0) == -1)
|
||||||
fatal("cannot daemon(): %s", errno_s);
|
fatal("cannot daemon(): %s", errno_s);
|
||||||
@ -853,25 +904,6 @@ kore_server_start(int argc, char *argv[])
|
|||||||
kore_pid = getpid();
|
kore_pid = getpid();
|
||||||
kore_write_kore_pid();
|
kore_write_kore_pid();
|
||||||
|
|
||||||
if (!kore_quiet) {
|
|
||||||
kore_log(LOG_NOTICE, "%s is starting up", __progname);
|
|
||||||
#if defined(__linux__)
|
|
||||||
kore_log(LOG_NOTICE, "seccomp sandbox enabled");
|
|
||||||
#endif
|
|
||||||
#if defined(KORE_USE_PGSQL)
|
|
||||||
kore_log(LOG_NOTICE, "pgsql built-in enabled");
|
|
||||||
#endif
|
|
||||||
#if defined(KORE_USE_TASKS)
|
|
||||||
kore_log(LOG_NOTICE, "tasks built-in enabled");
|
|
||||||
#endif
|
|
||||||
#if defined(KORE_USE_JSONRPC)
|
|
||||||
kore_log(LOG_NOTICE, "jsonrpc built-in enabled");
|
|
||||||
#endif
|
|
||||||
#if defined(KORE_USE_PYTHON)
|
|
||||||
kore_log(LOG_NOTICE, "python built-in enabled");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(KORE_SINGLE_BINARY) && !defined(KORE_USE_PYTHON)
|
#if !defined(KORE_SINGLE_BINARY) && !defined(KORE_USE_PYTHON)
|
||||||
kore_call_parent_configure(argc, argv);
|
kore_call_parent_configure(argc, argv);
|
||||||
#endif
|
#endif
|
||||||
@ -881,6 +913,10 @@ kore_server_start(int argc, char *argv[])
|
|||||||
kore_call_parent_configure(argc, argv);
|
kore_call_parent_configure(argc, argv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(KORE_USE_PYTHON)
|
||||||
|
kore_python_routes_resolve();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Check if keymgr will be active. */
|
/* Check if keymgr will be active. */
|
||||||
LIST_FOREACH(srv, &kore_servers, list) {
|
LIST_FOREACH(srv, &kore_servers, list) {
|
||||||
if (srv->tls) {
|
if (srv->tls) {
|
||||||
@ -890,7 +926,19 @@ kore_server_start(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
kore_platform_proctitle("[parent]");
|
kore_platform_proctitle("[parent]");
|
||||||
kore_worker_init();
|
|
||||||
|
if (!kore_worker_init()) {
|
||||||
|
kore_log(LOG_ERR, "last worker log lines:");
|
||||||
|
kore_log(LOG_ERR, "=====================================");
|
||||||
|
net_init();
|
||||||
|
kore_connection_init();
|
||||||
|
kore_platform_event_init();
|
||||||
|
kore_msg_parent_init();
|
||||||
|
kore_platform_event_wait(10);
|
||||||
|
kore_worker_dispatch_signal(SIGQUIT);
|
||||||
|
kore_log(LOG_ERR, "=====================================");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set worker_max_connections for kore_connection_init(). */
|
/* Set worker_max_connections for kore_connection_init(). */
|
||||||
tmp = worker_max_connections;
|
tmp = worker_max_connections;
|
||||||
@ -901,7 +949,6 @@ kore_server_start(int argc, char *argv[])
|
|||||||
kore_platform_event_init();
|
kore_platform_event_init();
|
||||||
kore_msg_parent_init();
|
kore_msg_parent_init();
|
||||||
|
|
||||||
quit = 0;
|
|
||||||
worker_max_connections = tmp;
|
worker_max_connections = tmp;
|
||||||
|
|
||||||
kore_timer_init();
|
kore_timer_init();
|
||||||
@ -913,23 +960,23 @@ kore_server_start(int argc, char *argv[])
|
|||||||
kore_msg_unregister(KORE_PYTHON_SEND_OBJ);
|
kore_msg_unregister(KORE_PYTHON_SEND_OBJ);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (quit != 1) {
|
while (kore_quit != 1) {
|
||||||
if (sig_recv != 0) {
|
|
||||||
last_sig = sig_recv;
|
last_sig = sig_recv;
|
||||||
|
|
||||||
switch (sig_recv) {
|
if (last_sig != 0) {
|
||||||
|
switch (last_sig) {
|
||||||
case SIGHUP:
|
case SIGHUP:
|
||||||
kore_worker_dispatch_signal(sig_recv);
|
kore_worker_dispatch_signal(last_sig);
|
||||||
kore_module_reload(0);
|
kore_module_reload(0);
|
||||||
break;
|
break;
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
case SIGQUIT:
|
case SIGQUIT:
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
quit = 1;
|
kore_quit = 1;
|
||||||
kore_worker_dispatch_signal(sig_recv);
|
kore_worker_dispatch_signal(last_sig);
|
||||||
continue;
|
continue;
|
||||||
case SIGUSR1:
|
case SIGUSR1:
|
||||||
kore_worker_dispatch_signal(sig_recv);
|
kore_worker_dispatch_signal(last_sig);
|
||||||
break;
|
break;
|
||||||
case SIGCHLD:
|
case SIGCHLD:
|
||||||
kore_worker_reap();
|
kore_worker_reap();
|
||||||
@ -948,8 +995,20 @@ kore_server_start(int argc, char *argv[])
|
|||||||
kore_platform_event_wait(netwait);
|
kore_platform_event_wait(netwait);
|
||||||
kore_connection_prune(KORE_CONNECTION_PRUNE_DISCONNECT);
|
kore_connection_prune(KORE_CONNECTION_PRUNE_DISCONNECT);
|
||||||
kore_timer_run(kore_time_ms());
|
kore_timer_run(kore_time_ms());
|
||||||
|
kore_worker_reap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kore_worker_dispatch_signal(SIGQUIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
kore_server_shutdown(void)
|
||||||
|
{
|
||||||
|
if (!kore_quiet)
|
||||||
|
kore_log(LOG_INFO, "server shutting down");
|
||||||
|
|
||||||
|
kore_worker_shutdown();
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
kore_accesslog_gather(NULL, kore_time_ms(), 1);
|
kore_accesslog_gather(NULL, kore_time_ms(), 1);
|
||||||
#endif
|
#endif
|
||||||
|
159
src/log.c
Normal file
159
src/log.c
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Joris Vink <joris@coders.se>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
#include "kore.h"
|
||||||
|
|
||||||
|
struct kore_wlog {
|
||||||
|
int prio;
|
||||||
|
u_int16_t wid;
|
||||||
|
size_t loglen;
|
||||||
|
char logmsg[];
|
||||||
|
};
|
||||||
|
|
||||||
|
static void log_print(int, const char *, ...);
|
||||||
|
static void log_from_worker(struct kore_msg *, const void *);
|
||||||
|
|
||||||
|
static FILE *fp = NULL;
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_log_init(void)
|
||||||
|
{
|
||||||
|
#if defined(KORE_SINGLE_BINARY)
|
||||||
|
extern const char *__progname;
|
||||||
|
const char *name = kore_strdup(__progname);
|
||||||
|
#else
|
||||||
|
const char *name = "kore";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fp = stdout;
|
||||||
|
|
||||||
|
if (!kore_foreground)
|
||||||
|
openlog(name, LOG_NDELAY | LOG_PID, LOG_DAEMON);
|
||||||
|
|
||||||
|
kore_msg_register(KORE_MSG_WORKER_LOG, log_from_worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_log_file(const char *path)
|
||||||
|
{
|
||||||
|
if ((fp = fopen(path, "a")) == NULL) {
|
||||||
|
fp = stdout;
|
||||||
|
fatal("fopen(%s): %s", path, errno_s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_log(int prio, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
const char *str;
|
||||||
|
struct kore_wlog wlog;
|
||||||
|
struct kore_buf buf, pkt;
|
||||||
|
|
||||||
|
kore_buf_init(&buf, 128);
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
kore_buf_appendv(&buf, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if (worker != NULL) {
|
||||||
|
kore_buf_init(&pkt, sizeof(wlog) + buf.offset);
|
||||||
|
|
||||||
|
memset(&wlog, 0, sizeof(wlog));
|
||||||
|
|
||||||
|
wlog.prio = prio;
|
||||||
|
wlog.wid = worker->id;
|
||||||
|
wlog.loglen = buf.offset;
|
||||||
|
|
||||||
|
kore_buf_append(&pkt, &wlog, sizeof(wlog));
|
||||||
|
kore_buf_append(&pkt, buf.data, buf.offset);
|
||||||
|
|
||||||
|
kore_msg_send(KORE_MSG_PARENT, KORE_MSG_WORKER_LOG,
|
||||||
|
pkt.data, pkt.offset);
|
||||||
|
|
||||||
|
kore_buf_cleanup(&pkt);
|
||||||
|
} else {
|
||||||
|
str = kore_buf_stringify(&buf, NULL);
|
||||||
|
|
||||||
|
if (kore_foreground || fp != stdout)
|
||||||
|
log_print(prio, "[parent]: %s\n", str);
|
||||||
|
else
|
||||||
|
syslog(prio, "[parent]: %s", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
kore_buf_cleanup(&buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
log_from_worker(struct kore_msg *msg, const void *data)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
const struct kore_wlog *wlog;
|
||||||
|
|
||||||
|
if (msg->length < sizeof(*wlog)) {
|
||||||
|
kore_log(LOG_NOTICE,
|
||||||
|
"too short worker log received (%zu < %zu)",
|
||||||
|
msg->length, sizeof(*wlog));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlog = data;
|
||||||
|
name = kore_worker_name(wlog->wid);
|
||||||
|
|
||||||
|
if (kore_foreground || fp != stdout) {
|
||||||
|
log_print(wlog->prio, "%s: %.*s\n",
|
||||||
|
name, (int)wlog->loglen, wlog->logmsg);
|
||||||
|
} else {
|
||||||
|
syslog(wlog->prio, "%s: %.*s",
|
||||||
|
name, (int)wlog->loglen, wlog->logmsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
log_print(int prio, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
struct tm *t;
|
||||||
|
struct timespec ts;
|
||||||
|
va_list args;
|
||||||
|
char tbuf[32];
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
switch (prio) {
|
||||||
|
case LOG_ERR:
|
||||||
|
case LOG_WARNING:
|
||||||
|
case LOG_NOTICE:
|
||||||
|
case LOG_INFO:
|
||||||
|
case LOG_DEBUG:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
t = gmtime(&ts.tv_sec);
|
||||||
|
|
||||||
|
if (strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M:%S", t) > 0)
|
||||||
|
fprintf(fp, "%s.%03ld UTC ", tbuf, ts.tv_nsec / 1000000);
|
||||||
|
|
||||||
|
vfprintf(fp, fmt, args);
|
||||||
|
fflush(fp);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
113
src/module.c
113
src/module.c
@ -135,11 +135,6 @@ kore_module_reload(int cbs)
|
|||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int ret;
|
int ret;
|
||||||
#if !defined(KORE_NO_HTTP)
|
|
||||||
struct kore_server *srv;
|
|
||||||
struct kore_domain *dom;
|
|
||||||
struct kore_module_handle *hdlr;
|
|
||||||
#endif
|
|
||||||
struct kore_module *module;
|
struct kore_module *module;
|
||||||
|
|
||||||
TAILQ_FOREACH(module, &modules, list) {
|
TAILQ_FOREACH(module, &modules, list) {
|
||||||
@ -183,22 +178,7 @@ kore_module_reload(int cbs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
LIST_FOREACH(srv, &kore_servers, list) {
|
kore_route_reload();
|
||||||
TAILQ_FOREACH(dom, &srv->domains, list) {
|
|
||||||
TAILQ_FOREACH(hdlr, &(dom->handlers), list) {
|
|
||||||
kore_free(hdlr->rcall);
|
|
||||||
hdlr->rcall = kore_runtime_getcall(hdlr->func);
|
|
||||||
if (hdlr->rcall == NULL) {
|
|
||||||
fatal("no function '%s' found",
|
|
||||||
hdlr->func);
|
|
||||||
}
|
|
||||||
hdlr->errors = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
|
||||||
kore_validator_reload();
|
kore_validator_reload();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -212,97 +192,6 @@ kore_module_loaded(void)
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
|
||||||
int
|
|
||||||
kore_module_handler_new(struct kore_domain *dom, const char *path,
|
|
||||||
const char *func, const char *auth, int type)
|
|
||||||
{
|
|
||||||
struct kore_auth *ap;
|
|
||||||
struct kore_module_handle *hdlr;
|
|
||||||
|
|
||||||
if (auth != NULL) {
|
|
||||||
if ((ap = kore_auth_lookup(auth)) == NULL)
|
|
||||||
fatal("no authentication block '%s' found", auth);
|
|
||||||
} else {
|
|
||||||
ap = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hdlr = kore_malloc(sizeof(*hdlr));
|
|
||||||
hdlr->auth = ap;
|
|
||||||
hdlr->dom = dom;
|
|
||||||
hdlr->errors = 0;
|
|
||||||
hdlr->type = type;
|
|
||||||
hdlr->path = kore_strdup(path);
|
|
||||||
hdlr->func = kore_strdup(func);
|
|
||||||
hdlr->methods = HTTP_METHOD_ALL;
|
|
||||||
|
|
||||||
TAILQ_INIT(&(hdlr->params));
|
|
||||||
|
|
||||||
if ((hdlr->rcall = kore_runtime_getcall(func)) == NULL) {
|
|
||||||
kore_module_handler_free(hdlr);
|
|
||||||
kore_log(LOG_ERR, "function '%s' not found", func);
|
|
||||||
return (KORE_RESULT_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hdlr->type == HANDLER_TYPE_DYNAMIC) {
|
|
||||||
if (regcomp(&(hdlr->rctx), hdlr->path,
|
|
||||||
REG_EXTENDED | REG_NOSUB)) {
|
|
||||||
kore_module_handler_free(hdlr);
|
|
||||||
kore_debug("regcomp() on %s failed", path);
|
|
||||||
return (KORE_RESULT_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&(dom->handlers), hdlr, list);
|
|
||||||
return (KORE_RESULT_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
kore_module_handler_free(struct kore_module_handle *hdlr)
|
|
||||||
{
|
|
||||||
struct kore_handler_params *param;
|
|
||||||
|
|
||||||
if (hdlr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (hdlr->func != NULL)
|
|
||||||
kore_free(hdlr->func);
|
|
||||||
if (hdlr->path != NULL)
|
|
||||||
kore_free(hdlr->path);
|
|
||||||
if (hdlr->type == HANDLER_TYPE_DYNAMIC)
|
|
||||||
regfree(&(hdlr->rctx));
|
|
||||||
|
|
||||||
/* Drop all validators associated with this handler */
|
|
||||||
while ((param = TAILQ_FIRST(&(hdlr->params))) != NULL) {
|
|
||||||
TAILQ_REMOVE(&(hdlr->params), param, list);
|
|
||||||
if (param->name != NULL)
|
|
||||||
kore_free(param->name);
|
|
||||||
kore_free(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
kore_free(hdlr);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct kore_module_handle *
|
|
||||||
kore_module_handler_find(struct http_request *req, struct kore_domain *dom)
|
|
||||||
{
|
|
||||||
struct kore_module_handle *hdlr;
|
|
||||||
|
|
||||||
TAILQ_FOREACH(hdlr, &(dom->handlers), list) {
|
|
||||||
if (hdlr->type == HANDLER_TYPE_STATIC) {
|
|
||||||
if (!strcmp(hdlr->path, req->path))
|
|
||||||
return (hdlr);
|
|
||||||
} else {
|
|
||||||
if (!regexec(&(hdlr->rctx), req->path,
|
|
||||||
HTTP_CAPTURE_GROUPS, req->cgroups, 0))
|
|
||||||
return (hdlr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
#endif /* !KORE_NO_HTTP */
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
kore_module_getsym(const char *symbol, struct kore_runtime **runtime)
|
kore_module_getsym(const char *symbol, struct kore_runtime **runtime)
|
||||||
{
|
{
|
||||||
|
34
src/msg.c
34
src/msg.c
@ -22,6 +22,10 @@
|
|||||||
#include "kore.h"
|
#include "kore.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
|
||||||
|
#if defined(KORE_USE_ACME)
|
||||||
|
#include "acme.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct msg_type {
|
struct msg_type {
|
||||||
u_int8_t id;
|
u_int8_t id;
|
||||||
void (*cb)(struct kore_msg *, const void *);
|
void (*cb)(struct kore_msg *, const void *);
|
||||||
@ -29,9 +33,8 @@ struct msg_type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct msg_type *msg_type_lookup(u_int8_t);
|
static struct msg_type *msg_type_lookup(u_int8_t);
|
||||||
static int msg_recv_packet(struct netbuf *);
|
|
||||||
static int msg_recv_data(struct netbuf *);
|
static int msg_recv_data(struct netbuf *);
|
||||||
static void msg_disconnected_parent(struct connection *);
|
static int msg_recv_packet(struct netbuf *);
|
||||||
static void msg_disconnected_worker(struct connection *);
|
static void msg_disconnected_worker(struct connection *);
|
||||||
static void msg_type_shutdown(struct kore_msg *, const void *);
|
static void msg_type_shutdown(struct kore_msg *, const void *);
|
||||||
|
|
||||||
@ -56,18 +59,8 @@ kore_msg_parent_init(void)
|
|||||||
struct kore_worker *kw;
|
struct kore_worker *kw;
|
||||||
|
|
||||||
for (idx = 0; idx < worker_count; idx++) {
|
for (idx = 0; idx < worker_count; idx++) {
|
||||||
if (keymgr_active == 0) {
|
|
||||||
if (idx == KORE_WORKER_KEYMGR_IDX ||
|
|
||||||
idx == KORE_WORKER_ACME_IDX)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(KORE_USE_ACME)
|
|
||||||
if (idx == KORE_WORKER_ACME_IDX)
|
|
||||||
continue;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
kw = kore_worker_data(idx);
|
kw = kore_worker_data(idx);
|
||||||
|
if (kw->ps != NULL)
|
||||||
kore_msg_parent_add(kw);
|
kore_msg_parent_add(kw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +112,6 @@ kore_msg_worker_init(void)
|
|||||||
worker->msg[1]->write = net_write;
|
worker->msg[1]->write = net_write;
|
||||||
worker->msg[1]->proto = CONN_PROTO_MSG;
|
worker->msg[1]->proto = CONN_PROTO_MSG;
|
||||||
worker->msg[1]->state = CONN_STATE_ESTABLISHED;
|
worker->msg[1]->state = CONN_STATE_ESTABLISHED;
|
||||||
worker->msg[1]->disconnect = msg_disconnected_parent;
|
|
||||||
worker->msg[1]->handle = kore_connection_handle;
|
worker->msg[1]->handle = kore_connection_handle;
|
||||||
worker->msg[1]->evt.flags = KORE_EVENT_WRITE;
|
worker->msg[1]->evt.flags = KORE_EVENT_WRITE;
|
||||||
|
|
||||||
@ -147,7 +139,7 @@ kore_msg_register(u_int8_t id, void (*cb)(struct kore_msg *, const void *))
|
|||||||
{
|
{
|
||||||
struct msg_type *type;
|
struct msg_type *type;
|
||||||
|
|
||||||
if ((type = msg_type_lookup(id)) != NULL)
|
if (msg_type_lookup(id) != NULL)
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
|
|
||||||
type = kore_malloc(sizeof(*type));
|
type = kore_malloc(sizeof(*type));
|
||||||
@ -251,16 +243,6 @@ msg_recv_data(struct netbuf *nb)
|
|||||||
return (KORE_RESULT_OK);
|
return (KORE_RESULT_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
msg_disconnected_parent(struct connection *c)
|
|
||||||
{
|
|
||||||
if (!kore_quiet)
|
|
||||||
kore_log(LOG_ERR, "parent gone, shutting down");
|
|
||||||
|
|
||||||
if (kill(worker->pid, SIGQUIT) == -1)
|
|
||||||
kore_log(LOG_ERR, "failed to send SIGQUIT: %s", errno_s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
msg_disconnected_worker(struct connection *c)
|
msg_disconnected_worker(struct connection *c)
|
||||||
{
|
{
|
||||||
@ -275,7 +257,7 @@ msg_type_shutdown(struct kore_msg *msg, const void *data)
|
|||||||
"shutdown requested by worker %u, going down", msg->src);
|
"shutdown requested by worker %u, going down", msg->src);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)raise(SIGQUIT);
|
kore_quit = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
|
@ -292,6 +292,9 @@ net_recv_flush(struct connection *c)
|
|||||||
if (c->rnb->buf == NULL)
|
if (c->rnb->buf == NULL)
|
||||||
return (KORE_RESULT_OK);
|
return (KORE_RESULT_OK);
|
||||||
|
|
||||||
|
if ((c->rnb->b_len - c->rnb->s_off) == 0)
|
||||||
|
return (KORE_RESULT_OK);
|
||||||
|
|
||||||
if (!c->read(c, &r))
|
if (!c->read(c, &r))
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
if (!(c->evt.flags & KORE_EVENT_READ))
|
if (!(c->evt.flags & KORE_EVENT_READ))
|
||||||
|
@ -772,6 +772,10 @@ pgsql_read_result(struct kore_pgsql *pgsql)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (PQresultStatus(pgsql->result)) {
|
switch (PQresultStatus(pgsql->result)) {
|
||||||
|
#if PG_VERSION_NUM >= 140000
|
||||||
|
case PGRES_PIPELINE_SYNC:
|
||||||
|
case PGRES_PIPELINE_ABORTED:
|
||||||
|
#endif
|
||||||
case PGRES_COPY_OUT:
|
case PGRES_COPY_OUT:
|
||||||
case PGRES_COPY_IN:
|
case PGRES_COPY_IN:
|
||||||
case PGRES_NONFATAL_ERROR:
|
case PGRES_NONFATAL_ERROR:
|
||||||
|
@ -47,6 +47,8 @@ kore_pool_init(struct kore_pool *pool, const char *name,
|
|||||||
if ((pool->name = strdup(name)) == NULL)
|
if ((pool->name = strdup(name)) == NULL)
|
||||||
fatal("kore_pool_init: strdup %s", errno_s);
|
fatal("kore_pool_init: strdup %s", errno_s);
|
||||||
|
|
||||||
|
len = (len + (8 - 1)) & ~(8 - 1);
|
||||||
|
|
||||||
pool->lock = 0;
|
pool->lock = 0;
|
||||||
pool->elms = 0;
|
pool->elms = 0;
|
||||||
pool->inuse = 0;
|
pool->inuse = 0;
|
||||||
|
1035
src/python.c
1035
src/python.c
File diff suppressed because it is too large
Load Diff
138
src/route.c
Normal file
138
src/route.c
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Joris Vink <joris@coders.se>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#include "kore.h"
|
||||||
|
#include "http.h"
|
||||||
|
|
||||||
|
struct kore_route *
|
||||||
|
kore_route_create(struct kore_domain *dom, const char *path, int type)
|
||||||
|
{
|
||||||
|
struct kore_route *rt;
|
||||||
|
|
||||||
|
rt = kore_calloc(1, sizeof(*rt));
|
||||||
|
rt->dom = dom;
|
||||||
|
rt->type = type;
|
||||||
|
rt->path = kore_strdup(path);
|
||||||
|
rt->methods = HTTP_METHOD_ALL;
|
||||||
|
|
||||||
|
TAILQ_INIT(&rt->params);
|
||||||
|
|
||||||
|
if (rt->type == HANDLER_TYPE_DYNAMIC) {
|
||||||
|
if (regcomp(&rt->rctx, rt->path, REG_EXTENDED | REG_NOSUB)) {
|
||||||
|
kore_route_free(rt);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TAILQ_INSERT_TAIL(&dom->routes, rt, list);
|
||||||
|
|
||||||
|
return (rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_route_free(struct kore_route *rt)
|
||||||
|
{
|
||||||
|
struct kore_route_params *param;
|
||||||
|
|
||||||
|
if (rt == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
kore_free(rt->func);
|
||||||
|
kore_free(rt->path);
|
||||||
|
|
||||||
|
if (rt->type == HANDLER_TYPE_DYNAMIC)
|
||||||
|
regfree(&rt->rctx);
|
||||||
|
|
||||||
|
/* Drop all validators associated with this handler */
|
||||||
|
while ((param = TAILQ_FIRST(&rt->params)) != NULL) {
|
||||||
|
TAILQ_REMOVE(&rt->params, param, list);
|
||||||
|
kore_free(param->name);
|
||||||
|
kore_free(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
kore_free(rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_route_callback(struct kore_route *rt, const char *func)
|
||||||
|
{
|
||||||
|
if ((rt->rcall = kore_runtime_getcall(func)) == NULL)
|
||||||
|
fatal("callback '%s' for '%s' not found", func, rt->path);
|
||||||
|
|
||||||
|
kore_free(rt->func);
|
||||||
|
rt->func = kore_strdup(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
kore_route_lookup(struct http_request *req, struct kore_domain *dom,
|
||||||
|
int method, struct kore_route **out)
|
||||||
|
{
|
||||||
|
struct kore_route *rt;
|
||||||
|
int exists;
|
||||||
|
|
||||||
|
exists = 0;
|
||||||
|
*out = NULL;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(rt, &dom->routes, list) {
|
||||||
|
if (rt->type == HANDLER_TYPE_STATIC) {
|
||||||
|
if (!strcmp(rt->path, req->path)) {
|
||||||
|
if (rt->methods & method) {
|
||||||
|
*out = rt;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
exists++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!regexec(&rt->rctx, req->path,
|
||||||
|
HTTP_CAPTURE_GROUPS, req->cgroups, 0)) {
|
||||||
|
if (rt->methods & method) {
|
||||||
|
*out = rt;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
exists++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (exists);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_route_reload(void)
|
||||||
|
{
|
||||||
|
struct kore_route *rt;
|
||||||
|
struct kore_server *srv;
|
||||||
|
struct kore_domain *dom;
|
||||||
|
|
||||||
|
LIST_FOREACH(srv, &kore_servers, list) {
|
||||||
|
TAILQ_FOREACH(dom, &srv->domains, list) {
|
||||||
|
TAILQ_FOREACH(rt, &dom->routes, list) {
|
||||||
|
kore_free(rt->rcall);
|
||||||
|
rt->rcall = kore_runtime_getcall(rt->func);
|
||||||
|
if (rt->rcall == NULL) {
|
||||||
|
fatal("no function '%s' for route '%s'",
|
||||||
|
rt->func, rt->path);
|
||||||
|
}
|
||||||
|
rt->errors = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -29,10 +29,14 @@
|
|||||||
|
|
||||||
static void native_runtime_execute(void *);
|
static void native_runtime_execute(void *);
|
||||||
static int native_runtime_onload(void *, int);
|
static int native_runtime_onload(void *, int);
|
||||||
|
static void native_runtime_signal(void *, int);
|
||||||
static void native_runtime_connect(void *, struct connection *);
|
static void native_runtime_connect(void *, struct connection *);
|
||||||
static void native_runtime_configure(void *, int, char **);
|
static void native_runtime_configure(void *, int, char **);
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
static int native_runtime_http_request(void *, struct http_request *);
|
static int native_runtime_http_request(void *, struct http_request *);
|
||||||
|
static void native_runtime_http_request_free(void *, struct http_request *);
|
||||||
|
static void native_runtime_http_body_chunk(void *, struct http_request *,
|
||||||
|
const void *, size_t);
|
||||||
static int native_runtime_validator(void *, struct http_request *,
|
static int native_runtime_validator(void *, struct http_request *,
|
||||||
const void *);
|
const void *);
|
||||||
|
|
||||||
@ -44,12 +48,15 @@ struct kore_runtime kore_native_runtime = {
|
|||||||
KORE_RUNTIME_NATIVE,
|
KORE_RUNTIME_NATIVE,
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
.http_request = native_runtime_http_request,
|
.http_request = native_runtime_http_request,
|
||||||
|
.http_request_free = native_runtime_http_request_free,
|
||||||
|
.http_body_chunk = native_runtime_http_body_chunk,
|
||||||
.validator = native_runtime_validator,
|
.validator = native_runtime_validator,
|
||||||
.wsconnect = native_runtime_connect,
|
.wsconnect = native_runtime_connect,
|
||||||
.wsmessage = native_runtime_wsmessage,
|
.wsmessage = native_runtime_wsmessage,
|
||||||
.wsdisconnect = native_runtime_connect,
|
.wsdisconnect = native_runtime_connect,
|
||||||
#endif
|
#endif
|
||||||
.onload = native_runtime_onload,
|
.onload = native_runtime_onload,
|
||||||
|
.signal = native_runtime_signal,
|
||||||
.connect = native_runtime_connect,
|
.connect = native_runtime_connect,
|
||||||
.execute = native_runtime_execute,
|
.execute = native_runtime_execute,
|
||||||
.configure = native_runtime_configure
|
.configure = native_runtime_configure
|
||||||
@ -97,6 +104,12 @@ kore_runtime_connect(struct kore_runtime_call *rcall, struct connection *c)
|
|||||||
rcall->runtime->connect(rcall->addr, c);
|
rcall->runtime->connect(rcall->addr, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_runtime_signal(struct kore_runtime_call *rcall, int sig)
|
||||||
|
{
|
||||||
|
rcall->runtime->signal(rcall->addr, sig);
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
int
|
int
|
||||||
kore_runtime_http_request(struct kore_runtime_call *rcall,
|
kore_runtime_http_request(struct kore_runtime_call *rcall,
|
||||||
@ -105,6 +118,20 @@ kore_runtime_http_request(struct kore_runtime_call *rcall,
|
|||||||
return (rcall->runtime->http_request(rcall->addr, req));
|
return (rcall->runtime->http_request(rcall->addr, req));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_runtime_http_request_free(struct kore_runtime_call *rcall,
|
||||||
|
struct http_request *req)
|
||||||
|
{
|
||||||
|
rcall->runtime->http_request_free(rcall->addr, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_runtime_http_body_chunk(struct kore_runtime_call *rcall,
|
||||||
|
struct http_request *req, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
rcall->runtime->http_body_chunk(rcall->addr, req, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
kore_runtime_validator(struct kore_runtime_call *rcall,
|
kore_runtime_validator(struct kore_runtime_call *rcall,
|
||||||
struct http_request *req, const void *data)
|
struct http_request *req, const void *data)
|
||||||
@ -168,6 +195,15 @@ native_runtime_onload(void *addr, int action)
|
|||||||
return (cb(action));
|
return (cb(action));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
native_runtime_signal(void *addr, int sig)
|
||||||
|
{
|
||||||
|
void (*cb)(int);
|
||||||
|
|
||||||
|
*(void **)&(cb) = addr;
|
||||||
|
cb(sig);
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
static int
|
static int
|
||||||
native_runtime_http_request(void *addr, struct http_request *req)
|
native_runtime_http_request(void *addr, struct http_request *req)
|
||||||
@ -178,6 +214,26 @@ native_runtime_http_request(void *addr, struct http_request *req)
|
|||||||
return (cb(req));
|
return (cb(req));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
native_runtime_http_request_free(void *addr, struct http_request *req)
|
||||||
|
{
|
||||||
|
int (*cb)(struct http_request *);
|
||||||
|
|
||||||
|
*(void **)&(cb) = addr;
|
||||||
|
cb(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
native_runtime_http_body_chunk(void *addr, struct http_request *req,
|
||||||
|
const void *data, size_t len)
|
||||||
|
{
|
||||||
|
void (*cb)(struct http_request *, const void *, size_t);
|
||||||
|
|
||||||
|
*(void **)&(cb) = addr;
|
||||||
|
|
||||||
|
cb(req, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
native_runtime_validator(void *addr, struct http_request *req, const void *data)
|
native_runtime_validator(void *addr, struct http_request *req, const void *data)
|
||||||
{
|
{
|
||||||
|
@ -90,6 +90,9 @@ static struct sock_filter filter_kore[] = {
|
|||||||
#if defined(SYS_readlink)
|
#if defined(SYS_readlink)
|
||||||
KORE_SYSCALL_ALLOW(readlink),
|
KORE_SYSCALL_ALLOW(readlink),
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(SYS_readlinkat)
|
||||||
|
KORE_SYSCALL_ALLOW(readlinkat),
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Process related. */
|
/* Process related. */
|
||||||
KORE_SYSCALL_ALLOW(exit),
|
KORE_SYSCALL_ALLOW(exit),
|
||||||
|
153
src/utils.c
153
src/utils.c
@ -54,6 +54,9 @@ static int utils_base64_encode(const void *, size_t, char **,
|
|||||||
const char *, int);
|
const char *, int);
|
||||||
static int utils_base64_decode(const char *, u_int8_t **,
|
static int utils_base64_decode(const char *, u_int8_t **,
|
||||||
size_t *, const char *, int);
|
size_t *, const char *, int);
|
||||||
|
static int utils_x509name_tobuf(void *, int, int, const char *,
|
||||||
|
const void *, size_t, int);
|
||||||
|
|
||||||
|
|
||||||
static char b64_table[] = \
|
static char b64_table[] = \
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
@ -79,46 +82,6 @@ kore_debug_internal(char *file, int line, const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
|
||||||
kore_log_init(void)
|
|
||||||
{
|
|
||||||
#if defined(KORE_SINGLE_BINARY)
|
|
||||||
extern const char *__progname;
|
|
||||||
const char *name = kore_strdup(__progname);
|
|
||||||
#else
|
|
||||||
const char *name = "kore";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!kore_foreground)
|
|
||||||
openlog(name, LOG_NDELAY | LOG_PID, LOG_DAEMON);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
kore_log(int prio, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
const char *name;
|
|
||||||
char buf[2048];
|
|
||||||
|
|
||||||
va_start(args, fmt);
|
|
||||||
(void)vsnprintf(buf, sizeof(buf), fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
if (worker != NULL) {
|
|
||||||
name = kore_worker_name(worker->id);
|
|
||||||
|
|
||||||
if (kore_foreground)
|
|
||||||
printf("%s: %s\n", name, buf);
|
|
||||||
else
|
|
||||||
syslog(prio, "%s: %s", name, buf);
|
|
||||||
} else {
|
|
||||||
if (kore_foreground)
|
|
||||||
printf("[parent]: %s\n", buf);
|
|
||||||
else
|
|
||||||
syslog(prio, "[parent]: %s", buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
kore_strlcpy(char *dst, const char *src, const size_t len)
|
kore_strlcpy(char *dst, const char *src, const size_t len)
|
||||||
{
|
{
|
||||||
@ -585,35 +548,72 @@ kore_worker_name(int id)
|
|||||||
return (buf);
|
return (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
kore_x509_issuer_name(struct connection *c, char **out, int flags)
|
||||||
|
{
|
||||||
|
struct kore_buf buf;
|
||||||
|
X509_NAME *name;
|
||||||
|
|
||||||
|
if ((name = X509_get_issuer_name(c->cert)) == NULL)
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
|
|
||||||
|
kore_buf_init(&buf, 1024);
|
||||||
|
|
||||||
|
if (!kore_x509name_foreach(name, flags, &buf, utils_x509name_tobuf)) {
|
||||||
|
kore_buf_cleanup(&buf);
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = kore_buf_stringify(&buf, NULL);
|
||||||
|
|
||||||
|
buf.offset = 0;
|
||||||
|
buf.data = NULL;
|
||||||
|
|
||||||
|
return (KORE_RESULT_OK);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
kore_x509_subject_name(struct connection *c, char **out, int flags)
|
kore_x509_subject_name(struct connection *c, char **out, int flags)
|
||||||
{
|
{
|
||||||
struct kore_buf buf;
|
struct kore_buf buf;
|
||||||
|
X509_NAME *name;
|
||||||
|
|
||||||
|
if ((name = X509_get_subject_name(c->cert)) == NULL)
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
|
|
||||||
|
kore_buf_init(&buf, 1024);
|
||||||
|
|
||||||
|
if (!kore_x509name_foreach(name, flags, &buf, utils_x509name_tobuf)) {
|
||||||
|
kore_buf_cleanup(&buf);
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = kore_buf_stringify(&buf, NULL);
|
||||||
|
|
||||||
|
buf.offset = 0;
|
||||||
|
buf.data = NULL;
|
||||||
|
|
||||||
|
return (KORE_RESULT_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
kore_x509name_foreach(X509_NAME *name, int flags, void *udata,
|
||||||
|
int (*cb)(void *, int, int, const char *, const void *, size_t, int))
|
||||||
|
{
|
||||||
u_int8_t *data;
|
u_int8_t *data;
|
||||||
ASN1_STRING *astr;
|
ASN1_STRING *astr;
|
||||||
X509_NAME *name;
|
|
||||||
X509_NAME_ENTRY *entry;
|
X509_NAME_ENTRY *entry;
|
||||||
const char *field;
|
const char *field;
|
||||||
int ret, idx, namelen, nid, len;
|
int islast, ret, idx, namelen, nid, len;
|
||||||
|
|
||||||
data = NULL;
|
data = NULL;
|
||||||
ret = KORE_RESULT_ERROR;
|
ret = KORE_RESULT_ERROR;
|
||||||
|
|
||||||
kore_buf_init(&buf, 1024);
|
if ((namelen = X509_NAME_entry_count(name)) == 0)
|
||||||
|
|
||||||
if (c->cert == NULL)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if ((name = X509_get_subject_name(c->cert)) == NULL)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
namelen = X509_NAME_entry_count(name);
|
|
||||||
if (namelen == 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
for (idx = 0; idx < namelen; idx++) {
|
for (idx = 0; idx < namelen; idx++) {
|
||||||
entry = X509_NAME_get_entry(name, idx);
|
if ((entry = X509_NAME_get_entry(name, idx)) == NULL)
|
||||||
if (entry == NULL)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(entry));
|
nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(entry));
|
||||||
@ -627,33 +627,24 @@ kore_x509_subject_name(struct connection *c, char **out, int flags)
|
|||||||
if ((len = ASN1_STRING_to_UTF8(&data, astr)) < 0)
|
if ((len = ASN1_STRING_to_UTF8(&data, astr)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (flags & KORE_X509_COMMON_NAME_ONLY) {
|
|
||||||
if (nid == NID_commonName) {
|
|
||||||
kore_buf_append(&buf, data, len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
kore_buf_appendf(&buf, "%s=", field);
|
|
||||||
kore_buf_append(&buf, data, len);
|
|
||||||
if (idx != (namelen - 1))
|
if (idx != (namelen - 1))
|
||||||
kore_buf_appendf(&buf, " ");
|
islast = 0;
|
||||||
}
|
else
|
||||||
|
islast = 1;
|
||||||
|
|
||||||
|
if (!cb(udata, islast, nid, field, data, len, flags))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
OPENSSL_free(data);
|
OPENSSL_free(data);
|
||||||
data = NULL;
|
data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = KORE_RESULT_OK;
|
ret = KORE_RESULT_OK;
|
||||||
*out = kore_buf_stringify(&buf, NULL);
|
|
||||||
|
|
||||||
buf.offset = 0;
|
|
||||||
buf.data = NULL;
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (data != NULL)
|
if (data != NULL)
|
||||||
OPENSSL_free(data);
|
OPENSSL_free(data);
|
||||||
|
|
||||||
kore_buf_cleanup(&buf);
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -689,17 +680,31 @@ static void
|
|||||||
fatal_log(const char *fmt, va_list args)
|
fatal_log(const char *fmt, va_list args)
|
||||||
{
|
{
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
extern const char *kore_progname;
|
|
||||||
|
|
||||||
(void)vsnprintf(buf, sizeof(buf), fmt, args);
|
(void)vsnprintf(buf, sizeof(buf), fmt, args);
|
||||||
|
kore_log(LOG_ERR, "FATAL: %s", buf);
|
||||||
if (!kore_foreground)
|
|
||||||
kore_log(LOG_ERR, "%s", buf);
|
|
||||||
|
|
||||||
if (worker != NULL && worker->id == KORE_WORKER_KEYMGR)
|
if (worker != NULL && worker->id == KORE_WORKER_KEYMGR)
|
||||||
kore_keymgr_cleanup(1);
|
kore_keymgr_cleanup(1);
|
||||||
|
}
|
||||||
|
|
||||||
printf("%s: %s\n", kore_progname, buf);
|
static int
|
||||||
|
utils_x509name_tobuf(void *udata, int islast, int nid, const char *field,
|
||||||
|
const void *data, size_t len, int flags)
|
||||||
|
{
|
||||||
|
struct kore_buf *buf = udata;
|
||||||
|
|
||||||
|
if (flags & KORE_X509_COMMON_NAME_ONLY) {
|
||||||
|
if (nid == NID_commonName)
|
||||||
|
kore_buf_append(buf, data, len);
|
||||||
|
} else {
|
||||||
|
kore_buf_appendf(buf, "%s=", field);
|
||||||
|
kore_buf_append(buf, data, len);
|
||||||
|
if (!islast)
|
||||||
|
kore_buf_appendf(buf, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (KORE_RESULT_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
315
src/worker.c
315
src/worker.c
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -28,6 +29,7 @@
|
|||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "kore.h"
|
#include "kore.h"
|
||||||
|
|
||||||
@ -77,6 +79,11 @@ struct wlock {
|
|||||||
static int worker_trylock(void);
|
static int worker_trylock(void);
|
||||||
static void worker_unlock(void);
|
static void worker_unlock(void);
|
||||||
static void worker_reaper(pid_t, int);
|
static void worker_reaper(pid_t, int);
|
||||||
|
static void worker_runtime_teardown(void);
|
||||||
|
static void worker_runtime_configure(void);
|
||||||
|
static void worker_domain_check(struct kore_domain *);
|
||||||
|
|
||||||
|
static struct kore_runtime_call *worker_runtime_signal(void);
|
||||||
|
|
||||||
static inline int worker_acceptlock_obtain(void);
|
static inline int worker_acceptlock_obtain(void);
|
||||||
static inline void worker_acceptlock_release(void);
|
static inline void worker_acceptlock_release(void);
|
||||||
@ -99,7 +106,7 @@ u_int32_t worker_max_connections = 512;
|
|||||||
u_int32_t worker_active_connections = 0;
|
u_int32_t worker_active_connections = 0;
|
||||||
int worker_policy = KORE_WORKER_POLICY_RESTART;
|
int worker_policy = KORE_WORKER_POLICY_RESTART;
|
||||||
|
|
||||||
void
|
int
|
||||||
kore_worker_init(void)
|
kore_worker_init(void)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -143,42 +150,59 @@ kore_worker_init(void)
|
|||||||
kw->lb.offset = 0;
|
kw->lb.offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!kore_quiet)
|
||||||
|
kore_log(LOG_INFO, "starting worker processes");
|
||||||
|
|
||||||
/* Now start all the workers. */
|
/* Now start all the workers. */
|
||||||
id = 1;
|
id = 1;
|
||||||
cpu = 1;
|
cpu = 1;
|
||||||
for (idx = KORE_WORKER_BASE; idx < worker_count; idx++) {
|
for (idx = KORE_WORKER_BASE; idx < worker_count; idx++) {
|
||||||
if (cpu >= cpu_count)
|
if (cpu >= cpu_count)
|
||||||
cpu = 0;
|
cpu = 0;
|
||||||
kore_worker_spawn(idx, id++, cpu++);
|
if (!kore_worker_spawn(idx, id++, cpu++))
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keymgr_active) {
|
if (keymgr_active) {
|
||||||
#if defined(KORE_USE_ACME)
|
#if defined(KORE_USE_ACME)
|
||||||
/* The ACME process is only started if we need it. */
|
/* The ACME process is only started if we need it. */
|
||||||
if (acme_provider) {
|
if (acme_domains) {
|
||||||
kore_worker_spawn(KORE_WORKER_ACME_IDX,
|
if (!kore_worker_spawn(KORE_WORKER_ACME_IDX,
|
||||||
KORE_WORKER_ACME, 0);
|
KORE_WORKER_ACME, 0))
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Now we can start the keymgr. */
|
/* Now we can start the keymgr. */
|
||||||
kore_worker_spawn(KORE_WORKER_KEYMGR_IDX,
|
if (!kore_worker_spawn(KORE_WORKER_KEYMGR_IDX,
|
||||||
KORE_WORKER_KEYMGR, 0);
|
KORE_WORKER_KEYMGR, 0))
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!kore_quiet)
|
||||||
|
kore_log(LOG_INFO, "all worker processes started");
|
||||||
|
|
||||||
|
return (KORE_RESULT_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
kore_worker_spawn(u_int16_t idx, u_int16_t id, u_int16_t cpu)
|
kore_worker_spawn(u_int16_t idx, u_int16_t id, u_int16_t cpu)
|
||||||
{
|
{
|
||||||
|
int cnt;
|
||||||
struct kore_worker *kw;
|
struct kore_worker *kw;
|
||||||
|
#if defined(__linux__)
|
||||||
|
int status;
|
||||||
|
#endif
|
||||||
|
|
||||||
kw = WORKER(idx);
|
kw = WORKER(idx);
|
||||||
kw->id = id;
|
kw->id = id;
|
||||||
kw->cpu = cpu;
|
kw->cpu = cpu;
|
||||||
kw->has_lock = 0;
|
|
||||||
kw->active_hdlr = NULL;
|
|
||||||
kw->running = 1;
|
kw->running = 1;
|
||||||
|
|
||||||
|
kw->ready = 0;
|
||||||
|
kw->has_lock = 0;
|
||||||
|
kw->active_route = NULL;
|
||||||
|
|
||||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, kw->pipe) == -1)
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, kw->pipe) == -1)
|
||||||
fatal("socketpair(): %s", errno_s);
|
fatal("socketpair(): %s", errno_s);
|
||||||
|
|
||||||
@ -186,6 +210,20 @@ kore_worker_spawn(u_int16_t idx, u_int16_t id, u_int16_t cpu)
|
|||||||
!kore_connection_nonblock(kw->pipe[1], 0))
|
!kore_connection_nonblock(kw->pipe[1], 0))
|
||||||
fatal("could not set pipe fds to nonblocking: %s", errno_s);
|
fatal("could not set pipe fds to nonblocking: %s", errno_s);
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case KORE_WORKER_KEYMGR:
|
||||||
|
kw->ps = &keymgr_privsep;
|
||||||
|
break;
|
||||||
|
#if defined(KORE_USE_ACME)
|
||||||
|
case KORE_WORKER_ACME:
|
||||||
|
kw->ps = &acme_privsep;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
kw->ps = &worker_privsep;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
kw->pid = fork();
|
kw->pid = fork();
|
||||||
if (kw->pid == -1)
|
if (kw->pid == -1)
|
||||||
fatal("could not spawn worker child: %s", errno_s);
|
fatal("could not spawn worker child: %s", errno_s);
|
||||||
@ -193,8 +231,34 @@ kore_worker_spawn(u_int16_t idx, u_int16_t id, u_int16_t cpu)
|
|||||||
if (kw->pid == 0) {
|
if (kw->pid == 0) {
|
||||||
kw->pid = getpid();
|
kw->pid = getpid();
|
||||||
kore_worker_entry(kw);
|
kore_worker_entry(kw);
|
||||||
/* NOTREACHED */
|
exit(1);
|
||||||
|
} else {
|
||||||
|
for (cnt = 0; cnt < 50; cnt++) {
|
||||||
|
if (kw->ready == 1)
|
||||||
|
break;
|
||||||
|
usleep(100000);
|
||||||
|
#if defined(__linux__)
|
||||||
|
/*
|
||||||
|
* If seccomp_tracing is enabled, make sure we
|
||||||
|
* handle the SIGSTOP from the child processes.
|
||||||
|
*/
|
||||||
|
if (kore_seccomp_tracing) {
|
||||||
|
if (waitpid(kw->pid, &status, WNOHANG) > 0)
|
||||||
|
kore_seccomp_trace(kw->pid, status);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kw->ready == 0) {
|
||||||
|
kore_log(LOG_NOTICE,
|
||||||
|
"worker %d failed to start, shutting down",
|
||||||
|
kw->id);
|
||||||
|
|
||||||
|
return (KORE_RESULT_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (KORE_RESULT_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct kore_worker *
|
struct kore_worker *
|
||||||
@ -237,9 +301,13 @@ kore_worker_shutdown(void)
|
|||||||
kw->pid = 0;
|
kw->pid = 0;
|
||||||
kw->running = 0;
|
kw->running = 0;
|
||||||
|
|
||||||
|
kw->msg[0]->evt.flags |= KORE_EVENT_READ;
|
||||||
|
net_recv_flush(kw->msg[0]);
|
||||||
|
|
||||||
if (!kore_quiet) {
|
if (!kore_quiet) {
|
||||||
kore_log(LOG_NOTICE, "worker %s exited",
|
kore_log(LOG_NOTICE,
|
||||||
kore_worker_name(kw->id));
|
"worker %s exited (%d)",
|
||||||
|
kore_worker_name(kw->id), status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,37 +350,43 @@ kore_worker_dispatch_signal(int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
kore_worker_privdrop(const char *runas, const char *root)
|
kore_worker_privsep(void)
|
||||||
{
|
{
|
||||||
rlim_t fd;
|
rlim_t fd;
|
||||||
struct rlimit rl;
|
struct rlimit rl;
|
||||||
struct passwd *pw = NULL;
|
struct passwd *pw;
|
||||||
|
|
||||||
if (root == NULL)
|
if (worker == NULL)
|
||||||
fatalx("no root directory for kore_worker_privdrop");
|
fatalx("%s called with no worker", __func__);
|
||||||
|
|
||||||
|
pw = NULL;
|
||||||
|
|
||||||
/* Must happen before chroot. */
|
/* Must happen before chroot. */
|
||||||
if (skip_runas == 0) {
|
if (worker->ps->skip_runas == 0) {
|
||||||
if (runas == NULL)
|
if (worker->ps->runas == NULL) {
|
||||||
fatalx("no runas user given and -r not specified");
|
fatalx("no runas user given for %s",
|
||||||
pw = getpwnam(runas);
|
kore_worker_name(worker->id));
|
||||||
if (pw == NULL) {
|
}
|
||||||
|
|
||||||
|
if ((pw = getpwnam(worker->ps->runas)) == NULL) {
|
||||||
fatalx("cannot getpwnam(\"%s\") for user: %s",
|
fatalx("cannot getpwnam(\"%s\") for user: %s",
|
||||||
runas, errno_s);
|
worker->ps->runas, errno_s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skip_chroot == 0) {
|
if (worker->ps->skip_chroot == 0) {
|
||||||
if (chroot(root) == -1) {
|
if (chroot(worker->ps->root) == -1) {
|
||||||
fatalx("cannot chroot(\"%s\"): %s",
|
fatalx("cannot chroot(\"%s\"): %s",
|
||||||
root, errno_s);
|
worker->ps->root, errno_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chdir("/") == -1)
|
if (chdir("/") == -1)
|
||||||
fatalx("cannot chdir(\"/\"): %s", errno_s);
|
fatalx("cannot chdir(\"/\"): %s", errno_s);
|
||||||
} else {
|
} else {
|
||||||
if (chdir(root) == -1)
|
if (chdir(worker->ps->root) == -1) {
|
||||||
fatalx("cannot chdir(\"%s\"): %s", root, errno_s);
|
fatalx("cannot chdir(\"%s\"): %s",
|
||||||
|
worker->ps->root, errno_s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
|
if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
|
||||||
@ -332,7 +406,7 @@ kore_worker_privdrop(const char *runas, const char *root)
|
|||||||
worker_rlimit_nofiles, errno_s);
|
worker_rlimit_nofiles, errno_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skip_runas == 0) {
|
if (worker->ps->skip_runas == 0) {
|
||||||
if (setgroups(1, &pw->pw_gid) ||
|
if (setgroups(1, &pw->pw_gid) ||
|
||||||
#if defined(__MACH__) || defined(NetBSD)
|
#if defined(__MACH__) || defined(NetBSD)
|
||||||
setgid(pw->pw_gid) || setegid(pw->pw_gid) ||
|
setgid(pw->pw_gid) || setegid(pw->pw_gid) ||
|
||||||
@ -341,7 +415,7 @@ kore_worker_privdrop(const char *runas, const char *root)
|
|||||||
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
|
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
|
||||||
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
|
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
|
||||||
#endif
|
#endif
|
||||||
fatalx("cannot drop privileges");
|
fatalx("cannot drop privileges (%s)", errno_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
kore_platform_sandbox();
|
kore_platform_sandbox();
|
||||||
@ -350,13 +424,16 @@ kore_worker_privdrop(const char *runas, const char *root)
|
|||||||
void
|
void
|
||||||
kore_worker_entry(struct kore_worker *kw)
|
kore_worker_entry(struct kore_worker *kw)
|
||||||
{
|
{
|
||||||
struct kore_runtime_call *rcall;
|
struct kore_runtime_call *sigcall;
|
||||||
u_int64_t last_seed;
|
u_int64_t last_seed;
|
||||||
int quit, had_lock;
|
int quit, had_lock, sig;
|
||||||
u_int64_t netwait, now, next_timeo;
|
u_int64_t netwait, now, next_timeo;
|
||||||
|
|
||||||
worker = kw;
|
worker = kw;
|
||||||
|
|
||||||
|
if (!kore_foreground)
|
||||||
|
closelog();
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
kore_seccomp_traceme();
|
kore_seccomp_traceme();
|
||||||
#endif
|
#endif
|
||||||
@ -367,7 +444,6 @@ kore_worker_entry(struct kore_worker *kw)
|
|||||||
kore_platform_worker_setcpu(kw);
|
kore_platform_worker_setcpu(kw);
|
||||||
|
|
||||||
kore_pid = kw->pid;
|
kore_pid = kw->pid;
|
||||||
|
|
||||||
kore_signal_setup();
|
kore_signal_setup();
|
||||||
|
|
||||||
if (kw->id == KORE_WORKER_KEYMGR) {
|
if (kw->id == KORE_WORKER_KEYMGR) {
|
||||||
@ -391,7 +467,7 @@ kore_worker_entry(struct kore_worker *kw)
|
|||||||
kore_task_init();
|
kore_task_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
kore_worker_privdrop(kore_runas_user, kore_root_path);
|
kore_worker_privsep();
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
http_init();
|
http_init();
|
||||||
@ -432,21 +508,16 @@ kore_worker_entry(struct kore_worker *kw)
|
|||||||
if (nlisteners == 0)
|
if (nlisteners == 0)
|
||||||
worker_no_lock = 1;
|
worker_no_lock = 1;
|
||||||
|
|
||||||
if (!kore_quiet) {
|
worker_runtime_configure();
|
||||||
kore_log(LOG_NOTICE,
|
|
||||||
"worker %d started (cpu#%d, pid#%d)",
|
|
||||||
kw->id, kw->cpu, kw->pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
rcall = kore_runtime_getcall("kore_worker_configure");
|
|
||||||
if (rcall != NULL) {
|
|
||||||
kore_runtime_execute(rcall);
|
|
||||||
kore_free(rcall);
|
|
||||||
}
|
|
||||||
|
|
||||||
kore_module_onload();
|
kore_module_onload();
|
||||||
|
kore_domain_callback(worker_domain_check);
|
||||||
|
|
||||||
|
kore_worker_started();
|
||||||
worker->restarted = 0;
|
worker->restarted = 0;
|
||||||
|
|
||||||
|
sigcall = worker_runtime_signal();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
now = kore_time_ms();
|
now = kore_time_ms();
|
||||||
|
|
||||||
@ -495,8 +566,9 @@ kore_worker_entry(struct kore_worker *kw)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sig_recv != 0) {
|
sig = sig_recv;
|
||||||
switch (sig_recv) {
|
if (sig != 0) {
|
||||||
|
switch (sig) {
|
||||||
case SIGHUP:
|
case SIGHUP:
|
||||||
kore_module_reload(1);
|
kore_module_reload(1);
|
||||||
break;
|
break;
|
||||||
@ -514,6 +586,10 @@ kore_worker_entry(struct kore_worker *kw)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sigcall != NULL)
|
||||||
|
kore_runtime_signal(sigcall, sig);
|
||||||
|
|
||||||
|
if (sig == sig_recv)
|
||||||
sig_recv = 0;
|
sig_recv = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,13 +615,7 @@ kore_worker_entry(struct kore_worker *kw)
|
|||||||
kore_connection_prune(KORE_CONNECTION_PRUNE_DISCONNECT);
|
kore_connection_prune(KORE_CONNECTION_PRUNE_DISCONNECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
rcall = kore_runtime_getcall("kore_worker_teardown");
|
worker_runtime_teardown();
|
||||||
if (rcall != NULL) {
|
|
||||||
kore_runtime_execute(rcall);
|
|
||||||
kore_free(rcall);
|
|
||||||
}
|
|
||||||
|
|
||||||
kore_msg_send(KORE_MSG_PARENT, KORE_MSG_SHUTDOWN, NULL, 0);
|
|
||||||
kore_server_cleanup();
|
kore_server_cleanup();
|
||||||
|
|
||||||
kore_platform_event_cleanup();
|
kore_platform_event_cleanup();
|
||||||
@ -577,16 +647,12 @@ kore_worker_reap(void)
|
|||||||
pid_t pid;
|
pid_t pid;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
pid = waitpid(WAIT_ANY, &status, WNOHANG);
|
pid = waitpid(WAIT_ANY, &status, WNOHANG);
|
||||||
|
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
if (errno == ECHILD)
|
if (errno == ECHILD || errno == EINTR)
|
||||||
return;
|
return;
|
||||||
if (errno == EINTR)
|
kore_log(LOG_ERR, "%s: waitpid(): %s", __func__, errno_s);
|
||||||
continue;
|
|
||||||
kore_log(LOG_ERR,
|
|
||||||
"failed to wait for children: %s", errno_s);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,7 +660,6 @@ kore_worker_reap(void)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
worker_reaper(pid, status);
|
worker_reaper(pid, status);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -669,6 +734,97 @@ kore_worker_keymgr_response_verify(struct kore_msg *msg, const void *data,
|
|||||||
return (KORE_RESULT_OK);
|
return (KORE_RESULT_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_worker_started(void)
|
||||||
|
{
|
||||||
|
const char *chroot;
|
||||||
|
|
||||||
|
if (worker->ps->skip_chroot)
|
||||||
|
chroot = "root";
|
||||||
|
else
|
||||||
|
chroot = "chroot";
|
||||||
|
|
||||||
|
if (!kore_quiet) {
|
||||||
|
kore_log(LOG_NOTICE,
|
||||||
|
"started (#%d %s=%s%s%s)",
|
||||||
|
getpid(), chroot, worker->ps->root,
|
||||||
|
worker->ps->skip_runas ? "" : " user=",
|
||||||
|
worker->ps->skip_runas ? "" : worker->ps->runas);
|
||||||
|
}
|
||||||
|
|
||||||
|
worker->ready = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
worker_runtime_configure(void)
|
||||||
|
{
|
||||||
|
struct kore_runtime_call *rcall;
|
||||||
|
|
||||||
|
rcall = NULL;
|
||||||
|
|
||||||
|
#if defined(KORE_USE_PYTHON)
|
||||||
|
rcall = kore_runtime_getcall(KORE_PYTHON_WORKER_START_HOOK);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (rcall == NULL)
|
||||||
|
rcall = kore_runtime_getcall("kore_worker_configure");
|
||||||
|
|
||||||
|
if (rcall != NULL) {
|
||||||
|
kore_runtime_execute(rcall);
|
||||||
|
kore_free(rcall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct kore_runtime_call *
|
||||||
|
worker_runtime_signal(void)
|
||||||
|
{
|
||||||
|
struct kore_runtime_call *rcall;
|
||||||
|
|
||||||
|
rcall = NULL;
|
||||||
|
|
||||||
|
#if defined(KORE_USE_PYTHON)
|
||||||
|
rcall = kore_runtime_getcall(KORE_PYTHON_SIGNAL_HOOK);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (rcall == NULL)
|
||||||
|
rcall = kore_runtime_getcall("kore_worker_signal");
|
||||||
|
|
||||||
|
return (rcall);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
worker_runtime_teardown(void)
|
||||||
|
{
|
||||||
|
struct kore_runtime_call *rcall;
|
||||||
|
|
||||||
|
rcall = NULL;
|
||||||
|
|
||||||
|
#if defined(KORE_USE_PYTHON)
|
||||||
|
rcall = kore_runtime_getcall(KORE_PYTHON_WORKER_STOP_HOOK);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (rcall == NULL)
|
||||||
|
rcall = kore_runtime_getcall("kore_worker_teardown");
|
||||||
|
|
||||||
|
if (rcall != NULL) {
|
||||||
|
kore_runtime_execute(rcall);
|
||||||
|
kore_free(rcall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
worker_domain_check(struct kore_domain *dom)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (dom->cafile != NULL) {
|
||||||
|
if (stat(dom->cafile, &st) == -1)
|
||||||
|
fatalx("'%s': %s", dom->cafile, errno_s);
|
||||||
|
if (access(dom->cafile, R_OK) == -1)
|
||||||
|
fatalx("'%s': not readable", dom->cafile, errno_s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
worker_reaper(pid_t pid, int status)
|
worker_reaper(pid_t pid, int status)
|
||||||
{
|
{
|
||||||
@ -686,6 +842,9 @@ worker_reaper(pid_t pid, int status)
|
|||||||
if (kw->pid != pid)
|
if (kw->pid != pid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
kw->msg[0]->evt.flags |= KORE_EVENT_READ;
|
||||||
|
net_recv_flush(kw->msg[0]);
|
||||||
|
|
||||||
if (!kore_quiet) {
|
if (!kore_quiet) {
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_NOTICE,
|
||||||
"worker %s (%d) exited with status %d",
|
"worker %s (%d) exited with status %d",
|
||||||
@ -701,8 +860,8 @@ worker_reaper(pid_t pid, int status)
|
|||||||
|
|
||||||
func = "none";
|
func = "none";
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
if (kw->active_hdlr != NULL)
|
if (kw->active_route != NULL)
|
||||||
func = kw->active_hdlr->func;
|
func = kw->active_route->func;
|
||||||
#endif
|
#endif
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_NOTICE,
|
||||||
"worker %d (pid: %d) (hdlr: %s) gone",
|
"worker %d (pid: %d) (hdlr: %s) gone",
|
||||||
@ -720,10 +879,7 @@ worker_reaper(pid_t pid, int status)
|
|||||||
kore_log(LOG_CRIT,
|
kore_log(LOG_CRIT,
|
||||||
"keymgr or acme process gone, stopping");
|
"keymgr or acme process gone, stopping");
|
||||||
kw->pid = 0;
|
kw->pid = 0;
|
||||||
if (raise(SIGTERM) != 0) {
|
kore_quit = 1;
|
||||||
kore_log(LOG_WARNING,
|
|
||||||
"failed to raise SIGTERM signal");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -732,12 +888,12 @@ worker_reaper(pid_t pid, int status)
|
|||||||
worker_unlock();
|
worker_unlock();
|
||||||
|
|
||||||
#if !defined(KORE_NO_HTTP)
|
#if !defined(KORE_NO_HTTP)
|
||||||
if (kw->active_hdlr != NULL) {
|
if (kw->active_route != NULL) {
|
||||||
kw->active_hdlr->errors++;
|
kw->active_route->errors++;
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_NOTICE,
|
||||||
"hdlr %s has caused %d error(s)",
|
"hdlr %s has caused %d error(s)",
|
||||||
kw->active_hdlr->func,
|
kw->active_route->func,
|
||||||
kw->active_hdlr->errors);
|
kw->active_route->errors);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -745,21 +901,25 @@ worker_reaper(pid_t pid, int status)
|
|||||||
kw->pid = 0;
|
kw->pid = 0;
|
||||||
kore_log(LOG_NOTICE,
|
kore_log(LOG_NOTICE,
|
||||||
"worker policy is 'terminate', stopping");
|
"worker policy is 'terminate', stopping");
|
||||||
if (raise(SIGTERM) != 0) {
|
kore_quit = 1;
|
||||||
kore_log(LOG_WARNING,
|
|
||||||
"failed to raise SIGTERM signal");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (kore_quit == 0) {
|
||||||
kore_log(LOG_NOTICE, "restarting worker %d", kw->id);
|
kore_log(LOG_NOTICE, "restarting worker %d", kw->id);
|
||||||
kw->restarted = 1;
|
kw->restarted = 1;
|
||||||
kore_msg_parent_remove(kw);
|
kore_msg_parent_remove(kw);
|
||||||
kore_worker_spawn(idx, kw->id, kw->cpu);
|
|
||||||
|
if (!kore_worker_spawn(idx, kw->id, kw->cpu)) {
|
||||||
|
kore_quit = 1;
|
||||||
|
kore_log(LOG_ERR, "failed to restart worker");
|
||||||
|
} else {
|
||||||
kore_msg_parent_add(kw);
|
kore_msg_parent_add(kw);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -899,7 +1059,10 @@ worker_keymgr_response(struct kore_msg *msg, const void *data)
|
|||||||
case KORE_ACME_CHALLENGE_CLEAR_CERT:
|
case KORE_ACME_CHALLENGE_CLEAR_CERT:
|
||||||
dom->acme_cert_len = 0;
|
dom->acme_cert_len = 0;
|
||||||
dom->acme_challenge = 0;
|
dom->acme_challenge = 0;
|
||||||
|
|
||||||
kore_free(dom->acme_cert);
|
kore_free(dom->acme_cert);
|
||||||
|
dom->acme_cert = NULL;
|
||||||
|
|
||||||
kore_log(LOG_NOTICE, "[%s] tls-alpn-01 challenge disabled",
|
kore_log(LOG_NOTICE, "[%s] tls-alpn-01 challenge disabled",
|
||||||
dom->domain);
|
dom->domain);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user