serve sftp: fix auth proxy configured via rc being silently ignored GHSA-p569-5gjg-9cmj CVE-PENDING
From v1.70.0, an SFTP server started through the rc serve/start API with
a per-server proxyOpt.AuthProxy decided whether to enable proxy
authentication by checking the process-global proxy.Opt.AuthProxy
instead of the supplied proxyOpt.AuthProxy. In the normal rc case the
global is empty, so the auth proxy was silently ignored: the server
either failed to start with "no authorization found" or authenticated
against the local authorized_keys file instead of routing each login
through the proxy the operator configured.
The serve Provider refactor (f425f8d46) fixed the constructor by building the
provider from the supplied proxyOpt, but the authorized-keys handling in
configure() still consulted the global option. Make it depend on whether
proxy mode is actually active, and add a regression test for the
per-server option.
This commit is contained in:
@@ -143,12 +143,12 @@ func (s *server) configure() (err error) {
|
||||
var authorizedKeysMap map[string]struct{}
|
||||
|
||||
// ensure the user isn't trying to use conflicting flags
|
||||
if proxy.Opt.AuthProxy != "" && s.opt.AuthorizedKeys != "" && s.opt.AuthorizedKeys != Opt.AuthorizedKeys {
|
||||
if s.provider.IsProxy() && s.opt.AuthorizedKeys != "" && s.opt.AuthorizedKeys != Opt.AuthorizedKeys {
|
||||
return errors.New("--auth-proxy and --authorized-keys cannot be used at the same time")
|
||||
}
|
||||
|
||||
// Load the authorized keys
|
||||
if s.opt.AuthorizedKeys != "" && proxy.Opt.AuthProxy == "" {
|
||||
if s.opt.AuthorizedKeys != "" && !s.provider.IsProxy() {
|
||||
authKeysFile := env.ShellExpand(s.opt.AuthorizedKeys)
|
||||
authorizedKeysMap, err = loadAuthorizedKeys(authKeysFile)
|
||||
// If user set the flag away from the default then report an error
|
||||
|
||||
@@ -78,6 +78,32 @@ func TestSftp(t *testing.T) {
|
||||
servetest.Run(t, "sftp", start)
|
||||
}
|
||||
|
||||
// TestNewServerPerServerAuthProxy checks that a per-server proxyOpt.AuthProxy
|
||||
// enables proxy mode even when the process-global proxy.Opt.AuthProxy is empty,
|
||||
// which is the normal case when the server is configured via serve/start.
|
||||
func TestNewServerPerServerAuthProxy(t *testing.T) {
|
||||
// Ensure the global is empty so we only test the per-server option.
|
||||
assert.Equal(t, "", proxy.Opt.AuthProxy)
|
||||
|
||||
opt := Opt
|
||||
opt.ListenAddr = testBindAddress
|
||||
|
||||
proxyOpt := proxy.Opt
|
||||
proxyOpt.AuthProxy = "/path/to/auth/proxy"
|
||||
|
||||
w, err := newServer(context.Background(), nil, &opt, &vfscommon.Opt, &proxyOpt)
|
||||
require.NoError(t, err)
|
||||
// Shutdown waits for Serve to finish, so Serve must be running first.
|
||||
go func() {
|
||||
assert.NoError(t, w.Serve())
|
||||
}()
|
||||
defer func() {
|
||||
assert.NoError(t, w.Shutdown())
|
||||
}()
|
||||
assert.True(t, w.provider.IsProxy(), "expected auth proxy to be enabled by per-server option")
|
||||
assert.Nil(t, w.provider.VFS(), "expected no fixed VFS when auth proxy is in use")
|
||||
}
|
||||
|
||||
func TestRc(t *testing.T) {
|
||||
servetest.TestRc(t, rc.Params{
|
||||
"type": "sftp",
|
||||
|
||||
Reference in New Issue
Block a user