Jo-Philipp Wich [Fri, 12 Aug 2022 18:54:03 +0000 (20:54 +0200)]
utils: accept '?' as path terminator in uh_path_match()
When matching prefixes against the request URL, we should accept '?' as
valid terminator, similar to '/' and '\0' since logically the query string
is not part of the requested path.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Wed, 10 Aug 2022 19:00:32 +0000 (21:00 +0200)]
file: support using dynamic script handlers as error pages
Rework the current request handler code to not require an error page path
to be an actual file system entity.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 2 Aug 2022 22:23:54 +0000 (00:23 +0200)]
relay: trigger close if in header read state with pending data
In case a relay process exits without printing at least one newline,
relay_close_if_done() will not close the relay context because there's
still pending data in the ustream.
Extend the relevant condition to only consider pending data if the relay
context is not in the header parsing state anymore.
Without this fix, requests triggering such a behaviour will never conclude.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 2 Aug 2022 11:40:28 +0000 (13:40 +0200)]
ucode: ignore exit exceptions
A request handler might legitimately call `exit()`, don't raise a server
error in this case.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 2 Aug 2022 11:40:28 +0000 (13:40 +0200)]
ucode: ignore exit exceptions
A request handler might legitimately call `exit()`, don't raise a server
error in this case.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Tested-by: Stijn Tintel <stijn@linux-ipv6.be>
Hauke Mehrtens [Fri, 1 Jan 2021 01:17:57 +0000 (02:17 +0100)]
cmake: use variables and find_library for dependency
Use FIND_LIBRARY to search the dependency and use variables to reference
them in the CMakeLists file.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
[ improve commit description ]
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Christian 'Ansuel' Marangi [Wed, 1 Jun 2022 12:25:32 +0000 (14:25 +0200)]
client: fix compilation error with GCC 12
Using GCC 12 on an aarch64 target the following compilation error is
printed.
ninja: Entering directory `/home/ansuel/openwrt/build_dir/target-aarch64_cortex-a53_musl/uhttpd-2022-02-07-
2f8b1360'
[1/2] Building C object CMakeFiles/uhttpd.dir/client.c.o
FAILED: CMakeFiles/uhttpd.dir/client.c.o
/home/ansuel/openwrt/staging_dir/host/bin/ccache /home/ansuel/openwrt/staging_dir/toolchain-aarch64_cortex-a53_gcc-12.1.0_musl/bin/aarch64-openwrt-linux-musl-gcc -DHAVE_LUA -DHAVE_SHADOW -DHAVE_TLS -DHAVE_UBUS -DHAVE_UCODE -D_FILE_OFFSET_BITS=64 -Os -pipe -mcpu=cortex-a53 -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -fmacro-prefix-map=/home/ansuel/openwrt/build_dir/target-aarch64_cortex-a53_musl/uhttpd-2022-02-07-
2f8b1360=uhttpd-2022-02-07-
2f8b1360 -Wformat -Werror=format-security -DPIC -fPIC -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -DNDEBUG -Os -Wall -Werror -Wmissing-declarations --std=gnu99 -g3 -MD -MT CMakeFiles/uhttpd.dir/client.c.o -MF CMakeFiles/uhttpd.dir/client.c.o.d -o CMakeFiles/uhttpd.dir/client.c.o -c /home/ansuel/openwrt/build_dir/target-aarch64_cortex-a53_musl/uhttpd-2022-02-07-
2f8b1360/client.c
In function 'tls_redirect_check',
inlined from 'client_header_complete' at client.c:306:7,
inlined from 'client_parse_header' at client.c:338:3,
inlined from 'client_header_cb' at client.c:502:2:
client.c:269:22: error: 'strcmp' reading 1 or more bytes from a region of size 0 [-Werror=stringop-overread]
269 | if (!strcmp(blobmsg_name(cur), "URL"))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
ninja: build stopped: subcommand failed.
Fix this by using the strncmp variant.
Signed-off-by: Christian 'Ansuel' Marangi <ansuelsmth@gmail.com>
Thomas Huehn [Mon, 27 Sep 2021 23:59:39 +0000 (01:59 +0200)]
fix compiler uninitialized variable
In file included from ubus.c:20:
ubus.c: In function 'uh_ubus_list_cb':
libubox/blobmsg.h:256:9: error: 'o' may be used uninitialized in this function [-Werror=maybe-uninitialized]
256 | blob_nest_end(buf, cookie);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
ubus.c:591:19: note: 'o' was declared here
591 | void *t, *o;
| ^
cc1: all warnings being treated as errors
Signed-off-by: Thomas Huehn <thomas.huehn@hs-nordhausen.de>
Acked-by: Alexander Couzens <lynxis@fe80.eu>
Jo-Philipp Wich [Mon, 7 Feb 2022 09:04:11 +0000 (10:04 +0100)]
main: fix leaking -p/-s argument values
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Mon, 7 Feb 2022 08:59:26 +0000 (09:59 +0100)]
ucode: adjust to latest ucode api
The public libucode api has been revised to return and expect an
uc_program_t pointer instead of a main function reference.
The program (former main function) is also not implicitly released
by uc_vm_execute() anymore.
Adjust the ucode plugin accordingly to match the new requirements.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 21 Dec 2021 09:30:35 +0000 (10:30 +0100)]
file: specify UTF-8 as charset for dirlists, add option to override
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 23 Nov 2021 18:34:30 +0000 (19:34 +0100)]
main: add ucode options to help text
Also clarify existing Lua option descriptions while we're at it.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 23 Nov 2021 18:25:18 +0000 (19:25 +0100)]
examples: add ucode handler example
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 23 Nov 2021 10:47:08 +0000 (11:47 +0100)]
ucode: add ucode plugin support
The ucode plugin mirrors the functionality of the Lua module, but using
the ucode script interpreter instead.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 23 Nov 2021 18:21:58 +0000 (19:21 +0100)]
examples: add example Lua handler script
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 23 Nov 2021 16:29:05 +0000 (17:29 +0100)]
listen: avoid invalid memory access
Fixes the following memory access error spotted by valgrind:
Invalid read of size 4
at 0x10D6D3: uh_socket_bind (listen.c:192)
by 0x10C830: add_listener_arg (main.c:128)
by 0x10C830: main (main.c:325)
Address 0x4aa1160 is 0 bytes after a block of size 64 alloc'd
at 0x483877F: malloc (vg_replace_malloc.c:307)
by 0x49ACAC5: gaih_inet.constprop.0 (getaddrinfo.c:1058)
by 0x49AE224: getaddrinfo (getaddrinfo.c:2256)
by 0x10D590: uh_socket_bind (listen.c:145)
by 0x10C830: add_listener_arg (main.c:128)
by 0x10C830: main (main.c:325)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Hauke Mehrtens [Sat, 20 Mar 2021 13:41:45 +0000 (14:41 +0100)]
client: Always close connection with request body in case of error
When we run into an error like a 404 Not Found the request body is not
read and will be parsed as part of the next request. The next Request
will then fail because there is unexpected data in it.
When we run into such a problem with a request body close return an
error and close the connection. This should be easier than trying to
recover the state.
We saw this problem when /ubus/ was not installed, but the browser tried
to access it. Then uhttpd returned a 404, but the next request done in
this connection also failed with a HTTP 400, bad request.
Fixes: FS#3378
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Wojciech Jowsa [Sun, 15 Nov 2020 09:19:17 +0000 (10:19 +0100)]
ubus: fix uhttpd crash
Unregister ubus subscriber in notification remove callback.
Without this call, uhttpd crashes when client tries to subscribe to
the ubus object after the object was unregistred and registered again.
It is bacuse the reference to ubus subscriber is not freed but
the memory is cleared in the uh_request_done function.
Signed-off-by: Wojciech Jowsa <wojciech.jowsa@gmail.com>
Jo-Philipp Wich [Thu, 1 Oct 2020 17:58:27 +0000 (19:58 +0200)]
ubus: fix legacy empty reply format
The legacy ubus protocol must not include an empty object in the result
array if the invoked ubus procedure yielded no response.
This fixes compatibility with existing legacy ubus api clients that expect
this behaviour, LuCI's fs.js in particular.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Thu, 1 Oct 2020 12:59:09 +0000 (14:59 +0200)]
client: fix spurious keepalive connection timeouts
When an uhttpd dispatch_handler provides a data_done callback which is
synchroneously finishing the request through ops->request_done(), the
calling client_poll_post_data() procedure incorrectly resets the resulting
client state from CLIENT_STATE_INIT to CLIENT_STATE_DONE which causes the
next uh_client_read_cb() invocation to bail out since no callback is
available for the CLIENT_STATE_DONE state, effectively discarding the
just received inbound request and sending the persistent connection state
into a deadlock sitation where the http client waits for a response to
its just sent request and uhttpd for further data to read.
Fix this issue by only setting CLIENT_STATE_DONE if the data_done callback
has not modified the state in the meanwhile.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Rafał Miłecki [Wed, 23 Sep 2020 10:43:27 +0000 (12:43 +0200)]
client: really close connection on timeout
After specified time of network inactivity uhttpd is meant to close
connection. It doesn't seem to work thought. After timeout client
doesn't receive any more data but connection it still opened.
This change fixes that.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Rafał Miłecki [Mon, 21 Sep 2020 14:16:23 +0000 (16:16 +0200)]
ubus: support GET method with CORS requests
Complex GET requests (e.g. those with custom headers) require browsers
to send preflight OPTIONS request with:
Access-Control-Request-Method: GET
It's important to reply to such requests with the header
Access-Control-Allow-Origin (and optionally others) to allow CORS
requests.
Adding GET to the Access-Control-Allow-Methods is cosmetical as
according to the Fetch standard:
> If request’s method is not in methods, request’s method is not a
> CORS-safelisted method, and request’s credentials mode is "include" or
> methods does not contain `*`, then return a network error.
It basically means that Access-Control-Allow-Methods value is ignored
for GET, HEAD and POST methods.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Rafał Miłecki [Tue, 15 Sep 2020 18:05:11 +0000 (20:05 +0200)]
ubus: add ACL support for "subscribe" request
With this change ubus will allow users with access to the object pseudo
method ":subscribe" to subscribe for notifications.
1. Move uh_ubus_allowed() up in the code
2. Export "Authorization" parsing code to the uh_ubus_get_auth()
3. Check for ":subscribe" method access
Right now this depends on "Authorization" HTTP header which browsers
don't allow setting for the EventSource. An alternative method of
submitting session token remains to be implemented.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Rafał Miłecki [Mon, 14 Sep 2020 15:15:23 +0000 (17:15 +0200)]
ubus: add new RESTful API
Initial uhttpd ubus API was fully based on JSON-RPC. That restricted it
from supporting ubus notifications that don't fit its model.
Notifications require protocol that allows server to send data without
being polled. There are two candidates for that:
1. Server-sent events
2. WebSocket
The later one is overcomplex for this simple task so ideally uhttps ubus
should support text-based server-sent events. It's not possible with
JSON-RPC without violating it. Specification requires server to reply
with Response object. Replying with text/event-stream is not allowed.
All above led to designing new API that:
1. Uses GET and POST requests
2. Makes use of RESTful URLs
3. Uses JSON-RPC in cleaner form and only for calling ubus methods
This new API allows:
1. Listing all ubus objects and their methods using GET <prefix>/list
2. Listing object methods using GET <prefix>/list/<path>
3. Listening to object notifications with GET <prefix>/subscribe/<path>
4. Calling ubus methods using POST <prefix>/call/<path>
JSON-RPC custom protocol was also simplified to:
1. Use "method" member for ubus object method name
It was possible thanks to using RESTful URLs. Previously "method"
had to be "list" or "call".
2. Reply with Error object on ubus method call error
This simplified "result" member format as it doesn't need to contain
ubus result code anymore.
This patch doesn't break or change the old API. The biggest downside of
the new API is no support for batch requests. It's cost of using RESTful
URLs. It should not matter much as uhttpd supports keep alive.
Example usages:
1. Getting all objects and their methods:
$ curl http://192.168.1.1/ubus/list
{
"dhcp": {
"ipv4leases": {
},
"ipv6leases": {
}
},
"log": {
"read": {
"lines": "number",
"stream": "boolean",
"oneshot": "boolean"
},
"write": {
"event": "string"
}
}
}
2. Getting object methods:
$ curl http://192.168.1.1/ubus/list/log
{
"read": {
"lines": "number",
"stream": "boolean",
"oneshot": "boolean"
},
"write": {
"event": "string"
}
}
3. Subscribing to notifications:
$ curl http://192.168.1.1/ubus/subscribe/foo
event: status
data: {"count":5}
4. Calling ubus object method:
$ curl -d '{
"jsonrpc": "2.0",
"id": 1,
"method": "login",
"params": {"username": "root", "password": "password" }
}' http://192.168.1.1/ubus/call/session
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"ubus_rpc_session": "
01234567890123456789012345678901",
(...)
}
}
$ curl -H 'Authorization: Bearer
01234567890123456789012345678901' -d '{
"jsonrpc": "2.0",
"id": 1,
"method": "write",
"params": {"event": "Hello world" }
}' http://192.168.1.1/ubus/call/log
{
"jsonrpc": "2.0",
"id": 1,
"result": null
}
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Rafał Miłecki [Mon, 14 Sep 2020 14:04:13 +0000 (16:04 +0200)]
ubus: fix blob_buf initialization
Initializing buffer in the uh_ubus_handle_request() didn't handle
batched requests correctly. It resulted in reusing buffer and generating
malformed replies.
Call blob_buf_init() before every usage of the global buf variable.
While at it make two functions take blob_buf pointer as argument:
1. uh_ubus_send_response()
2. uh_ubus_init_json_rpc_response()
This helps following global "buf" variable usage and will help avoiding
similar bugs in the future.
Fixes: 628341fae412 ("ubus: use local "blob_buf" in uh_ubus_handle_request_object()")
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Rafał Miłecki [Wed, 5 Aug 2020 06:58:45 +0000 (08:58 +0200)]
ubus: rename JSON-RPC format related functions
Use "_json_rpc_" in their names so it's clear they are related to the
JSON-RPC format. This cleans up code a bit and will allow adding more
formats in the future.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Rafał Miłecki [Mon, 27 Jul 2020 05:07:34 +0000 (07:07 +0200)]
ubus: use local "blob_buf" in uh_ubus_handle_request_object()
This follows two other functions logic: uh_ubus_send_request() and
uh_ubus_allowed(). Thanks to this change global "buf" variable is used
only for replies and doesn't require state tracking & reinitialization.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Rafał Miłecki [Sat, 25 Jul 2020 08:18:50 +0000 (10:18 +0200)]
ubus: use BLOBMSG_TYPE_UNSPEC for "params" JSON attribute
According to the JSON-RPC 2.0 specification "params" value can be either
an Array or Object. This change makes parse_json_rpc() accept both.
Type validation should be handled by a function that actually reads
"params" depending on expected format. This doesn't change existing
behaviour but allows adding more methods (that expect Object) in the
future.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Rafał Miłecki [Sat, 25 Jul 2020 08:18:49 +0000 (10:18 +0200)]
ubus: drop unused "obj" arguments
Both: uh_ubus_send_request() and uh_ubus_send_list() don't use it.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Rafał Miłecki [Thu, 23 Jul 2020 05:38:07 +0000 (07:38 +0200)]
ubus: parse "call" method params only for relevant call
There is no point in parsing "call" specific params for other ("list")
method calls. This is a minor cleanup that doesn't change uhttpd ubus
behaviour.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Acked-by: Jo-Philipp Wich <jo@mein.io>
Santiago Piccinini [Thu, 10 Oct 2019 20:26:48 +0000 (17:26 -0300)]
proc: do not cancel script killing after writing headers
Before this change if the cgi script hangs after writing headers
then the process will never be killed. Let's only cancel the timeout
if the process ends.
Signed-off-by: Santiago Piccinini <spiccinini@altermundi.net>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Jo-Philipp Wich [Fri, 13 Mar 2020 11:57:44 +0000 (12:57 +0100)]
client: allow keep-alive for POST requests
Allow POST requests via persistent connections to improve performance
especially when using HTTPS on older devices.
After this change, average page load times in LuCI improve significantly
once the TLS connections are initiated.
When testing an ar71xx 19.07.2 build on an ethernet connected TL-WR1043nd
using luci-ssl-openssl and the ustream-openssl backend, the average page
load time for the main status page decreased to 1.3s compared to 4.7s
before, the interface and wireless configuration pages loaded in 1.2s
seconds each compared to the 4.2s and 4.9s respectively before.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Sat, 15 Feb 2020 20:35:40 +0000 (21:35 +0100)]
tls: support specifying accepted TLS ciphers
Introduce a new `-P` option which allows specifying a colon separated list
of accepted TLS ciphers.
Depending on the underlying ustream-ssl provider, the list either follows
OpenSSL's cipher string format or, in case of mbedTLS, is a simple colon
separated cipher whitelist.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 11 Feb 2020 07:59:48 +0000 (08:59 +0100)]
file: poke ustream after starting deferred program
When we're starting a deferred request, the related input ustream might
have gone into read_blocked mode because incoming client request data
exhausted the ustreams internal buffer space. When this happens, edge
triggered uloop read events are "lost" and never re-triggered causing
the script input to never complete.
In order to avoid that deadlock situation, manually poke the input
ustream using ustream_poll() after invoking client_poll_post_data()
which should have drained (some) of the buffered input ustream contents.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Sun, 22 Dec 2019 21:32:00 +0000 (22:32 +0100)]
client: fix invalid data access through invalid content-length values
An invalid data access can be triggered with an HTTP POST request to a CGI
script specifying both `Transfer-Encoding: chunked` and a large negative
`Content-Length`.
The negative content length is assigned to `r->content_length` in
`client_parse_header` and passed as a negative read length to
`ustream_consume` in `client_poll_post_data` which will set the internal
ustream buffer pointer to an invalid address, causing out of bounds memory
reads later on in the code flow.
A similar implicit unsigned to signed conversion happens when parsing
chunk sizes emitted by a CGI program.
Address these issues by rejecting negative values in `r->content_length`
after assigning the `strtoul()` result.
Reported-by: Jan-Niklas Sohn <jan-niklas.sohn@gmx.de>
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Sat, 17 Aug 2019 19:53:38 +0000 (21:53 +0200)]
ubus: increase maximum ubus request size to 64KB
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Hauke Mehrtens [Sun, 16 Jun 2019 20:24:36 +0000 (22:24 +0200)]
uhttpd: Fix multiple format string problems
After format string checks were activated in libubox the compiler
started to complain about multiple missuses in uhttpd. This fixes the
format strings without changing the behavior.
blobmsg_get_string() just checks if the parameter is not NULL and then
calls blobmsg_data() and casts the result.
I think non of these problem is security relevant.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Jo-Philipp Wich [Wed, 28 Nov 2018 11:36:35 +0000 (12:36 +0100)]
cgi: escape url in 403 error output
Escape the untrusted request URL input in the permission denied HTML output.
This fixes certain XSS vulnerabilities which can be leveraged to further
exploit the system.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Paul Willoughby [Wed, 26 Sep 2018 17:53:14 +0000 (11:53 -0600)]
uhttpd: fix building without TLS and Lua support
Adds ifdefs to fix building without TLS and Lua support
Signed-off-by: Paul Willoughby <paulw@spacemonkey.com>
Karl Pálsson [Thu, 1 Nov 2018 12:50:32 +0000 (12:50 +0000)]
help: document -A option
It's one of the parameters used by default in LuCI, so it should be
included in the help output.
Signed-off-by: Karl Palsson <karlp@etactica.com>
Jo-Philipp Wich [Mon, 24 Sep 2018 05:25:55 +0000 (07:25 +0200)]
file: fix CPP syntax error
Fixes: 77b774b ("build: avoid redefining _DEFAULT_SOURCE")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Thu, 23 Aug 2018 07:36:06 +0000 (09:36 +0200)]
build: avoid redefining _DEFAULT_SOURCE
Work around further glibc toolchain annoyances.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Thu, 23 Aug 2018 05:51:56 +0000 (07:51 +0200)]
lua: support multiple Lua prefixes
Allow -l / -L arguments to be repeated to register multiple Lua prefix
handlers in the same process.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 21 Aug 2018 12:24:48 +0000 (14:24 +0200)]
build: use _DEFAULT_SOURCE
Add _DEFAULT_SOURCE FTM in order to avoid warnings with recent glibc.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 21 Aug 2018 09:39:15 +0000 (11:39 +0200)]
uhttpd: recognize PATCH, PUT and DELETE HTTP methods
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 26 Jun 2018 06:35:06 +0000 (08:35 +0200)]
client: flush buffered SSL output when tearing down client ustream
When the outer SSL ustream triggers a change notification due to
encountering EOF, the inner connection ustream might still have
pending data buffered.
Previously, such a condition led to truncated files delivered by
uhttpd via HTTPS and could be triggered by requesting large resources
via slow network links.
Mitigate the problem by propagating the EOF status indicator from
the outer ustream to the inner one and by deferring the client
connection shutdown until the inner ustream output buffer has been
completely drained.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 24 Apr 2018 18:03:19 +0000 (20:03 +0200)]
proc: expose HTTP Origin header in process environment
Map the "Origin:" header as $HTTP_ORIGIN environment variable for use by
request handling processes.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Wed, 4 Apr 2018 14:58:11 +0000 (16:58 +0200)]
file: escape strings in HTML output
Escape untrusted input like the request URL or filesystem paths in HTML
outputs such as the directory listing or 404 error messages.
This fixes certain XSS vulnerabilities which can be leveraged to further
exploit the system.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Wed, 4 Apr 2018 14:56:49 +0000 (16:56 +0200)]
utils: add uh_htmlescape() helper
The uh_htmlescape() function returns a copy of the given string with the
HTML special characters `<`, `>`, `"` and `'` replaced by HTML entities in
hexadecimal notation.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Wed, 4 Apr 2018 13:56:21 +0000 (15:56 +0200)]
Revert "proc: avoid stdio deadlocks"
This reverts commit
ccd9717ba5d501b45fda957f0ea41c4660ef414c.
Jo-Philipp Wich [Wed, 24 Jan 2018 20:02:46 +0000 (21:02 +0100)]
proc: avoid stdio deadlocks
When a request handler accepting post data is too slow in consuming stdin,
uhttpd might deadlock with the master process stuck in a blocking write()
to the child and the child stuck with a blocking write() to the master.
Avoid this issue by putting the master side write end of the child pipe
into nonblocking mode right away and by raising the data_blocked flag
when attempts to write to the child yield EAGAIN.
Setting the flag ensures that client_poll_post_data() does not immediately
trigger a write attempt again, which effectively yields the master write
cycle so that the relay ustream has a chance to consume output of the
client process, thus solving the deadlock.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Wed, 24 Jan 2018 18:45:00 +0000 (19:45 +0100)]
lua: honour size argument in recv() function
The existing implementation incorrectly attempted to read the entire stdin
instead of fetching at most the given amount of bytes.
While we're at it, also make the size argument optional and let it default
to Luas internal buffer size.
Suggested-by: Bryan Mayland <bmayland+lede@capnbry.net>
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Sat, 4 Nov 2017 13:31:40 +0000 (14:31 +0100)]
file: fix query string handling
Instead of storing a pointer to the beginning of the query string within the
request url, store a copy in a static buffer instead. This aligns handling
the query string portion of the url with other elements like physical path
or path info information.
Since the URL is usually kept in the per-client blob buffer which might
change its memory location due to reallocations triggered by blobmsg_add_*,
it is not safe to point to it early in the request life cycle.
This fixes invalid memory access usually manifesting itself as corrupted
query string data in CGI scripts.
Reported-by: P. Wassi <p.wassi@gmx.at>
Suggested-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Adrian Panella [Fri, 21 Jul 2017 19:17:36 +0000 (14:17 -0500)]
uhttpd: add manifest support
Add "text/cache-manifest" mimetype support to enable the possibility of
using Application Cache.
Signed-off-by: Adrian Panella <ianchi74@outlook.com>
Jo-Philipp Wich [Sun, 9 Jul 2017 18:43:36 +0000 (20:43 +0200)]
file: fix basic auth regression
Previous refactoring of the basic auth handling code broke the logic in
such a way that basic auth was only performed if a client sent an
Authorization header in its request, but it was never prompted for by
the server.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Sun, 2 Jul 2017 14:24:07 +0000 (16:24 +0200)]
file: remove unused "auth" member from struct path_info
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Sun, 2 Jul 2017 14:20:45 +0000 (16:20 +0200)]
proc: expose HTTP_AUTH_USER and HTTP_AUTH_PASS
Mimic other web servers like Nginx or Apache and expose the parsed basic
auth information as HTTP_AUTH_USER and HTTP_AUTH_PASS environment variables
to CGI processes.
This also restores login-from-basic-auth functionality in LuCI.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Sun, 2 Jul 2017 14:19:16 +0000 (16:19 +0200)]
auth: store parsed username and password
Store the parsed username and password information as HTTP headers in the
clients header blob buffer for later use by proc.c
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Sun, 2 Jul 2017 14:06:46 +0000 (16:06 +0200)]
proc: do not declare empty process variables
If a HTTP header variable has no corresponding value, then do not set it
to the empty string but to NULL, so that cgi.c will later skip it when
setting up the process environment.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Rosen Penev [Thu, 26 Jan 2017 01:14:23 +0000 (17:14 -0800)]
uhttpd: Add TCP_FASTOPEN support
Provides a small speedup when resuming the connection.
Signed-off by: Rosen Penev <rosenp@gmail.com>
Jo-Philipp Wich [Tue, 25 Oct 2016 15:10:14 +0000 (17:10 +0200)]
lua: ensure that PATH_INFO starts with a slash
When calculating the matching prefix length, make sure to not take the trailing
slash into account in order to ensure that the resulting PATH_INFO string
always starts with a slash.
This ensures that an url like "/foo" against the matching prefix "/" or
"/foo/bar" against "/foo/" result in "/foo" and "/bar" respectively.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Tue, 25 Oct 2016 14:23:05 +0000 (16:23 +0200)]
utils: add proper handling of "/" special case in uh_path_match()
The special prefix of "/" should match any url by definition but the final
assertion which ensures that the matched prefix ends in '\0' or '/' is causing
matches against the "/" prefix to fail.
Add some extra code to handle this special case to implemented the expected
behaviour.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Jo-Philipp Wich [Thu, 8 Oct 2015 17:45:00 +0000 (19:45 +0200)]
cgi: allow conf.cgi_docroot_path to be NULL
The check_cgi_path() function would segfault if we ever support running
uhttpd without any CGI prefix.
Add a check to prevent running uh_patch_match() when the prefix is unset.
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Felix Fietkau [Thu, 6 Oct 2016 13:16:20 +0000 (15:16 +0200)]
file: re-run json handler script after file fallback redirect
This allows the request handler to add extra headers to the response
even in the redirect case.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Florian Fainelli [Mon, 11 Jul 2016 21:01:15 +0000 (14:01 -0700)]
cmake: Find libubox/usock.h
Add a CMake FIND_PATH and INCLUDE_DIRECTORIES searching for libubox/usock.h.
Some external toolchains which do not include standard locations would fail to
find the header otherwise.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Felix Fietkau [Thu, 16 Jun 2016 16:29:59 +0000 (18:29 +0200)]
file: add support for disabling cache related precondition checks via handlers
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Felix Fietkau [Thu, 16 Jun 2016 16:26:18 +0000 (18:26 +0200)]
uhttpd: add support for adding arbitrary headers via handler scripts
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Felix Fietkau [Sun, 8 Nov 2015 19:23:31 +0000 (20:23 +0100)]
file: on redirect, only send content-length header when not using chunked transfer
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Felix Fietkau [Sun, 8 Nov 2015 19:22:18 +0000 (20:22 +0100)]
handler: only send content-length header when not using chunked transfer
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Felix Fietkau [Sun, 8 Nov 2015 19:21:07 +0000 (20:21 +0100)]
handler: add support for overriding redirect status code + message
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Felix Fietkau [Sun, 8 Nov 2015 19:10:02 +0000 (20:10 +0100)]
handler: rename set_uri to rewrite
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Felix Fietkau [Sun, 8 Nov 2015 10:41:42 +0000 (11:41 +0100)]
add support for handling redirects via a script
In a json_script file you can specify rules for rewriting the URL or
redirecting the browser either unconditionally, or as a fallback where
it would otherwise print a 404 error
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Felix Fietkau [Fri, 6 Nov 2015 15:50:13 +0000 (16:50 +0100)]
main: sort getopt characters
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
John Crispin [Tue, 20 Oct 2015 18:12:24 +0000 (20:12 +0200)]
fix the alias support
the path compare return code was not honoured properly
Signed-off-by: John Crispin <blogic@openwrt.org>
John Crispin [Wed, 7 Oct 2015 14:21:10 +0000 (16:21 +0200)]
add a -y parameter for cgi-bin redirects
this allows an alias entry inside the root folder point at a cgi-bin script
-y foo=bar will redirect /foo to /cgi-bin/bar
Signed-off-by: John Crispin <blogic@openwrt.org>
Jo-Philipp Wich [Wed, 7 Oct 2015 21:57:55 +0000 (23:57 +0200)]
fix chunked transfer encoding in keepalive mode
The two commits
5162e3b0ee7bd1d0fd6e75e1ca7993a1834b5291
"allow request handlers to disable chunked reponses"
and
618493e378e2239f0d30902e47adfa134e649fdc
"file: disable chunked encoding for file responses"
broke the chunked transfer encoding handling for proc responses in keep-alive
connections that followed a file response with http status 204 or 304.
The effect of this bug is that cgi responses following a 204 or 304 one where
sent neither in chunked encoding nor with a content-length header, causing
browsers to stall until the keep alive timeout was reached.
Fix the logic flaw by inverting the chunk prevention flag in the client state
and by testing the chunked encoding preconditions every time instead of
once upon client (re-)initialization.
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Andrej Krpic [Wed, 23 Sep 2015 21:33:57 +0000 (23:33 +0200)]
uhttpd: fix wrong header file inclusion for PRI* constant definitions
Signed-off-by: Andrej Krpic <ak77@tnode.com>
Felix Fietkau [Mon, 7 Sep 2015 19:18:26 +0000 (21:18 +0200)]
file: fix processing POST data for deferred requests
Fixes https://dev.openwrt.org/ticket/20458
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Karl Palsson [Mon, 17 Aug 2015 15:19:48 +0000 (15:19 +0000)]
cgi: Support passing X-HTTP-Method-Override header.
As uhttpd doesn't currently support PUT/DELETE/PATCH, allow passing the
commonly used X-HTTP-Method-Override header to CGI scripts.
This is an optional "protocol specific metadata" variable as per rfc
3875 section 4.1.18.
Signed-off-by: Karl Palsson <karlp@remake.is>
Jo-Philipp Wich [Sat, 30 May 2015 21:13:08 +0000 (23:13 +0200)]
client: use 307 instead of 302 for HTTPS redirects
Use the 307 code to force agents to retain the original request method.
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Sat, 30 May 2015 20:48:03 +0000 (22:48 +0200)]
proc: add HTTPS environment variable
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Sat, 30 May 2015 16:25:39 +0000 (18:25 +0200)]
add support for enforcing HTTPS
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Sat, 30 May 2015 13:58:24 +0000 (15:58 +0200)]
file: disable chunked encoding for file responses
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Sat, 30 May 2015 13:48:42 +0000 (15:48 +0200)]
allow request handlers to disable chunked reponses
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
John Crispin [Sat, 28 Mar 2015 16:25:40 +0000 (17:25 +0100)]
properly handle return codes
Signed-off-by: John Crispin <blogic@openwrt.org>
John Crispin [Wed, 11 Mar 2015 08:32:37 +0000 (09:32 +0100)]
fixes for json 0.12
Signed-off-by: John Crispin <blogic@openwrt.org>
Jo-Philipp Wich [Sun, 25 Jan 2015 20:36:42 +0000 (21:36 +0100)]
lua: don't make uhttpd_plugin symbol constant
uhttpd modifies the list_head member of the uhttpd_plugin struct when
loading a plugin, therefore we cannot make it const, otherwise we
trigger a security violation if uhttpd is built with RelRO support.
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Sun, 25 Jan 2015 17:57:31 +0000 (18:57 +0100)]
file: explicitely cast st_mtime to uint64_t when generating ETag
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Sun, 25 Jan 2015 17:13:03 +0000 (18:13 +0100)]
ubus: don't make uhttpd_plugin symbol constant
uhttpd modifies the list_head member of the uhttpd_plugin struct when
loading a plugin, therefore we cannot make it const, otherwise we
trigger a security violation if uhttpd is built with RelRO support.
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Sun, 18 Jan 2015 15:07:04 +0000 (16:07 +0100)]
Build with largefile support
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Andrej Krpic [Mon, 22 Dec 2014 17:55:11 +0000 (18:55 +0100)]
uhttpd: Fix possible memory leaks when generating directory listing
scandir() call requires free() of each returned dirent structure
and parent list. Code constructing HTML response of directory
listing is missing a call to free in some cases.
Signed-off-by: Andrej Krpic <ak77@tnode.com>
Karl Palsson [Thu, 23 Oct 2014 13:00:29 +0000 (13:00 +0000)]
mimetypes: add json and jsonp (distinct from js)
.js files are being transferred as text/javascript, which, although
obsolete by RFC 4329 is most backward compatible.
.json and .jsonp are both transferred as application/octet-stream
however, causing warnings on the console for some browsers, even though
it works just fine.
Add the mimetypes for .json as per RFC 4627 and .jsonp as per RFC4329
(As jsonp _is_ javascript)
Signed-off-by: Karl Palsson <karlp@remake.is>
Jo-Philipp Wich [Mon, 27 Oct 2014 10:19:07 +0000 (11:19 +0100)]
file: do not emit Content-Length header for 304/412 responses
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Mon, 27 Oct 2014 10:18:10 +0000 (11:18 +0100)]
utils: do not emit eof chunk for 204/304 responses
According to RFC2616 10.2.5 and 10.3.5, 204 and 304 responses MUST NOT contain any
message body, therfore do not emit an EOF chunk for such responses.
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Mon, 27 Oct 2014 10:15:35 +0000 (11:15 +0100)]
client: store http code of last emitted response
Certain response types (notably 204 and 304) require a slightly different
handling like emitting the response body entirely, therfore record the last
code to act on it in the appropriate places.
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Wed, 3 Sep 2014 13:19:53 +0000 (15:19 +0200)]
lua: fix error reporting when Lua handler cannot be compiled
Reported-by: Sebastian Apel <sebastian.apel@gmx.de>
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Wed, 3 Sep 2014 13:18:49 +0000 (15:18 +0200)]
main: use proper variable when warning about unsupported features
Reported-by: Sebastian Apel <sebastian.apel@gmx.de>
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Thu, 13 Feb 2014 19:43:43 +0000 (19:43 +0000)]
file: invoke error handler in 403 case as well
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich [Tue, 27 May 2014 12:40:58 +0000 (14:40 +0200)]
ubus: add CORS header support
In order to support cross-domain AJAX requests to the /ubus endpoint
we need to implement the Cross-Origin Resource Sharing (CORS) spec
in the ubus plugin.
- Implement a new option "-X" to enable CORS support in ubus
- Implement rudimentary support for "OPTIONS" HTTP requests
- Implement essential CORS headers the ubus plugin
The current CORS response headers merely reflect the request headers
sent by the client, this way any requesting origin is automatically
allowed. Cross-domain cookies (Access-Control-Allow-Credentials) are
unconditionally enabled.
Restricting permitted origins and toggle the credential accepting can
be made configurable in a future commit to allow more fine grained
control over permitted AJAX clients.
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Felix Fietkau [Sun, 8 Jun 2014 11:50:53 +0000 (13:50 +0200)]
cgi: add _GNU_SOURCE define to fix build error on musl
Signed-off-by: Felix Fietkau <nbd@openwrt.org>