diff --git a/go.mod b/go.mod index be6b70e9..7e921fa2 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/golang/protobuf v1.4.2 // indirect github.com/klauspost/compress v1.13.4 github.com/minio/highwayhash v1.0.1 - github.com/nats-io/jwt/v2 v2.1.0 + github.com/nats-io/jwt/v2 v2.2.0 github.com/nats-io/nats.go v1.13.1-0.20211018182449-f2416a8b1483 github.com/nats-io/nkeys v0.3.0 github.com/nats-io/nuid v1.0.1 diff --git a/go.sum b/go.sum index b7b2c150..b5c80979 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ github.com/klauspost/compress v1.13.4 h1:0zhec2I8zGnjWcKyLl6i3gPqKANCCn5e9xmviEE github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz/0= github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= -github.com/nats-io/jwt/v2 v2.1.0 h1:1UbfD5g1xTdWmSeRV8bh/7u+utTiBsRtWhLl1PixZp4= -github.com/nats-io/jwt/v2 v2.1.0/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k= +github.com/nats-io/jwt/v2 v2.2.0 h1:Yg/4WFK6vsqMudRg91eBb7Dh6XeVcDMPHycDE8CfltE= +github.com/nats-io/jwt/v2 v2.2.0/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k= github.com/nats-io/nats.go v1.13.1-0.20211018182449-f2416a8b1483 h1:GMx3ZOcMEVM5qnUItQ4eJyQ6ycwmIEB/VC/UxvdevE0= github.com/nats-io/nats.go v1.13.1-0.20211018182449-f2416a8b1483/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= diff --git a/server/auth.go b/server/auth.go index 5f5c9298..2e5031d2 100644 --- a/server/auth.go +++ b/server/auth.go @@ -1104,7 +1104,9 @@ func validateAllowedConnectionTypes(m map[string]struct{}) error { for ct := range m { ctuc := strings.ToUpper(ct) switch ctuc { - case jwt.ConnectionTypeStandard, jwt.ConnectionTypeWebsocket, jwt.ConnectionTypeLeafnode, jwt.ConnectionTypeMqtt: + case jwt.ConnectionTypeStandard, jwt.ConnectionTypeWebsocket, + jwt.ConnectionTypeLeafnode, jwt.ConnectionTypeLeafnodeWS, + jwt.ConnectionTypeMqtt: default: return fmt.Errorf("unknown connection type %q", ct) } diff --git a/server/client.go b/server/client.go index 11fe8759..aeb0d6e2 100644 --- a/server/client.go +++ b/server/client.go @@ -5172,7 +5172,9 @@ func convertAllowedConnectionTypes(cts []string) (map[string]struct{}, error) { for _, i := range cts { i = strings.ToUpper(i) switch i { - case jwt.ConnectionTypeStandard, jwt.ConnectionTypeWebsocket, jwt.ConnectionTypeLeafnode, jwt.ConnectionTypeMqtt: + case jwt.ConnectionTypeStandard, jwt.ConnectionTypeWebsocket, + jwt.ConnectionTypeLeafnode, jwt.ConnectionTypeLeafnodeWS, + jwt.ConnectionTypeMqtt: m[i] = struct{}{} default: unknown = append(unknown, i) @@ -5206,7 +5208,11 @@ func (c *client) connectionTypeAllowed(acts map[string]struct{}) bool { want = jwt.ConnectionTypeMqtt } case LEAF: - want = jwt.ConnectionTypeLeafnode + if c.isWebsocket() { + want = jwt.ConnectionTypeLeafnodeWS + } else { + want = jwt.ConnectionTypeLeafnode + } } _, ok := acts[want] return ok diff --git a/server/leafnode_test.go b/server/leafnode_test.go index 5d1e19b5..feb6dc5d 100644 --- a/server/leafnode_test.go +++ b/server/leafnode_test.go @@ -22,6 +22,7 @@ import ( "math/rand" "net" "net/url" + "os" "strings" "sync" "sync/atomic" @@ -3032,12 +3033,12 @@ func TestLeafNodeWSFailedConnection(t *testing.T) { } func TestLeafNodeWSAuth(t *testing.T) { - conf := createConfFile(t, []byte(fmt.Sprintf(` + template := ` port: -1 authorization { users [ {user: "user", pass: "puser", connection_types: ["%s"]} - {user: "leaf", pass: "pleaf", connection_types: ["%s"]} + {user: "leaf", pass: "pleaf", connection_types: ["%s"%s]} ] } websocket { @@ -3047,20 +3048,40 @@ func TestLeafNodeWSAuth(t *testing.T) { leafnodes { port: -1 } - `, jwt.ConnectionTypeStandard, jwt.ConnectionTypeLeafnode))) - defer removeFile(t, conf) - o, err := ProcessConfigFile(conf) - if err != nil { - t.Fatalf("Error processing config file: %v", err) - } - o.NoLog, o.NoSigs = true, true - s := RunServer(o) + ` + s, o, conf := runReloadServerWithContent(t, + []byte(fmt.Sprintf(template, jwt.ConnectionTypeStandard, jwt.ConnectionTypeLeafnode, ""))) + defer os.Remove(conf) defer s.Shutdown() + l := &captureErrorLogger{errCh: make(chan string, 10)} + s.SetLogger(l, false, false) + lo := testDefaultRemoteLeafNodeWSOptions(t, o, false) + u, _ := url.Parse(fmt.Sprintf("ws://leaf:pleaf@127.0.0.1:%d", o.Websocket.Port)) + remote := &RemoteLeafOpts{URLs: []*url.URL{u}} + lo.LeafNode.Remotes = []*RemoteLeafOpts{remote} + lo.LeafNode.ReconnectInterval = 50 * time.Millisecond ln := RunServer(lo) defer ln.Shutdown() + var lasterr string + tm := time.NewTimer(2 * time.Second) + for done := false; !done; { + select { + case lasterr = <-l.errCh: + if strings.Contains(lasterr, "authentication") { + done = true + } + case <-tm.C: + t.Fatalf("Expected auth error, got %v", lasterr) + } + } + + ws := fmt.Sprintf(`, "%s"`, jwt.ConnectionTypeLeafnodeWS) + reloadUpdateConfig(t, s, conf, fmt.Sprintf(template, + jwt.ConnectionTypeStandard, jwt.ConnectionTypeLeafnode, ws)) + checkLeafNodeConnected(t, s) checkLeafNodeConnected(t, ln) diff --git a/vendor/github.com/nats-io/jwt/v2/header.go b/vendor/github.com/nats-io/jwt/v2/header.go index 3dece6a1..198bf306 100644 --- a/vendor/github.com/nats-io/jwt/v2/header.go +++ b/vendor/github.com/nats-io/jwt/v2/header.go @@ -23,7 +23,7 @@ import ( const ( // Version is semantic version. - Version = "2.1.0" + Version = "2.2.0" // TokenTypeJwt is the JWT token type supported JWT tokens // encoded and decoded by this library diff --git a/vendor/github.com/nats-io/jwt/v2/signingkeys.go b/vendor/github.com/nats-io/jwt/v2/signingkeys.go index 87fc951a..0d8a5b93 100644 --- a/vendor/github.com/nats-io/jwt/v2/signingkeys.go +++ b/vendor/github.com/nats-io/jwt/v2/signingkeys.go @@ -120,9 +120,12 @@ func (sk SigningKeys) Validate(vr *ValidationResults) { } // MarshalJSON serializes the scoped signing keys as an array -func (sk SigningKeys) MarshalJSON() ([]byte, error) { +func (sk *SigningKeys) MarshalJSON() ([]byte, error) { + if sk == nil { + return nil, nil + } var a []interface{} - for k, v := range sk { + for k, v := range *sk { if v != nil { a = append(a, v) } else { @@ -132,7 +135,10 @@ func (sk SigningKeys) MarshalJSON() ([]byte, error) { return json.Marshal(a) } -func (sk SigningKeys) UnmarshalJSON(data []byte) error { +func (sk *SigningKeys) UnmarshalJSON(data []byte) error { + if *sk == nil { + *sk = make(SigningKeys) + } // read an array - we can have a string or an map var a []interface{} if err := json.Unmarshal(data, &a); err != nil { @@ -141,7 +147,7 @@ func (sk SigningKeys) UnmarshalJSON(data []byte) error { for _, i := range a { switch v := i.(type) { case string: - sk[v] = nil + (*sk)[v] = nil case map[string]interface{}: d, err := json.Marshal(v) if err != nil { @@ -153,7 +159,7 @@ func (sk SigningKeys) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(d, &us); err != nil { return err } - sk[us.Key] = us + (*sk)[us.Key] = us default: return fmt.Errorf("unknown signing key scope %q", v["type"]) } diff --git a/vendor/github.com/nats-io/jwt/v2/user_claims.go b/vendor/github.com/nats-io/jwt/v2/user_claims.go index 0c8ccbeb..d8a3a6c9 100644 --- a/vendor/github.com/nats-io/jwt/v2/user_claims.go +++ b/vendor/github.com/nats-io/jwt/v2/user_claims.go @@ -23,10 +23,12 @@ import ( ) const ( - ConnectionTypeStandard = "STANDARD" - ConnectionTypeWebsocket = "WEBSOCKET" - ConnectionTypeLeafnode = "LEAFNODE" - ConnectionTypeMqtt = "MQTT" + ConnectionTypeStandard = "STANDARD" + ConnectionTypeWebsocket = "WEBSOCKET" + ConnectionTypeLeafnode = "LEAFNODE" + ConnectionTypeLeafnodeWS = "LEAFNODE_WS" + ConnectionTypeMqtt = "MQTT" + ConnectionTypeMqttWS = "MQTT_WS" ) type UserPermissionLimits struct { diff --git a/vendor/modules.txt b/vendor/modules.txt index a71b7fe2..8a790725 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -6,7 +6,7 @@ github.com/klauspost/compress/s2 # github.com/minio/highwayhash v1.0.1 ## explicit github.com/minio/highwayhash -# github.com/nats-io/jwt/v2 v2.1.0 +# github.com/nats-io/jwt/v2 v2.2.0 ## explicit github.com/nats-io/jwt/v2 # github.com/nats-io/nats.go v1.13.1-0.20211018182449-f2416a8b1483