Skip to content

Commit

Permalink
[FIXED] Do not bypass authorization blocks when turning on $SYS accou…
Browse files Browse the repository at this point in the history
…nt access (#4605)

Only setup auto no-auth for $G account iff no authorization block was
defined.

Signed-off-by: Derek Collison <derek@nats.io>

Resolves #4535
  • Loading branch information
derekcollison committed Sep 28, 2023
2 parents 3d5564b + 2737c56 commit fa5b7af
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 11 deletions.
5 changes: 4 additions & 1 deletion server/opts.go
Expand Up @@ -395,6 +395,9 @@ type Options struct {

// OCSP Cache config enables next-gen cache for OCSP features
OCSPCacheConfig *OCSPResponseCacheConfig

// Used to mark that we had a top level authorization block.
authBlockDefined bool
}

// WebsocketOpts are options for websocket
Expand Down Expand Up @@ -885,7 +888,7 @@ func (o *Options) processConfigFileLine(k string, v interface{}, errors *[]error
*errors = append(*errors, err)
return
}

o.authBlockDefined = true
o.Username = auth.user
o.Password = auth.pass
o.Authorization = auth.token
Expand Down
17 changes: 10 additions & 7 deletions server/opts_test.go
Expand Up @@ -120,6 +120,7 @@ func TestConfigFile(t *testing.T) {
LameDuckDuration: 4 * time.Minute,
ConnectErrorReports: 86400,
ReconnectErrorReports: 5,
authBlockDefined: true,
}

opts, err := ProcessConfigFile("./configs/test.conf")
Expand All @@ -132,13 +133,14 @@ func TestConfigFile(t *testing.T) {

func TestTLSConfigFile(t *testing.T) {
golden := &Options{
ConfigFile: "./configs/tls.conf",
Host: "127.0.0.1",
Port: 4443,
Username: "derek",
Password: "foo",
AuthTimeout: 1.0,
TLSTimeout: 2.0,
ConfigFile: "./configs/tls.conf",
Host: "127.0.0.1",
Port: 4443,
Username: "derek",
Password: "foo",
AuthTimeout: 1.0,
TLSTimeout: 2.0,
authBlockDefined: true,
}
opts, err := ProcessConfigFile("./configs/tls.conf")
if err != nil {
Expand Down Expand Up @@ -283,6 +285,7 @@ func TestMergeOverrides(t *testing.T) {
LameDuckDuration: 4 * time.Minute,
ConnectErrorReports: 86400,
ReconnectErrorReports: 5,
authBlockDefined: true,
}
fopts, err := ProcessConfigFile("./configs/test.conf")
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion server/routes_test.go
Expand Up @@ -105,7 +105,8 @@ func TestRouteConfig(t *testing.T) {
NoAdvertise: true,
ConnectRetries: 2,
},
PidFile: "/tmp/nats-server/nats_cluster_test.pid",
PidFile: "/tmp/nats-server/nats_cluster_test.pid",
authBlockDefined: true,
}

// Setup URLs
Expand Down
4 changes: 2 additions & 2 deletions server/server.go
Expand Up @@ -1239,8 +1239,8 @@ func (s *Server) configureAccounts(reloading bool) (map[string]struct{}, error)
// If we have defined a system account here check to see if its just us and the $G account.
// We would do this to add user/pass to the system account. If this is the case add in
// no-auth-user for $G.
// Only do this if non-operator mode.
if len(opts.TrustedOperators) == 0 && numAccounts == 2 && opts.NoAuthUser == _EMPTY_ {
// Only do this if non-operator mode and we did not have an authorization block defined.
if len(opts.TrustedOperators) == 0 && numAccounts == 2 && opts.NoAuthUser == _EMPTY_ && !opts.authBlockDefined {
// If we come here from config reload, let's not recreate the fake user name otherwise
// it will cause currently clients to be disconnected.
uname := s.sysAccOnlyNoAuthUser
Expand Down
27 changes: 27 additions & 0 deletions server/server_test.go
Expand Up @@ -19,6 +19,7 @@ import (
"context"
"crypto/tls"
"encoding/json"
"errors"
"flag"
"fmt"
"io"
Expand Down Expand Up @@ -2080,3 +2081,29 @@ func TestServerRateLimitLogging(t *testing.T) {

checkLog(c1, c2)
}

// https://github.com/nats-io/nats-server/discussions/4535
func TestServerAuthBlockAndSysAccounts(t *testing.T) {
conf := createConfFile(t, []byte(`
listen: 127.0.0.1:-1
server_name: s-test
authorization {
users = [ { user: "u", password: "pass"} ]
}
accounts {
$SYS: { users: [ { user: admin, password: pwd } ] }
}
`))

s, _ := RunServerWithConfig(conf)
defer s.Shutdown()

// This should work of course.
nc, err := nats.Connect(s.ClientURL(), nats.UserInfo("u", "pass"))
require_NoError(t, err)
defer nc.Close()

// This should not.
_, err = nats.Connect(s.ClientURL())
require_Error(t, err, nats.ErrAuthorization, errors.New("nats: Authorization Violation"))
}

0 comments on commit fa5b7af

Please sign in to comment.