2522 Commits
Author SHA1 Message Date
Nicola Murino a276f9dc05 WebClient: add a render function to the dir browser meta field
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-24 11:20:24 +02:00
Nicola Murino 5542293ab9 fix test cases on Windows
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 23:48:03 +02:00
Nicola Murino 9e670437d0 suppress lint warnings
we should consider to remove the gocyclo linter

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:34:25 +02:00
Nicola Murino b77556a7d2 service: warn at startup when running with an effective uid of 0
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:32:01 +02:00
Nicola Murino fdadfe102a httpd: do not end a streamed listing on a batch with nothing to render
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:31:35 +02:00
Nicola Murino 1497afd09c vfs: skip the listing entries that do not address an entry inside
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:29:03 +02:00
Nicola Murino f15a87ebca templates: bound the two factor requests with their timeout
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:22:30 +02:00
Nicola Murino 787b9b6094 sftpd: align SCP name parsing with OpenSSH
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:21:54 +02:00
Nicola Murino 4b93982fa8 common: do not apply the user transfer limits to the event actions
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:20:21 +02:00
Nicola Murino c96f671f26 sftpd: bound the SCP download recursion
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:19:49 +02:00
Nicola Murino 75b6262c72 sftpd: read the directory entries through the shared listing on SCP download
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:18:18 +02:00
Nicola Murino fadc353ef9 sftpd: clean the path before the SCP download checks
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:16:35 +02:00
Nicola Murino b42c16be9a sftpd: report the SCP download errors once
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:14:51 +02:00
Nicola Murino b4d870aa9a common: check the target write permission and quota on the server-side copy
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:12:17 +02:00
Nicola Murino de6bc600a3 common: report a hidden path as missing consistently
this is a best effort and outside the security boundaries

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:10:30 +02:00
Nicola Murino b7a2404f77 common: match the entries when a rename changes the filter scope
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 22:04:19 +02:00
Nicola Murino d389a3b048 common: apply the name filter wherever a directory is created
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:56:15 +02:00
Nicola Murino 03368b8d34 common: authorize a directory copy before it creates anything
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:52:15 +02:00
Nicola Murino 604664b5a1 common: evaluate the name filter on the source of copy, rename and symlink
The file pattern filter matches names, and the operations that read an item
evaluate it on the item itself. Three did not agree with that: a copy
evaluated it on the target only, a rename mapped every refusal to a
permission error and so discarded the deny policy configured on the filter,
and symlink creation honored the hide policy alone, letting the default one
through.

They now all evaluate the source and report the configured policy through
GetErrorForDeniedFile, as stat, download and delete already do, so the same
filter gives the same answer whichever operation reaches a name. The target
keeps reporting a permission error: it is a path being written, not an item
being read. isRenamePermitted returns an error and is renamed accordingly;
the recursive walk still reports a permission error, because the entries it
walks are the contents of the directory being renamed and a hidden one among
them must not make that directory look missing.

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:50:00 +02:00
Nicola Murino da38e0f4e1 sftpd: refuse to hash a path that ends with a slash
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:46:17 +02:00
Nicola Murino 15a67758da httpd: refuse an authorization request without a browser identifier
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:42:52 +02:00
Nicola Murino 75527eb2e6 sftpd: ignore a trailing slash in the path to hashsftpd: ignore a trailing slash in the path to hash
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:42:03 +02:00
Nicola Murino 18f9b41920 ftpd: end the pre auth session once the client is banned
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:39:37 +02:00
Nicola Murino 80265143e1 security policy: scope out the observable effect of pre auth controls
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:36:39 +02:00
Nicola Murino 3215f91deb sftpd: read the file through a transfer to compute a hash
The read goes through a regular download transfer, so it honors the data
transfer quota and the bandwidth limit, it counts towards the transfer limits,
it is listed among the active transfers and can be monitored and aborted, and
it triggers the pre-download and download events.

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:36:08 +02:00
Nicola Murino 479b584c43 sftpd: require the download permission to compute a file hash
Computing a digest reads the whole file, so the hash commands now require the
download permission on the parent directory, the same check a download
performs. They previously accepted the list permission: accounts granted list
without download now get a permission denied error.

Reported-by: @cyny666

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:18:51 +02:00
Nicola Murino db5cda1388 webdavd: key the user cache on the stored username
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:17:07 +02:00
Nicola Murino c32f5b5c47 httpd: bind the OAuth2 token request to the browser that started it
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:14:54 +02:00
Nicola Murino 55952bcf67 httpd: bind the OIDC authorization request to the browser that started it
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:14:05 +02:00
Nicola Murino 0da768877c dataprovider: apply the anonymous restrictions at runtime
they were applied during the validation

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:13:05 +02:00
Nicola Murino 641f263317 dataprovider: apply the naming rules to the username the external auth returns
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:05:43 +02:00
Nicola Murino 961999f54b dataprovider: pass the plugin auth scope down the keyboard interactive flow
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:01:52 +02:00
Nicola Murino 701c852f49 remove duplicated log
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 21:01:03 +02:00
Nicola Murino 8f079955bb ftpd: refactor TLS requirement
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 20:59:48 +02:00
Nicola Murino c4092cee08 sftpd: ask for the password before resolving the account
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 20:53:46 +02:00
Nicola Murino 40e97113a1 httpd: return the same response for password reset requests that send no code
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-12 20:45:48 +02:00
Nicola Murino 96287a099f suppress a lint warning
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-04 14:08:42 +02:00
Nicola Murino be4340ebbc httpd: add OIDC option to read claims from the UserInfo endpoint
With query_userinfo enabled, the UserInfo endpoint is queried after
authentication and the user claims are read from both sources. Claims
from the verified ID token take precedence on conflicts, empty values
do not override, and the UserInfo subject must match the ID token
subject. The option is validated at startup against the provider
metadata.

Reading the claims from the UserInfo endpoint was requested in #2265
and an implementation, enabled by default and with the opposite claim
precedence, was proposed in #2266.

Fixes #2265
Closes #2266

Suggested-by: TEC <git@tecosaur.net>

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-04 13:10:17 +02:00
Nicola Murino 270f3fc431 httpd: tie share login tokens to the share signature
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-04 09:35:00 +02:00
Nicola Murino 98712e8c9d update sponsors section
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-03 22:55:47 +02:00
Nicola Murino 5a4ff1a0b0 update deps
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-03 22:45:50 +02:00
Nicola Murino 236a9c7c68 vfs: various os.Root improvements
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-03 22:43:59 +02:00
Nicola Murino 5baff82564 vfs: abort a pending Azure copy when the poll loop gives up
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-03 22:24:27 +02:00
Nicola Murino e3bc808686 common: compare the resolved copy paths within the same namespace
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-03 22:23:13 +02:00
Nicola Murino 441beec0de httpd: report a logout that cannot invalidate the token
The token manager Add now reports whether the entry was persisted and the
provider-backed manager logs the failure, so an invalidation that does not
happen leaves a trace instead of being dropped in silence.

The REST admin and user logout propagate the error and answer 500: the
response states that the token has been invalidated, so it must not be
sent while the token is still usable. invalidateToken also reports an
error for a request without a verified token, there is nothing to
invalidate in that case.

Invalidation that is a side effect of another operation stays best effort
and does not gate that operation's result: the password is already
changed, the request is already rejected, the pre-login token goes away
with the cookie. Those call sites rely on the token manager log.

The web logout paths keep clearing the login cookie and redirecting
instead of rendering an error page: the client is logged out locally
either way, and a failed store write only matters to someone who already
holds a copy of the token.

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-03 21:48:16 +02:00
Nicola Murino f4cacb8e20 httpd: key the JWT invalidation store on the token ID
Invalidation was keyed on the exact token text, so an equivalent
Base64URL spelling of the same signed token did not match the stored
entry and kept working after a logout. The store is now keyed on the
"jti" claim, which is invariant across equivalent encodings of one token.

This is a correctness fix and not a privilege boundary: producing an
equivalent spelling requires already holding a valid signed token, it
grants no additional access, and the token remains usable only until its
own expiry, a bound it never exceeds.

Reported-by: Corban Villa (@corbanvilla)
Reported-by: Sohee Kim (@soh3e)
Reported-by: Austin Chu (@dderpym)

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-08-03 21:27:22 +02:00
Nicola Murino 8331745946 windows installer: remove explicit permissions
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-07-26 12:59:00 +02:00
dependabot[bot] 42f7a4d415 build(deps): bump actions/setup-go from 6 to 7 (#2267)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6 to 7.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 19:46:26 +02:00
Nicola Murino dbbcf4d741 Fix additional flaky Windows tests
we should add a common helper

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-07-18 17:04:57 +02:00
Nicola Murino eca67e750a fixed some test cases
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
2026-07-18 16:19:48 +02:00