When KORE_MEM_GUARD is set in the environment when Kore is started
it will enable a few memory protection techniques for all kore pools:
1) The metadata is placed away from the actual user pointer returned.
2) Each entry in a pool is placed in such a way that it is followed
immediately by a guard page which has PROT_NONE. Accessing a guard
page will cause an immediate crash.
3) Each entry is marked with PROT_NONE until it is allocated. Once it
is returned to a pool it becomes PROT_NONE again, protecting against
use after frees.
This commit also removes the magic goo from the mem facitilies such
as kore_malloc and friends and moves these as canaries into the kore
pool facilities instead.
Note that using this will increase memory pressure and decrease performance.
It is recommended to enable this during development to catch bugs.
We used to just call EVP_PKEY_get1_RSA() and set the domain
and RSA_METHOD on that.
But with OpenSSL 3, the EVP_PKEY_get1_RSA() function returns a cached
copy of the internal provider struct and any changes we make are not
reflected back. So we can't use it to set the domain and custom method.
Instead just create our own EVP_PKEY from scratch, coupled with an
RSA key that contains just n and e from the public key.
Works with both 1.1.x and 3.0.x.
Allow passing of an env keyword, allowing you to set environment variables
that may be required by the subprocess.
The env keyword must be a list with correctly formed environment variables.
eg:
proc = kore.proc("/bin/myproc",
env=[
"LD_LIBRARY_PATH=/my/path"
]
)
The _PyInterpreterFrame_GetLine() is hidden in dynamic libs so
roll our own variant of it.
Shuffle the old code so we always end up calling python_resolve_frame_line()
no matter the Python version.
In the upcoming Python 3.11 release the PyCoroObject no longer
has a full PyFrameObject, but instead their internal frame
struct _PyInterpreterFrame. Use that when we are building
against 3.11 or higher so we can still provide useful tracing
functionality (and so that it builds).
Kore used to just stall the connection until the timeout kicked
in, but if no proper headers were received by the time the header
buffer is full we should just error out.
While here, use s_off for the inital length check.
When receiving an HTTP body, Kore never reset http_timeout once
the transfer was done.
This can result in a 408 being thrown by Kore while a request is
activity running.
The worker_count is incremented by 2 earlier to account for keymgr/acme
but aren't actually workers that should count towards CPU pinning.
So adjust the count when comparing to cpu_count when logging that there
are more workers than cpus.
The crl keyword is parsed when the client_verify keyword has been set.
eg:
kore.domain("kore.io", cert="cert.pem", key="key.pem",
client_verify="cacert.pem", verify_depth=1, crl="crl.pem")
This commit introduces the ability to add authenticators to filemaps.
Just like in normal routes, the authenticators will be resolved first
before allowing access to the filemap entries.
Configuration wise, the authenticator is an optional value after the
filemap config directive:
filemap / webroot myauth
In the Python API you can now pass the authenticator for a filemap entry
but turning the value of the filemap into a tuple with the first entry
being the path and the second being the auth dict:
AUTH AUTH={
"type": "cookie",
"value": "cookiename",
"redirect": "/auth/",
"verify": verify_cookie
}
domain.filemaps({
"/css/": "webroot/css",
"/secret/": ("webroot/secret", AUTH)
})
The parent process never differentiated between a worker process
asking for a shutdown or a worker process calling fatalx() when
it came to its exit code.
I made some changes here so the parent process will exit with
an exit code 1 if anything worker related went wrong (fatalx/death policy).
The coroutines results are now relayed back via PyIter_Send() and
no longer obtainable via _PyGen_FetchStopIterationValue().
This means that our kore.gather() would not be able to return any
values from any of the coroutines it governed.
Fix this by saving the object returned in PyIter_Send() and using it
later in pygather_reap_coro().