Commit graph

54 commits

Author SHA1 Message Date
Jo-Philipp Wich
790005cdfa luci-base: dispatcher.lua: support declarative node dependencies
Introduce two new properties for page nodes to allow for declaratively
specifiying system dependencies which is useful to e.g. make certain
views depend on specific uci values or the presence of certain files.

The recognized properties are:

 - `uci_depends` - a nested table in one of the following forms:

     1) `{ config = { section = { option = "exact_value" } }`
     2) `{ config = { section = { option = true } }`
     3) `{ config = { section = "exact_type" } }`
     4) `{ config = { section = true } }`
     5) `{ config = true }`

   Depending on the declaration, the uci option or section type must either
   match the given "exact_value" or "exact_type" values or be a non-nil value
   in case boolean "true" is specified.

 - `file_depends` - a flat lists of file paths that must be accessible

   If a path listed in `file_depends` points to a directory, that directory
   must be not empty, otherwise it suffices if the path exists.

Examples:

 - Only display the node if an /etc/config/wireless file exists with
   a "config wifi-device radio0" section.

    node = page(...)
    node.uci_depends = { wireless = { radio0 = "wifi-device" } }

 - Only display the node when swconfig is installed.

    node = page(...)
    node.file_depends = { "/sbin/swconfig" }

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2019-11-01 12:03:33 +01:00
Jo-Philipp Wich
f8c6eb67cd luci-base: fix CSRF prevention for arcombine targets
The dispatcher failed to propagate the child target post security
requirements to the arcombine() dispatch target so far - fix this
by recursively testing the post security requirements.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2019-10-09 09:55:44 +02:00
Jo-Philipp Wich
2beb9fa16f luci-base: add client based view actions
Introduce a new view() target for CBI dispatch nodes, as long with the
required template and plumbing work in luci.js to allow requiring view
classes.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2019-07-07 15:25:49 +02:00
Jo-Philipp Wich
4141243762 luci-base: dispatcher: support raw values in attr() and ifattr()
Extend the attr() and ifattr() template functions to take an optional
further parameter indicating that the passed value should not be escaped.

This is needed for cases where the input already is escaped through
other means, e.g. when the value was previously filtered through the
striptags() template helper.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2019-02-12 08:31:08 +01:00
Jo-Philipp Wich
2509b5984d luci-base: dispatcher: use consistent ordering
Use the same ordering logic for building the dispatch tree and for
querying the children of a given node.

Fixes #2338.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-11-27 15:25:05 +01:00
Jo-Philipp Wich
2e36e09303 luci-base: dispatcher: remove tree modifier support
This feature was never used, is hardly documented and appears to be
designed to fiddle with the internal dispatch tree state.

Given that, simply drop the related code to simplify the dispatcher
class somewhat.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-11-27 14:46:55 +01:00
Jo-Philipp Wich
425a02734e luci-base: dispatcher: add login indication on 403 errors
Send a custom LuCI X-Header to indicate that a login is required to access
the requested resource. This is mainly intended for xhr.js to be able to
intercept such responses and popup an authentication dialog.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-11-16 21:11:34 +01:00
Jo-Philipp Wich
7a98222106 luci-base: remove references to luci.i18n.loadc()
The i18n.loadc() function has been a no-op since almost six years so it
makes no sense to invoke it anymore.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-11-05 11:01:45 +01:00
Jo-Philipp Wich
11f7817d33 luci-base: dispatcher: introduce firstnode() dispatching target
The firstnode target will dispatch the request to the first eligible menu
subtree node that is not a redirect to another node, a special action or
post security enabled page.

That action is specifically useful for global category toplevel nodes like
"admin" which are supposed to simply direct access to the first installed
page node without having to hardcode specific choices.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-09-19 20:08:19 +02:00
Daniel F. Dickinson
6ec0353201 modules: Make luci-base sufficient to use luci apps
Per the discussion in https://github.com/openwrt/luci/issues/869, make
luci-base sufficient to login, logout, and review and apply or revert
uci changes.  This allows most luci-app-xxx to work without having
luci-mod-admin-full installed.

It has been tested with some apps and not luci-mod-admin-full, as well
as with luci-mod-admin-full (to make sure the usual case doesn't break).

Instead of creating a new module namespace (e.g. 'Base') we reduce the
opportunities for breakage by having luci-base take over the 'shell' of
the 'Administration' (admin/....) namespace.

Since admin is assumed by all current building LuCI components (including
Freifunk), this doesn't introduce the 'Administration' tab into any
situation where it would not already be present (but includes it where it
was before).

We also add a "Component not installed" page to avoid fatal errors and
backtrace when e.g. luci-mod-admin-full is not installed.

Signed-off-by: Daniel F. Dickinson <cshored@thecshore.com>
2018-09-19 20:08:19 +02:00
Jo-Philipp Wich
e5a1ac0228 treewide: rework rollback/apply workflow
Rework the apply confirmation mechanism to be session agnostic in order to
circumvent cross domain restrictions which prevent the JS code from issuing
apply confirm requests in some cases, e.g. when changing the LAN IP.

Confirmation calls may now be done from unauthenticated pages, as long as a
matching confirmation token is sent along with the request.

The reasoning behind this is that there is little security impact in
confirming pending apply sessions, especially since those sessions can only
be initiated while being authenticated.

After this change, LuCI will now launch a confirmation process on every
rendered page when a rollback is pending. The confirmation will happen
regardless of whether the user is logged in or not, or if the current page
is a CBI form or static template.

A confirmation request now also requires a random one-time token which is
rendered along with the confirmation JavaScript code in order to succeed.

This token is not meant to provide security but to ensure that the confirm
was triggered from an interactive browser session and not some background
HTTP requests that happened to end up in the admin ui.

As a consequence, the different apply/confirm/rollback code paths in CBI
maps and the UCI change/revert pages have been consolidated into one common
implementation residing in the common global theme agnostic footer template.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-07-27 14:07:23 +02:00
Jo-Philipp Wich
3aba615029 luci-base: rework "in request" flagging logic for menu nodes
The previous implementation failed to mark active nodes under some
circumstances.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-07-02 08:46:26 +02:00
Jo-Philipp Wich
298d164dd7 luci-base: update coxpcall() implementation, fix runtime error reporting
Sync our coxpcall() implementation to the newest upstream version in order to
get access to the inner backtrace information and propagate these traces to
the browser in luci.dispatcher.dispatch().

This should make tracking down runtime errors much easier.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-05-31 17:45:49 +02:00
Ansuel Smith
da1e655294
luci-base: fix dispacher fail
http.getenv("SCRIPT_NAME") fail if it's not provided. This can happen in the login screen when we don't have any script to load.

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
2018-05-23 02:52:08 +02:00
Jo-Philipp Wich
828202ef52
Merge pull request #1769 from jow-/master
UCI apply/rollback workflow
2018-05-18 16:44:33 +02:00
Yousong Zhou
2f0f456b71 luci-base: harden cookie sysauth=
A simple scan of the code indicates that currently no code in the repo
is accessing the sysauth= cookie

Closes openwrt/luci#1555

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
2018-05-13 18:30:47 +08:00
Jo-Philipp Wich
8deb949551 treewide: rework uci apply workflow
Switch to rpcd based uci apply/rollback workflow which helps to avoid soft-
bricking devices by requiring an explicit confirmation call after config
apply.

When a user now clicks "Save & Apply", LuCI first issues a call to uci apply
which commits and reloads configuration, then goes into a polling countdown
mode where it repeatedly attempts to call uci confirm.

If the committed configuration is sane, the confirm call will go through and
cancel rpcd's pending rollback timer.

If the configuration change leads to a loss of connectivity (e.g. due to bad
firewall rules or similar), the rollback mechanism will kick in after the
timeout and revert configuration files and pending changes to the pre-apply
state.

In order to cover such rare cases where a lost of connectivity is expected
and desired, the user is offered an "unchecked" apply option after timing
out, which allows committing and applying the changes anyway, without the
extra safety checks.

As a consequence of this change, the luci-reload mechanism is now completely
unsused since rpcd uses ubus config reload signals to reload affected
services, which means that only procd-enabled services will receive proper
reload treatment with the new workflow.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-05-05 23:11:23 +02:00
Jo-Philipp Wich
7cca313959 luci-base: enable uci session isolation
Switch to per-session save directories to decouple LuCI configuration changes
from system wide ones.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-05-05 23:11:23 +02:00
Jo-Philipp Wich
8459ec0ec8 luci-base: add simple CORS handling to luci.dispatcher
Support a new boolean property `cors` which - if set to true - causes the
dispatcher to positively answer CORS OPTIONS requests after authentication
without actually running the dispatching target.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-04-26 08:26:30 +02:00
Jo-Philipp Wich
2b516423a0 luci-base: fix rendering of 404 HTML error template
This 404 error template rendering has been broken for a long time due to bad
function environment level in luci.template when invoking the rendering from
the toplevel dispatcher context.

Fix this issue by adding a local function indirection, essentially adding an
additional stack frame.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-04-10 12:03:15 +02:00
Jo-Philipp Wich
b194b8882e luci-base: don't propagate null bytes in path information
It is possible to inject unescaped markup using a double encoded null byte
via PATH_INFO on certain leaf nodes.

Since there is no legitimate reason to handle null bytes in any part of the
requested url, simply skip over such bytes when parsing the PATH_INFO value.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-04-10 11:41:32 +02:00
Jo-Philipp Wich
b1b5723516 luci-base: consider empty parameters as well when testing POST requirement
The cbi class will react on an empty "cbi.submit" parameter as well so we
must intercept GET requests using that too.

Fixes 186e690c0 ("luci-base: dispatcher: reject non-POST requests with any cbi.submit value")

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-04-09 07:19:28 +02:00
Jo-Philipp Wich
bf71ae5f1b luci-base: emit a warning if cbi() delegates a SimpleForm instance
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-04-06 12:07:49 +02:00
Jo-Philipp Wich
7b04d0bbcf luci-base: introduce luci.dispatcher.lookup()
The lookup function takes multiple, possibly malformed path fragments,
splits them on slashes, constructs a temporary path and looks up the
result in the dispatch tree.

If a matching node has been found, the function will return both the
node reference and the canonical url to it.

If no corresponding node is found, the function returns nil.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-04-05 23:03:01 +02:00
Jo-Philipp Wich
186e690c08 luci-base: dispatcher: reject non-POST requests with any cbi.submit value
Due to the fact that luci.model.cbi reacts on any "cbi.submit" value while
the dispatcher only required POST for cbi.submit == 1, the CSRF token
protection could be bypassed.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-04-05 00:15:22 +02:00
Jo-Philipp Wich
8c617c02b5 luci-base: add FULL_REQUEST_URI template property
Introduce a new template property FULL_REQUEST_URI which returns the full
canonicalized request URL built from SCRIPT_NAME, PATH_INFO and QUERY_STRING.

This new property is safer to use compared to using the raw REQUEST_URI CGI
environment variable directly as this value is essentially untrusted user
input which may contain embedded escaped slashes, double forward slashes and
other oddities allowing XSS exploitation or request redirection.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-04-04 23:24:31 +02:00
Jo-Philipp Wich
a441721d32 luci-base: log login attempts
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2018-01-17 18:49:42 +01:00
Jo-Philipp Wich
15cb504b44 luci-base: improve language detection
Properly deal with client accept languages containing a culture identifier
such as "zh-CN" or "pt-BR".

Fixes #1226.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2017-08-13 15:55:22 +02:00
Jo-Philipp Wich
4e1b884157 luci-base: properly handle authentication without authenticator
Some controller actions like the ones in "servicectl" require authentication
but are not meant to provide an authenticator because they're only invoked
by scripts.

Rework the dispatcher logic to handle this situation and only bail out if
an authenticator name other than "htmlauth" is set.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2017-07-11 14:12:50 +02:00
Jo-Philipp Wich
d6360bf81e luci-base: use rpcd session logins
Drop the custom credentials checking in favor to perform proper session
logins via rpcd. This is needed to properly setup ACLs when spawning
rpcd sessions in order to support direct client side ubus access in the
future.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2017-07-09 21:35:26 +02:00
Jo-Philipp Wich
57121f3743 luci-base: luci.dispatcher: allow overriding sysauth template
In some cases it is useful to be able to override the template used for the
sysauth login dialog.

Add a new property "sysauth_template" which allows overriding the template
name from controller files.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
2017-05-06 15:06:07 +02:00
Matthias Schiffer
c8675d0c55 modules/base: dispatcher: use default language if automatic choice fails
Fall back to default language if "auto" is configured, but none provided by
the browser matches.

Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
2016-03-01 17:25:55 +01:00
Jo-Philipp Wich
8f409a45ab luci-base: dispatcher: let attr() automatically serialize JSON
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2016-02-10 19:31:10 +01:00
Hannu Nyman
c2cf5d1855 Fix embedded links: github instead of luci.subsignal.org
Fix links to point into Github repo instead of luci.subsignal.org
 - the hint to file a bug in dispatcher
 - footers of Bootstrap and Firefunk themes

Signed-off-by: Hannu Nyman <hannu.nyman@iki.fi>
2016-02-02 12:07:16 +02:00
Jo-Philipp Wich
81e80c4b87 luci-base: properly handle ubus connections for non-root (#570, #571)
Instead of relying on the connect-before-setuid hack, ship a proper
acl definition file whitelisting the procedures that LuCI requires
on its non-root pages.

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2016-01-11 15:21:46 +01:00
Jo-Philipp Wich
d32c685039 luci-base: dispatcher expose test_post_security()
Allows external code to perform POST and token checking manually.

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-10-22 08:30:29 +02:00
Jo-Philipp Wich
79383f5a74 luci-base: ensure that base url is emitted with trailing slash
Now that we don't have an url token anymore, '/cgi-bin/luci' becomes a valid
url while cookies are restricted to only '/cgi-bin/luci/' and below.

In order to ensure that the first request after login refers to a path
covered by the authentication cookie, change build_url() to always append
a trailing slash if we're referring to the base url.

This should fix the login problems mentioned in #516.

While we're touching the dispatcher, also remove remaining url token code.

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-10-21 16:48:25 +02:00
Jo-Philipp Wich
86326e0def luci-base: remove security token from urls
Now that sensitive urls require post requests and only accept them if a valid
security token is sent along the request, we can drop the global random url
token to improve LuCI usability.

The main improvement is the ability to use multiple tabs with the same login
session, but also deep linking to specific urls without the need for another
login becomes feasible, e.g. for documentation purposes.

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-10-21 00:31:27 +02:00
Jo-Philipp Wich
562c47e5fd luci-base: generalize post security token handling
* Add a generic helper function to check need for post / csrf token validation
* Remove custom token verification in cbi targets
* Support requiring post security depending on specific submit parameters,
  usable through post_on() action

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-10-20 21:04:46 +02:00
Jo-Philipp Wich
49a2cb5ad1 luci-base: expose luci.dispatcher.build_url() as url() in templates
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-10-07 13:03:42 +02:00
Jo-Philipp Wich
3f29078fb9 luci-base: protect simpleforms with CSRF tokens
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-10-07 12:24:58 +02:00
Jo-Philipp Wich
8d46c20327 luci-base: protect CBI forms with CSRF tokens
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-10-06 18:54:35 +02:00
Jo-Philipp Wich
5a6382171d luci-base: add support for POST-only actions with CSRF token check
Add the dispatcher infrastructure to restrict certain routes to POST
requests only in conjunction with verification of CSRF tokens.

This is the first step to get rid of the CSRF token in the url in favor
to tokens embedded in forms.

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-10-06 15:56:35 +02:00
Jo-Philipp Wich
ec1a86977b Avoid setting duplicate cookies
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-02-09 16:30:11 +01:00
Jo-Philipp Wich
ec90cd69ed luci-base: pass session timeout as integer
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-02-09 13:03:44 +01:00
Jo-Philipp Wich
993cf12229 luci-base: establish ubus connection before dropping privileges (#310)
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-02-09 12:14:20 +01:00
Jo-Philipp Wich
84346cd178 Move inline documentation into separate files.
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-01-29 16:26:46 +01:00
Jo-Philipp Wich
83d520ab07 luci-base: improve login/logout handling
Redirect to the canonical url after login and redirect to an url without
security token if the session expired. Also make sure that the login page
is served with status code 403, not 200 to give ajax calls a chance to
detect expired sessions.

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-01-26 17:31:21 +01:00
Jo-Philipp Wich
7a3493b1f7 Globally reduce copyright headers
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-01-16 23:38:38 +01:00
Jo-Philipp Wich
9980114624 luci-base: remove luci.init
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
2015-01-16 21:40:49 +01:00