rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
wa_guard.h File Reference

Which requests the Wi-Fi page answers at all: the Host header, the Origin or Referer of a write, the upload's own header and the size of a body. More...

#include <stdbool.h>
#include <stdint.h>

Go to the source code of this file.

Data Structures

struct  wa_self_t
 The panel as a request may name it. More...
struct  wa_req_t
 The request's headers as the guard reads them. NULL is a header not sent; a value longer than the platform's buffer is passed as "", sent and matching nothing. More...

Macros

#define WA_UPLOAD_HDR   "X-Rcbench-Upload"
 The upload's own request header.
#define WA_UPLOAD_VAL   "1"
 The value the page's script gives WA_UPLOAD_HDR.
#define WA_CODE_BODY_MAX   95u
 Bytes of the code form's body at most: "code=" and 8 characters, each up to 3 bytes percent-encoded, with room to spare.
#define WA_HTTP_PORT   80u
 The port the page's server listens on.

Enumerations

enum  wa_req_kind_t { WA_REQ_READ = 0 , WA_REQ_CODE , WA_REQ_UPLOAD }
 What the request is to the guard. More...
enum  wa_guard_t {
  WA_GUARD_OK = 0 , WA_GUARD_HOST , WA_GUARD_BODY , WA_GUARD_BIG ,
  WA_GUARD_ORIGIN , WA_GUARD_UPLOAD
}
 The guard's answer. More...

Functions

bool wa_host_ok (const char *host, const wa_self_t *self)
 Whether host, a Host header's value, names the panel.
bool wa_origin_ok (const char *origin, const char *referer, const wa_self_t *self)
 Whether a write comes from the panel's own page.
wa_guard_t wa_guard (wa_req_kind_t kind, const wa_req_t *req, const wa_self_t *self)
 The guard: Host first, then the body, then a write's Origin and the upload's header.
const char * wa_guard_status (wa_guard_t g)
 The HTTP status line of a refusal, "421 Misdirected Request" and the like.

Detailed Description

Which requests the Wi-Fi page answers at all: the Host header, the Origin or Referer of a write, the upload's own header and the size of a body.

Three attacks are refused here, before any access code or card read.

  • DNS (domain name system) rebinding: a web page whose name resolves to the panel's address sends its own name as Host. Every request needs a Host that names the panel: its mDNS (multicast DNS) name "rcbench-1A2B.local", the bare "rcbench-1A2B" the home router's DNS may know from the panel's DHCP (dynamic host configuration protocol) host name, or the IPv4 address the request came in on. Letters compare without regard to case; a port, when given, is 80. Anything else, an IPv6 literal included, is WA_GUARD_HOST (HTTP 421).
  • A cross-site write: any page the browser has open can POST to the panel. A write needs an Origin that is "http://" and an allowed Host; without an Origin, a Referer that starts that way. Neither, "null", https and a foreign name are WA_GUARD_ORIGIN (HTTP 403).
  • A cross-site upload that the browser sends without asking: the upload needs WA_UPLOAD_HDR: WA_UPLOAD_VAL, which the page's own script sets. A header of its own makes a cross-site request a CORS (cross-origin resource sharing) one with a preflight, and the panel answers no preflight with an allow. Missing or other: WA_GUARD_UPLOAD (403).

And a slow body: a read takes none (WA_GUARD_BODY, HTTP 400), the code form at most WA_CODE_BODY_MAX bytes (WA_GUARD_BIG, HTTP 413). The body of a refused request is never read; the connection closes with the answer.

Pure C, no ESP-IDF (Espressif Internet-of-Things Development Framework).

SPDX-License-Identifier: MIT

Enumeration Type Documentation

◆ wa_guard_t

enum wa_guard_t

The guard's answer.

Enumerator
WA_GUARD_HOST 

Host missing or not the panel: 421

WA_GUARD_BODY 

a read with a body: 400

WA_GUARD_BIG 

a code form over WA_CODE_BODY_MAX: 413

WA_GUARD_ORIGIN 

a write from another site, or unknown: 403

WA_GUARD_UPLOAD 

an upload without WA_UPLOAD_HDR: 403

◆ wa_req_kind_t

What the request is to the guard.

Enumerator
WA_REQ_READ 

GET: the page, a file, the ZIP

WA_REQ_CODE 

POST of the code form

WA_REQ_UPLOAD 

POST of a firmware image

Function Documentation

◆ wa_guard()

wa_guard_t wa_guard ( wa_req_kind_t kind,
const wa_req_t * req,
const wa_self_t * self )

The guard: Host first, then the body, then a write's Origin and the upload's header.

Parameters
kindwhat the request is
reqits headers
selfthe panel
Returns
WA_GUARD_OK, or the first check that refuses it

◆ wa_guard_status()

const char * wa_guard_status ( wa_guard_t g)

The HTTP status line of a refusal, "421 Misdirected Request" and the like.

Parameters
gthe answer; WA_GUARD_OK gives "200 OK"
Returns
a constant string

◆ wa_host_ok()

bool wa_host_ok ( const char * host,
const wa_self_t * self )

Whether host, a Host header's value, names the panel.

Parameters
hostthe value; NULL refuses
selfthe panel
Returns
true for the panel's name, as above, or its address

◆ wa_origin_ok()

bool wa_origin_ok ( const char * origin,
const char * referer,
const wa_self_t * self )

Whether a write comes from the panel's own page.

Parameters
originthe Origin header, or NULL
refererthe Referer header, read only when origin is NULL
selfthe panel
Returns
true for "http://" and a host wa_host_ok() takes, and after it nothing (Origin) or "/", "?", "#" or nothing (Referer)