When serving FTP with --auth-proxy, the obscured password was cached in a driver-global map keyed only by the username. Two sessions that logged in with the same username but different credentials shared one map entry, so a later login overwrote it and every subsequent operation on the earlier, still-authenticated session was re-authorized with the later session's credential and executed against the later session's backend. Bind the credential to the FTP session by storing the obscured password in the per-session goftp Session.Data map instead, so each session always resolves the backend it authenticated for.
39 lines
878 B
Go
39 lines
878 B
Go
//go:build ignore
|
|
|
|
// A test auth proxy that maps the supplied password to a backend root.
|
|
//
|
|
// Both roots require the same FTP username ("shared") but different
|
|
// passwords, so it exercises two credentials that share a username but
|
|
// resolve to different backends. The roots are passed in the environment.
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
"os"
|
|
)
|
|
|
|
func main() {
|
|
var in map[string]string
|
|
if err := json.NewDecoder(os.Stdin).Decode(&in); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
roots := map[string]string{
|
|
"attacker-token": os.Getenv("RCLONE_TEST_ATTACKER_ROOT"),
|
|
"victim-token": os.Getenv("RCLONE_TEST_VICTIM_ROOT"),
|
|
}
|
|
root, ok := roots[in["pass"]]
|
|
if in["user"] != "shared" || !ok {
|
|
os.Exit(1)
|
|
}
|
|
|
|
out := map[string]string{
|
|
"type": "local",
|
|
"_root": root,
|
|
}
|
|
if err := json.NewEncoder(os.Stdout).Encode(&out); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|