diff --git a/go.sum b/go.sum index 0d2227f7..951bc44e 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,7 @@ github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/minio/highwayhash v1.0.0 h1:iMSDhgUILCr0TNm8LWlSjF8N0ZIj2qbO8WHp6Q/J2BA= github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc= +github.com/nats-io/jwt v0.3.2 h1:+RB5hMpXUUA2dfxuhBTEkMOrYmM+gKIZYS1KjSostMI= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/jwt v0.3.3-0.20200519195258-f2bf5ce574c7 h1:RnGotxlghqR5D2KDAu4TyuLqyjuylOsJiAFhXvMvQIc= github.com/nats-io/jwt v0.3.3-0.20200519195258-f2bf5ce574c7/go.mod h1:n3cvmLfBfnpV4JJRN7lRYCyZnw48ksGsbThGXEk4w9M= diff --git a/server/jwt.go b/server/jwt.go index d9d0c916..029a5e46 100644 --- a/server/jwt.go +++ b/server/jwt.go @@ -105,6 +105,24 @@ func validateTrustedOperators(o *Options) error { return fmt.Errorf("system_account in config and operator JWT must be identical") } } + srvMajor, srvMinor, srvUpdate, _ := jwt.ParseServerVersion(strings.Split(VERSION, "-")[0]) + for _, opc := range o.TrustedOperators { + if major, minor, update, err := jwt.ParseServerVersion(opc.AssertServerVersion); err != nil { + return fmt.Errorf("operator %s expects version %s got error instead: %s", + opc.Subject, opc.AssertServerVersion, err) + } else if major > srvMajor { + return fmt.Errorf("operator %s expected major version %d > server major version %d", + opc.Subject, major, srvMajor) + } else if srvMajor > major { + } else if minor > srvMinor { + return fmt.Errorf("operator %s expected minor version %d > server minor version %d", + opc.Subject, minor, srvMinor) + } else if srvMinor > minor { + } else if update > srvUpdate { + return fmt.Errorf("operator %s expected update version %d > server update version %d", + opc.Subject, update, srvUpdate) + } + } // If we have operators, fill in the trusted keys. // FIXME(dlc) - We had TrustedKeys before TrustedOperators. The jwt.OperatorClaims // has a DidSign(). Use that longer term. For now we can expand in place. diff --git a/server/opts_test.go b/server/opts_test.go index f1355826..913a01c5 100644 --- a/server/opts_test.go +++ b/server/opts_test.go @@ -2664,3 +2664,51 @@ func TestReadOperatorJWTSystemAccountMismatch(t *testing.T) { t.Fatalf("Received unexpected error %s", err) } } + +const operatorJwtAssertVersion_1_2_3 = ` + listen: "127.0.0.1:-1" + // Operator "TESTOP" + operator: eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJYWFhGNEREQTdRSEtCSU5MUlBSNTZPUFFTUjc0RFdLSjZCQkZWN1BSVEpMNUtDUUdCUFhBIiwiaWF0IjoxNTkwNTI4NTI1LCJpc3MiOiJPRDRYSkwyM0haSlozTzZKQ0FGUTZSVk9ZR0JZWUtGU0tIRlJFWkRaUEJGN1I0SlpQSTVWNzNLTSIsInN1YiI6Ik9ENFhKTDIzSFpKWjNPNkpDQUZRNlJWT1lHQllZS0ZTS0hGUkVaRFpQQkY3UjRKWlBJNVY3M0tNIiwibmF0cyI6eyJhc3NlcnRfc2VydmVyX3ZlcnNpb24iOiIxLjIuMyIsInR5cGUiOiJvcGVyYXRvciIsInZlcnNpb24iOjJ9fQ.ERRsFUekK7W5tZbeYlkLlwU3AGMpZTtlh5jKIj2rWoLnoWLlWcjXYD4uKdaT-tNGbsahiQZV82C5_K89BCWODA + resolver: MEMORY + resolver_preload: { + } +` + +func TestReadOperatorAssertVersion(t *testing.T) { + confFileName := createConfFile(t, []byte(operatorJwtAssertVersion_1_2_3)) + defer os.Remove(confFileName) + opts, err := ProcessConfigFile(confFileName) + if err != nil { + t.Fatalf("Received unexpected error %s", err) + } + s, err := NewServer(opts) + if err != nil { + t.Fatalf("Received unexpected error %s", err) + } + s.Shutdown() +} + +const operatorJwtAssertVersion_10_20_30 = ` + listen: "127.0.0.1:-1" + // Operator "TESTOP" + operator: eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJJRjNXQkFENk9JWE5HTzRWUFkzQ0hTS1ZMUDJXT0ZLQkZPR0RMUFRHSERVR0hRV1BUVlNRIiwiaWF0IjoxNTkwNTI4NTI1LCJpc3MiOiJPQ0laQUFVN0dDNkREU0QyTk1VQU9VQ0JRS09SQlNEQUxPSVBNRDRSVEM0SUhCRUZQRVE0TjZERSIsInN1YiI6Ik9DSVpBQVU3R0M2RERTRDJOTVVBT1VDQlFLT1JCU0RBTE9JUE1ENFJUQzRJSEJFRlBFUTRONkRFIiwibmF0cyI6eyJhc3NlcnRfc2VydmVyX3ZlcnNpb24iOiIxMC4yMC4zMCIsInR5cGUiOiJvcGVyYXRvciIsInZlcnNpb24iOjJ9fQ.bGFUCQIa2D5GjluEbXYJQGZnsM_O1r46b_xq2AUp4cEYGqCqvBAJZp9coBTgXL-4MPjyoPZSj2RglC1yUy9aDQ + resolver: MEMORY + resolver_preload: { + } +` + +func TestReadOperatorAssertVersionFail(t *testing.T) { + confFileName := createConfFile(t, []byte(operatorJwtAssertVersion_10_20_30)) + defer os.Remove(confFileName) + opts, err := ProcessConfigFile(confFileName) + if err != nil { + t.Fatalf("Received unexpected error %s", err) + } + s, err := NewServer(opts) + if err == nil { + s.Shutdown() + t.Fatalf("Received no error") + } else if !strings.Contains(err.Error(), "expected major version 10 > server major version") { + t.Fatal("expected different error got: ", err) + } +}