WebDAV — Basic, or a bearer token
tls {
cert_file = "/etc/fileshare/tls/fullchain.pem"
key_file = "/etc/fileshare/tls/key.pem"
}
serve "webdav" {
addr = "0.0.0.0:443"
tls = true
}HTTP Basic, or a bearer token — over TLS, from files or from ACME.
Not in the clear, since v0.9.0
HTTP Basic is the password on every request, and a bearer token is as good
as one. WebDAV without TLS, on an address other machines can reach,
while anybody authenticates, is refused at startup —
serve "webdav" { addr = "0.0.0.0:8080" }, the example this page used to
show, no longer starts. When a proxy terminates TLS in front of it, say so:
serve "webdav" {
addr = "10.0.0.5:8080"
plaintext = true
}Loopback, and a server with nobody to authenticate, are unaffected. See TLS.
404, not 403
A share a person may not use answers 404. It is not confirmed to exist.
A token, over the one protocol that can carry one
oidc {
issuer = "https://login.example.org"
audience = "fileshare"
}A browser has a token and no password. So WebDAV accepts Authorization: Bearer, and where there are local people too, the challenge it sends offers
both — a client picks the one it can answer. The token is verified by
go-authn/oidc: signature, issuer, audience,
expiry.
A bearer token: only WebDAV
SMB authenticates with NTLMv2, SFTP with a key or a certificate, NFS with
nothing at all, and S3 with a SigV4 signature: none of them has anywhere to
put an Authorization header. That is a fact about the protocols, not a
limit of this program.
The provider’s word reaches SFTP in a certificate instead — see SFTP. A configuration naming a provider and serving neither WebDAV nor such an SFTP is refused rather than started.
A token says who the provider thinks somebody is. It does not say this server has a share for them.
A valid token for a name no source here knows is refused — the safe reading
of I do not know you is not you are allowed. Nor is a name a local
account also has that account, unless local_names = true says the
provider’s names are this server’s (off by default, since v0.20.0); without
it, such a token is refused too, unless an oidc: rule names the person.
A site where the provider is the directory says so:
oidc {
issuer = "https://login.example.org"
audience = "fileshare"
trust_all = true # everybody that provider vouches for, not just these people
}There is no login flow here: no redirect, no client secret, no cookies. This is the resource server.
The name a token gives is preferred_username, or the claim
username_claim names. Without preferred_username, it is the email only if
the provider says email_verified: true, and otherwise sub. With
username_claim = "email", a token whose email is not verified is refused —
over WebDAV, and for an opkssh login over SFTP alike. Until it is verified,
the email is only what the person typed, and a signed token that carried it
would bind as an address nobody checked (OpenID Connect Core 5.1;
go-authn/oidc v0.2.0, fileshare v0.16.3).
Which of the provider’s people get a share — groups, named people, whole
institutions — is written with oidc: rules and domains; see
people the identity provider names.
A token outlives the person, unless something says otherwise
A token is verified here, on its own, and is valid until it expires — whatever
happened to the person since. No revocation list can name it. An
ssf block makes a CAEP session-revoked
from the provider void every token issued (iat) before it.
The root, and uploads in pieces
The root lists the shares (since v0.29.0). A browser at / gets a page of
the shares it may open; a PROPFIND of / gets them as collections (207), so
a file manager can mount the whole server rather than one share. Depth
infinity is refused (403, propfind-finite-depth, as RFC 4918 allows), and
so is anything that would write at the root (405). Up to v0.28 every method at
/ got the page.
A large upload can go in pieces (since v0.29.0). One PUT is held in memory
whole, up to 1 GiB, so a client that cannot stream — a browser, the
file explorer — sends an empty
PUT, then each piece with a Content-Range that starts exactly where the last
one ended, then a MOVE to the real name. A range that starts past the end is
still 416: it would leave bytes nobody sent.
Created on by tannevaled
Modified on by tannevaled