github.com/nats-io/nats-server/v2@v2.11.0-preview.2/server/opts_test.go (about)

     1  // Copyright 2012-2020 The NATS Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package server
    15  
    16  import (
    17  	"bytes"
    18  	"crypto/tls"
    19  	"encoding/json"
    20  	"flag"
    21  	"fmt"
    22  	"net/url"
    23  	"os"
    24  	"reflect"
    25  	"runtime"
    26  	"strings"
    27  	"sync"
    28  	"sync/atomic"
    29  	"testing"
    30  	"time"
    31  
    32  	"github.com/nats-io/jwt/v2"
    33  	"github.com/nats-io/nats.go"
    34  	"github.com/nats-io/nkeys"
    35  )
    36  
    37  func checkOptionsEqual(t *testing.T, golden, opts *Options) {
    38  	t.Helper()
    39  	// Clone them so we can remove private fields that we don't
    40  	// want to be compared.
    41  	goldenClone := golden.Clone()
    42  	goldenClone.inConfig, goldenClone.inCmdLine = nil, nil
    43  	optsClone := opts.Clone()
    44  	optsClone.inConfig, optsClone.inCmdLine = nil, nil
    45  	if !reflect.DeepEqual(goldenClone, optsClone) {
    46  		t.Fatalf("Options are incorrect.\nexpected: %+v\ngot: %+v", goldenClone, optsClone)
    47  	}
    48  }
    49  
    50  func TestDefaultOptions(t *testing.T) {
    51  	golden := &Options{
    52  		Host:                DEFAULT_HOST,
    53  		Port:                DEFAULT_PORT,
    54  		MaxConn:             DEFAULT_MAX_CONNECTIONS,
    55  		HTTPHost:            DEFAULT_HOST,
    56  		PingInterval:        DEFAULT_PING_INTERVAL,
    57  		MaxPingsOut:         DEFAULT_PING_MAX_OUT,
    58  		TLSTimeout:          float64(TLS_TIMEOUT) / float64(time.Second),
    59  		AuthTimeout:         float64(AUTH_TIMEOUT) / float64(time.Second),
    60  		MaxControlLine:      MAX_CONTROL_LINE_SIZE,
    61  		MaxPayload:          MAX_PAYLOAD_SIZE,
    62  		MaxPending:          MAX_PENDING_SIZE,
    63  		WriteDeadline:       DEFAULT_FLUSH_DEADLINE,
    64  		MaxClosedClients:    DEFAULT_MAX_CLOSED_CLIENTS,
    65  		LameDuckDuration:    DEFAULT_LAME_DUCK_DURATION,
    66  		LameDuckGracePeriod: DEFAULT_LAME_DUCK_GRACE_PERIOD,
    67  		LeafNode: LeafNodeOpts{
    68  			ReconnectInterval: DEFAULT_LEAF_NODE_RECONNECT,
    69  		},
    70  		ConnectErrorReports:   DEFAULT_CONNECT_ERROR_REPORTS,
    71  		ReconnectErrorReports: DEFAULT_RECONNECT_ERROR_REPORTS,
    72  		MaxTracedMsgLen:       0,
    73  		JetStreamMaxMemory:    -1,
    74  		JetStreamMaxStore:     -1,
    75  		SyncInterval:          2 * time.Minute,
    76  	}
    77  
    78  	opts := &Options{}
    79  	setBaselineOptions(opts)
    80  
    81  	checkOptionsEqual(t, golden, opts)
    82  }
    83  
    84  func TestOptions_RandomPort(t *testing.T) {
    85  	opts := &Options{Port: RANDOM_PORT}
    86  	setBaselineOptions(opts)
    87  
    88  	if opts.Port != 0 {
    89  		t.Fatalf("Process of options should have resolved random port to "+
    90  			"zero.\nexpected: %d\ngot: %d", 0, opts.Port)
    91  	}
    92  }
    93  
    94  func TestConfigFile(t *testing.T) {
    95  	golden := &Options{
    96  		ConfigFile:            "./configs/test.conf",
    97  		ServerName:            "testing_server",
    98  		Host:                  "127.0.0.1",
    99  		Port:                  4242,
   100  		Username:              "derek",
   101  		Password:              "porkchop",
   102  		AuthTimeout:           1.0,
   103  		Debug:                 false,
   104  		Trace:                 true,
   105  		Logtime:               false,
   106  		HTTPPort:              8222,
   107  		HTTPBasePath:          "/nats",
   108  		PidFile:               "/tmp/nats-server/nats-server.pid",
   109  		ProfPort:              6543,
   110  		Syslog:                true,
   111  		RemoteSyslog:          "udp://foo.com:33",
   112  		MaxControlLine:        2048,
   113  		MaxPayload:            65536,
   114  		MaxConn:               100,
   115  		MaxSubs:               1000,
   116  		MaxPending:            10000000,
   117  		PingInterval:          60 * time.Second,
   118  		MaxPingsOut:           3,
   119  		WriteDeadline:         3 * time.Second,
   120  		LameDuckDuration:      4 * time.Minute,
   121  		ConnectErrorReports:   86400,
   122  		ReconnectErrorReports: 5,
   123  		authBlockDefined:      true,
   124  	}
   125  
   126  	opts, err := ProcessConfigFile("./configs/test.conf")
   127  	if err != nil {
   128  		t.Fatalf("Received an error reading config file: %v", err)
   129  	}
   130  
   131  	checkOptionsEqual(t, golden, opts)
   132  }
   133  
   134  func TestTLSConfigFile(t *testing.T) {
   135  	golden := &Options{
   136  		ConfigFile:       "./configs/tls.conf",
   137  		Host:             "127.0.0.1",
   138  		Port:             4443,
   139  		Username:         "derek",
   140  		Password:         "foo",
   141  		AuthTimeout:      1.0,
   142  		TLSTimeout:       2.0,
   143  		authBlockDefined: true,
   144  	}
   145  	opts, err := ProcessConfigFile("./configs/tls.conf")
   146  	if err != nil {
   147  		t.Fatalf("Received an error reading config file: %v", err)
   148  	}
   149  	tlsConfig := opts.TLSConfig
   150  	if tlsConfig == nil {
   151  		t.Fatal("Expected opts.TLSConfig to be non-nil")
   152  	}
   153  	opts.TLSConfig = nil
   154  	opts.tlsConfigOpts = nil
   155  	checkOptionsEqual(t, golden, opts)
   156  
   157  	// Now check TLSConfig a bit more closely
   158  	// CipherSuites
   159  	ciphers := defaultCipherSuites()
   160  	if !reflect.DeepEqual(tlsConfig.CipherSuites, ciphers) {
   161  		t.Fatalf("Got incorrect cipher suite list: [%+v]", tlsConfig.CipherSuites)
   162  	}
   163  	if tlsConfig.MinVersion != tls.VersionTLS12 {
   164  		t.Fatalf("Expected MinVersion of 1.2 [%v], got [%v]", tls.VersionTLS12, tlsConfig.MinVersion)
   165  	}
   166  	//lint:ignore SA1019 We want to retry on a bunch of errors here.
   167  	if !tlsConfig.PreferServerCipherSuites { // nolint:staticcheck
   168  		t.Fatal("Expected PreferServerCipherSuites to be true")
   169  	}
   170  	// Verify hostname is correct in certificate
   171  	if len(tlsConfig.Certificates) != 1 {
   172  		t.Fatal("Expected 1 certificate")
   173  	}
   174  	cert := tlsConfig.Certificates[0].Leaf
   175  	if err := cert.VerifyHostname("127.0.0.1"); err != nil {
   176  		t.Fatalf("Could not verify hostname in certificate: %v", err)
   177  	}
   178  
   179  	// Now test adding cipher suites.
   180  	opts, err = ProcessConfigFile("./configs/tls_ciphers.conf")
   181  	if err != nil {
   182  		t.Fatalf("Received an error reading config file: %v", err)
   183  	}
   184  	tlsConfig = opts.TLSConfig
   185  	if tlsConfig == nil {
   186  		t.Fatal("Expected opts.TLSConfig to be non-nil")
   187  	}
   188  
   189  	// CipherSuites listed in the config - test all of them.
   190  	ciphers = []uint16{
   191  		tls.TLS_RSA_WITH_RC4_128_SHA,
   192  		tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
   193  		tls.TLS_RSA_WITH_AES_128_CBC_SHA,
   194  		tls.TLS_RSA_WITH_AES_256_CBC_SHA,
   195  		tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
   196  		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
   197  		tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
   198  		tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
   199  		tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
   200  		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
   201  		tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
   202  		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
   203  		tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
   204  	}
   205  
   206  	if !reflect.DeepEqual(tlsConfig.CipherSuites, ciphers) {
   207  		t.Fatalf("Got incorrect cipher suite list: [%+v]", tlsConfig.CipherSuites)
   208  	}
   209  
   210  	// Test an unrecognized/bad cipher
   211  	if _, err := ProcessConfigFile("./configs/tls_bad_cipher.conf"); err == nil {
   212  		t.Fatal("Did not receive an error from a unrecognized cipher")
   213  	}
   214  
   215  	// Test an empty cipher entry in a config file.
   216  	if _, err := ProcessConfigFile("./configs/tls_empty_cipher.conf"); err == nil {
   217  		t.Fatal("Did not receive an error from empty cipher_suites")
   218  	}
   219  
   220  	// Test a curve preference from the config.
   221  	curves := []tls.CurveID{
   222  		tls.CurveP256,
   223  	}
   224  
   225  	// test on a file that  will load the curve preference defaults
   226  	opts, err = ProcessConfigFile("./configs/tls_ciphers.conf")
   227  	if err != nil {
   228  		t.Fatalf("Received an error reading config file: %v", err)
   229  	}
   230  
   231  	if !reflect.DeepEqual(opts.TLSConfig.CurvePreferences, defaultCurvePreferences()) {
   232  		t.Fatalf("Got incorrect curve preference list: [%+v]", tlsConfig.CurvePreferences)
   233  	}
   234  
   235  	// Test specifying a single curve preference
   236  	opts, err = ProcessConfigFile("./configs/tls_curve_prefs.conf")
   237  	if err != nil {
   238  		t.Fatal("Did not receive an error from a unrecognized cipher.")
   239  	}
   240  
   241  	if !reflect.DeepEqual(opts.TLSConfig.CurvePreferences, curves) {
   242  		t.Fatalf("Got incorrect cipher suite list: [%+v]", tlsConfig.CurvePreferences)
   243  	}
   244  
   245  	// Test an unrecognized/bad curve preference
   246  	if _, err := ProcessConfigFile("./configs/tls_bad_curve_prefs.conf"); err == nil {
   247  		t.Fatal("Did not receive an error from a unrecognized curve preference")
   248  	}
   249  	// Test an empty curve preference
   250  	if _, err := ProcessConfigFile("./configs/tls_empty_curve_prefs.conf"); err == nil {
   251  		t.Fatal("Did not receive an error from empty curve preferences")
   252  	}
   253  }
   254  
   255  func TestMergeOverrides(t *testing.T) {
   256  	golden := &Options{
   257  		ConfigFile:     "./configs/test.conf",
   258  		ServerName:     "testing_server",
   259  		Host:           "127.0.0.1",
   260  		Port:           2222,
   261  		Username:       "derek",
   262  		Password:       "porkchop",
   263  		AuthTimeout:    1.0,
   264  		Debug:          true,
   265  		Trace:          true,
   266  		Logtime:        false,
   267  		HTTPPort:       DEFAULT_HTTP_PORT,
   268  		HTTPBasePath:   DEFAULT_HTTP_BASE_PATH,
   269  		PidFile:        "/tmp/nats-server/nats-server.pid",
   270  		ProfPort:       6789,
   271  		Syslog:         true,
   272  		RemoteSyslog:   "udp://foo.com:33",
   273  		MaxControlLine: 2048,
   274  		MaxPayload:     65536,
   275  		MaxConn:        100,
   276  		MaxSubs:        1000,
   277  		MaxPending:     10000000,
   278  		PingInterval:   60 * time.Second,
   279  		MaxPingsOut:    3,
   280  		Cluster: ClusterOpts{
   281  			NoAdvertise:    true,
   282  			ConnectRetries: 2,
   283  		},
   284  		WriteDeadline:         3 * time.Second,
   285  		LameDuckDuration:      4 * time.Minute,
   286  		ConnectErrorReports:   86400,
   287  		ReconnectErrorReports: 5,
   288  		authBlockDefined:      true,
   289  	}
   290  	fopts, err := ProcessConfigFile("./configs/test.conf")
   291  	if err != nil {
   292  		t.Fatalf("Received an error reading config file: %v", err)
   293  	}
   294  
   295  	// Overrides via flags
   296  	opts := &Options{
   297  		Port:         2222,
   298  		Password:     "porkchop",
   299  		Debug:        true,
   300  		HTTPPort:     DEFAULT_HTTP_PORT,
   301  		HTTPBasePath: DEFAULT_HTTP_BASE_PATH,
   302  		ProfPort:     6789,
   303  		Cluster: ClusterOpts{
   304  			NoAdvertise:    true,
   305  			ConnectRetries: 2,
   306  		},
   307  	}
   308  	merged := MergeOptions(fopts, opts)
   309  
   310  	checkOptionsEqual(t, golden, merged)
   311  }
   312  
   313  func TestRemoveSelfReference(t *testing.T) {
   314  	url1, _ := url.Parse("nats-route://user:password@10.4.5.6:4223")
   315  	url2, _ := url.Parse("nats-route://user:password@127.0.0.1:4223")
   316  	url3, _ := url.Parse("nats-route://user:password@127.0.0.1:4223")
   317  
   318  	routes := []*url.URL{url1, url2, url3}
   319  
   320  	newroutes, err := RemoveSelfReference(4223, routes)
   321  	if err != nil {
   322  		t.Fatalf("Error during RemoveSelfReference: %v", err)
   323  	}
   324  
   325  	if len(newroutes) != 1 {
   326  		t.Fatalf("Wrong number of routes: %d", len(newroutes))
   327  	}
   328  
   329  	if newroutes[0] != routes[0] {
   330  		t.Fatalf("Self reference IP address %s in Routes", routes[0])
   331  	}
   332  }
   333  
   334  func TestAllowRouteWithDifferentPort(t *testing.T) {
   335  	url1, _ := url.Parse("nats-route://user:password@127.0.0.1:4224")
   336  	routes := []*url.URL{url1}
   337  
   338  	newroutes, err := RemoveSelfReference(4223, routes)
   339  	if err != nil {
   340  		t.Fatalf("Error during RemoveSelfReference: %v", err)
   341  	}
   342  
   343  	if len(newroutes) != 1 {
   344  		t.Fatalf("Wrong number of routes: %d", len(newroutes))
   345  	}
   346  }
   347  
   348  func TestRouteFlagOverride(t *testing.T) {
   349  	routeFlag := "nats-route://ruser:top_secret@127.0.0.1:8246"
   350  	rurl, _ := url.Parse(routeFlag)
   351  
   352  	golden := &Options{
   353  		ConfigFile: "./configs/srv_a.conf",
   354  		Host:       "127.0.0.1",
   355  		Port:       7222,
   356  		Cluster: ClusterOpts{
   357  			Name:        "abc",
   358  			Host:        "127.0.0.1",
   359  			Port:        7244,
   360  			Username:    "ruser",
   361  			Password:    "top_secret",
   362  			AuthTimeout: 0.5,
   363  		},
   364  		Routes:    []*url.URL{rurl},
   365  		RoutesStr: routeFlag,
   366  	}
   367  
   368  	fopts, err := ProcessConfigFile("./configs/srv_a.conf")
   369  	if err != nil {
   370  		t.Fatalf("Received an error reading config file: %v", err)
   371  	}
   372  
   373  	// Overrides via flags
   374  	opts := &Options{
   375  		RoutesStr: routeFlag,
   376  	}
   377  	merged := MergeOptions(fopts, opts)
   378  
   379  	checkOptionsEqual(t, golden, merged)
   380  }
   381  
   382  func TestClusterFlagsOverride(t *testing.T) {
   383  	routeFlag := "nats-route://ruser:top_secret@127.0.0.1:7246"
   384  	rurl, _ := url.Parse(routeFlag)
   385  
   386  	// In this test, we override the cluster listen string. Note that in
   387  	// the golden options, the cluster other infos correspond to what
   388  	// is recovered from the configuration file, this explains the
   389  	// discrepency between ClusterListenStr and the rest.
   390  	// The server would then process the ClusterListenStr override and
   391  	// correctly override ClusterHost/ClustherPort/etc..
   392  	golden := &Options{
   393  		ConfigFile: "./configs/srv_a.conf",
   394  		Host:       "127.0.0.1",
   395  		Port:       7222,
   396  		Cluster: ClusterOpts{
   397  			Name:        "abc",
   398  			Host:        "127.0.0.1",
   399  			Port:        7244,
   400  			ListenStr:   "nats://127.0.0.1:8224",
   401  			Username:    "ruser",
   402  			Password:    "top_secret",
   403  			AuthTimeout: 0.5,
   404  		},
   405  		Routes: []*url.URL{rurl},
   406  	}
   407  
   408  	fopts, err := ProcessConfigFile("./configs/srv_a.conf")
   409  	if err != nil {
   410  		t.Fatalf("Received an error reading config file: %v", err)
   411  	}
   412  
   413  	// Overrides via flags
   414  	opts := &Options{
   415  		Cluster: ClusterOpts{
   416  			ListenStr: "nats://127.0.0.1:8224",
   417  		},
   418  	}
   419  	merged := MergeOptions(fopts, opts)
   420  
   421  	checkOptionsEqual(t, golden, merged)
   422  }
   423  
   424  func TestRouteFlagOverrideWithMultiple(t *testing.T) {
   425  	routeFlag := "nats-route://ruser:top_secret@127.0.0.1:8246, nats-route://ruser:top_secret@127.0.0.1:8266"
   426  	rurls := RoutesFromStr(routeFlag)
   427  
   428  	golden := &Options{
   429  		ConfigFile: "./configs/srv_a.conf",
   430  		Host:       "127.0.0.1",
   431  		Port:       7222,
   432  		Cluster: ClusterOpts{
   433  			Host:        "127.0.0.1",
   434  			Name:        "abc",
   435  			Port:        7244,
   436  			Username:    "ruser",
   437  			Password:    "top_secret",
   438  			AuthTimeout: 0.5,
   439  		},
   440  		Routes:    rurls,
   441  		RoutesStr: routeFlag,
   442  	}
   443  
   444  	fopts, err := ProcessConfigFile("./configs/srv_a.conf")
   445  	if err != nil {
   446  		t.Fatalf("Received an error reading config file: %v", err)
   447  	}
   448  
   449  	// Overrides via flags
   450  	opts := &Options{
   451  		RoutesStr: routeFlag,
   452  	}
   453  	merged := MergeOptions(fopts, opts)
   454  
   455  	checkOptionsEqual(t, golden, merged)
   456  }
   457  
   458  func TestDynamicPortOnListen(t *testing.T) {
   459  	opts, err := ProcessConfigFile("./configs/listen-1.conf")
   460  	if err != nil {
   461  		t.Fatalf("Received an error reading config file: %v", err)
   462  	}
   463  	if opts.Port != -1 {
   464  		t.Fatalf("Received incorrect port %v, expected -1", opts.Port)
   465  	}
   466  	if opts.HTTPPort != -1 {
   467  		t.Fatalf("Received incorrect monitoring port %v, expected -1", opts.HTTPPort)
   468  	}
   469  	if opts.HTTPSPort != -1 {
   470  		t.Fatalf("Received incorrect secure monitoring port %v, expected -1", opts.HTTPSPort)
   471  	}
   472  }
   473  
   474  func TestListenConfig(t *testing.T) {
   475  	opts, err := ProcessConfigFile("./configs/listen.conf")
   476  	if err != nil {
   477  		t.Fatalf("Received an error reading config file: %v", err)
   478  	}
   479  	setBaselineOptions(opts)
   480  
   481  	// Normal clients
   482  	host := "10.0.1.22"
   483  	port := 4422
   484  	monHost := "127.0.0.1"
   485  	if opts.Host != host {
   486  		t.Fatalf("Received incorrect host %q, expected %q", opts.Host, host)
   487  	}
   488  	if opts.HTTPHost != monHost {
   489  		t.Fatalf("Received incorrect host %q, expected %q", opts.HTTPHost, monHost)
   490  	}
   491  	if opts.Port != port {
   492  		t.Fatalf("Received incorrect port %v, expected %v", opts.Port, port)
   493  	}
   494  
   495  	// Clustering
   496  	clusterHost := "127.0.0.1"
   497  	clusterPort := 4244
   498  
   499  	if opts.Cluster.Host != clusterHost {
   500  		t.Fatalf("Received incorrect cluster host %q, expected %q", opts.Cluster.Host, clusterHost)
   501  	}
   502  	if opts.Cluster.Port != clusterPort {
   503  		t.Fatalf("Received incorrect cluster port %v, expected %v", opts.Cluster.Port, clusterPort)
   504  	}
   505  
   506  	// HTTP
   507  	httpHost := "127.0.0.1"
   508  	httpPort := 8422
   509  
   510  	if opts.HTTPHost != httpHost {
   511  		t.Fatalf("Received incorrect http host %q, expected %q", opts.HTTPHost, httpHost)
   512  	}
   513  	if opts.HTTPPort != httpPort {
   514  		t.Fatalf("Received incorrect http port %v, expected %v", opts.HTTPPort, httpPort)
   515  	}
   516  
   517  	// HTTPS
   518  	httpsPort := 9443
   519  	if opts.HTTPSPort != httpsPort {
   520  		t.Fatalf("Received incorrect https port %v, expected %v", opts.HTTPSPort, httpsPort)
   521  	}
   522  }
   523  
   524  func TestListenPortOnlyConfig(t *testing.T) {
   525  	opts, err := ProcessConfigFile("./configs/listen_port.conf")
   526  	if err != nil {
   527  		t.Fatalf("Received an error reading config file: %v", err)
   528  	}
   529  	setBaselineOptions(opts)
   530  
   531  	port := 8922
   532  
   533  	if opts.Host != DEFAULT_HOST {
   534  		t.Fatalf("Received incorrect host %q, expected %q", opts.Host, DEFAULT_HOST)
   535  	}
   536  	if opts.HTTPHost != DEFAULT_HOST {
   537  		t.Fatalf("Received incorrect host %q, expected %q", opts.Host, DEFAULT_HOST)
   538  	}
   539  	if opts.Port != port {
   540  		t.Fatalf("Received incorrect port %v, expected %v", opts.Port, port)
   541  	}
   542  }
   543  
   544  func TestListenPortWithColonConfig(t *testing.T) {
   545  	opts, err := ProcessConfigFile("./configs/listen_port_with_colon.conf")
   546  	if err != nil {
   547  		t.Fatalf("Received an error reading config file: %v", err)
   548  	}
   549  	setBaselineOptions(opts)
   550  
   551  	port := 8922
   552  
   553  	if opts.Host != DEFAULT_HOST {
   554  		t.Fatalf("Received incorrect host %q, expected %q", opts.Host, DEFAULT_HOST)
   555  	}
   556  	if opts.HTTPHost != DEFAULT_HOST {
   557  		t.Fatalf("Received incorrect host %q, expected %q", opts.Host, DEFAULT_HOST)
   558  	}
   559  	if opts.Port != port {
   560  		t.Fatalf("Received incorrect port %v, expected %v", opts.Port, port)
   561  	}
   562  }
   563  
   564  func TestListenMonitoringDefault(t *testing.T) {
   565  	opts := &Options{
   566  		Host: "10.0.1.22",
   567  	}
   568  	setBaselineOptions(opts)
   569  
   570  	host := "10.0.1.22"
   571  	if opts.Host != host {
   572  		t.Fatalf("Received incorrect host %q, expected %q", opts.Host, host)
   573  	}
   574  	if opts.HTTPHost != host {
   575  		t.Fatalf("Received incorrect host %q, expected %q", opts.Host, host)
   576  	}
   577  	if opts.Port != DEFAULT_PORT {
   578  		t.Fatalf("Received incorrect port %v, expected %v", opts.Port, DEFAULT_PORT)
   579  	}
   580  }
   581  
   582  func TestMultipleUsersConfig(t *testing.T) {
   583  	opts, err := ProcessConfigFile("./configs/multiple_users.conf")
   584  	if err != nil {
   585  		t.Fatalf("Received an error reading config file: %v", err)
   586  	}
   587  	setBaselineOptions(opts)
   588  }
   589  
   590  // Test highly depends on contents of the config file listed below. Any changes to that file
   591  // may very well break this test.
   592  func TestAuthorizationConfig(t *testing.T) {
   593  	opts, err := ProcessConfigFile("./configs/authorization.conf")
   594  	if err != nil {
   595  		t.Fatalf("Received an error reading config file: %v", err)
   596  	}
   597  	setBaselineOptions(opts)
   598  	lu := len(opts.Users)
   599  	if lu != 5 {
   600  		t.Fatalf("Expected 5 users, got %d", lu)
   601  	}
   602  	// Build a map
   603  	mu := make(map[string]*User)
   604  	for _, u := range opts.Users {
   605  		mu[u.Username] = u
   606  	}
   607  
   608  	// Alice
   609  	alice, ok := mu["alice"]
   610  	if !ok {
   611  		t.Fatalf("Expected to see user Alice")
   612  	}
   613  	// Check for permissions details
   614  	if alice.Permissions == nil {
   615  		t.Fatalf("Expected Alice's permissions to be non-nil")
   616  	}
   617  	if alice.Permissions.Publish == nil {
   618  		t.Fatalf("Expected Alice's publish permissions to be non-nil")
   619  	}
   620  	if len(alice.Permissions.Publish.Allow) != 1 {
   621  		t.Fatalf("Expected Alice's publish permissions to have 1 element, got %d",
   622  			len(alice.Permissions.Publish.Allow))
   623  	}
   624  	pubPerm := alice.Permissions.Publish.Allow[0]
   625  	if pubPerm != "*" {
   626  		t.Fatalf("Expected Alice's publish permissions to be '*', got %q", pubPerm)
   627  	}
   628  	if alice.Permissions.Subscribe == nil {
   629  		t.Fatalf("Expected Alice's subscribe permissions to be non-nil")
   630  	}
   631  	if len(alice.Permissions.Subscribe.Allow) != 1 {
   632  		t.Fatalf("Expected Alice's subscribe permissions to have 1 element, got %d",
   633  			len(alice.Permissions.Subscribe.Allow))
   634  	}
   635  	subPerm := alice.Permissions.Subscribe.Allow[0]
   636  	if subPerm != ">" {
   637  		t.Fatalf("Expected Alice's subscribe permissions to be '>', got %q", subPerm)
   638  	}
   639  
   640  	// Bob
   641  	bob, ok := mu["bob"]
   642  	if !ok {
   643  		t.Fatalf("Expected to see user Bob")
   644  	}
   645  	if bob.Permissions == nil {
   646  		t.Fatalf("Expected Bob's permissions to be non-nil")
   647  	}
   648  
   649  	// Susan
   650  	susan, ok := mu["susan"]
   651  	if !ok {
   652  		t.Fatalf("Expected to see user Susan")
   653  	}
   654  	if susan.Permissions == nil {
   655  		t.Fatalf("Expected Susan's permissions to be non-nil")
   656  	}
   657  	// Check susan closely since she inherited the default permissions.
   658  	if susan.Permissions == nil {
   659  		t.Fatalf("Expected Susan's permissions to be non-nil")
   660  	}
   661  	if susan.Permissions.Publish != nil {
   662  		t.Fatalf("Expected Susan's publish permissions to be nil")
   663  	}
   664  	if susan.Permissions.Subscribe == nil {
   665  		t.Fatalf("Expected Susan's subscribe permissions to be non-nil")
   666  	}
   667  	if len(susan.Permissions.Subscribe.Allow) != 1 {
   668  		t.Fatalf("Expected Susan's subscribe permissions to have 1 element, got %d",
   669  			len(susan.Permissions.Subscribe.Allow))
   670  	}
   671  	subPerm = susan.Permissions.Subscribe.Allow[0]
   672  	if subPerm != "PUBLIC.>" {
   673  		t.Fatalf("Expected Susan's subscribe permissions to be 'PUBLIC.>', got %q", subPerm)
   674  	}
   675  
   676  	// Service A
   677  	svca, ok := mu["svca"]
   678  	if !ok {
   679  		t.Fatalf("Expected to see user Service A")
   680  	}
   681  	if svca.Permissions == nil {
   682  		t.Fatalf("Expected Service A's permissions to be non-nil")
   683  	}
   684  	if svca.Permissions.Subscribe == nil {
   685  		t.Fatalf("Expected Service A's subscribe permissions to be non-nil")
   686  	}
   687  	if len(svca.Permissions.Subscribe.Allow) != 1 {
   688  		t.Fatalf("Expected Service A's subscribe permissions to have 1 element, got %d",
   689  			len(svca.Permissions.Subscribe.Allow))
   690  	}
   691  	subPerm = svca.Permissions.Subscribe.Allow[0]
   692  	if subPerm != "my.service.req" {
   693  		t.Fatalf("Expected Service A's subscribe permissions to be 'my.service.req', got %q", subPerm)
   694  	}
   695  	// We want allow_responses to essentially set deny all, or allow none in this case.
   696  	if svca.Permissions.Publish == nil {
   697  		t.Fatalf("Expected Service A's publish permissions to be non-nil")
   698  	}
   699  	if len(svca.Permissions.Publish.Allow) != 0 {
   700  		t.Fatalf("Expected Service A's publish permissions to have no elements, got %d",
   701  			len(svca.Permissions.Publish.Allow))
   702  	}
   703  	// We should have a ResponsePermission present with default values.
   704  	if svca.Permissions.Response == nil {
   705  		t.Fatalf("Expected Service A's response permissions to be non-nil")
   706  	}
   707  	if svca.Permissions.Response.MaxMsgs != DEFAULT_ALLOW_RESPONSE_MAX_MSGS {
   708  		t.Fatalf("Expected Service A's response permissions of max msgs to be %d, got %d",
   709  			DEFAULT_ALLOW_RESPONSE_MAX_MSGS, svca.Permissions.Response.MaxMsgs,
   710  		)
   711  	}
   712  	if svca.Permissions.Response.Expires != DEFAULT_ALLOW_RESPONSE_EXPIRATION {
   713  		t.Fatalf("Expected Service A's response permissions of expiration to be %v, got %v",
   714  			DEFAULT_ALLOW_RESPONSE_EXPIRATION, svca.Permissions.Response.Expires,
   715  		)
   716  	}
   717  
   718  	// Service B
   719  	svcb, ok := mu["svcb"]
   720  	if !ok {
   721  		t.Fatalf("Expected to see user Service B")
   722  	}
   723  	if svcb.Permissions == nil {
   724  		t.Fatalf("Expected Service B's permissions to be non-nil")
   725  	}
   726  	if svcb.Permissions.Subscribe == nil {
   727  		t.Fatalf("Expected Service B's subscribe permissions to be non-nil")
   728  	}
   729  	if len(svcb.Permissions.Subscribe.Allow) != 1 {
   730  		t.Fatalf("Expected Service B's subscribe permissions to have 1 element, got %d",
   731  			len(svcb.Permissions.Subscribe.Allow))
   732  	}
   733  	subPerm = svcb.Permissions.Subscribe.Allow[0]
   734  	if subPerm != "my.service.req" {
   735  		t.Fatalf("Expected Service B's subscribe permissions to be 'my.service.req', got %q", subPerm)
   736  	}
   737  	// We want allow_responses to essentially set deny all, or allow none in this case.
   738  	if svcb.Permissions.Publish == nil {
   739  		t.Fatalf("Expected Service B's publish permissions to be non-nil")
   740  	}
   741  	if len(svcb.Permissions.Publish.Allow) != 0 {
   742  		t.Fatalf("Expected Service B's publish permissions to have no elements, got %d",
   743  			len(svcb.Permissions.Publish.Allow))
   744  	}
   745  	// We should have a ResponsePermission present with default values.
   746  	if svcb.Permissions.Response == nil {
   747  		t.Fatalf("Expected Service B's response permissions to be non-nil")
   748  	}
   749  	if svcb.Permissions.Response.MaxMsgs != 10 {
   750  		t.Fatalf("Expected Service B's response permissions of max msgs to be %d, got %d",
   751  			10, svcb.Permissions.Response.MaxMsgs,
   752  		)
   753  	}
   754  	if svcb.Permissions.Response.Expires != time.Minute {
   755  		t.Fatalf("Expected Service B's response permissions of expiration to be %v, got %v",
   756  			time.Minute, svcb.Permissions.Response.Expires,
   757  		)
   758  	}
   759  }
   760  
   761  // Test highly depends on contents of the config file listed below. Any changes to that file
   762  // may very well break this test.
   763  func TestNewStyleAuthorizationConfig(t *testing.T) {
   764  	opts, err := ProcessConfigFile("./configs/new_style_authorization.conf")
   765  	if err != nil {
   766  		t.Fatalf("Received an error reading config file: %v", err)
   767  	}
   768  	setBaselineOptions(opts)
   769  
   770  	lu := len(opts.Users)
   771  	if lu != 2 {
   772  		t.Fatalf("Expected 2 users, got %d", lu)
   773  	}
   774  	// Build a map
   775  	mu := make(map[string]*User)
   776  	for _, u := range opts.Users {
   777  		mu[u.Username] = u
   778  	}
   779  	// Alice
   780  	alice, ok := mu["alice"]
   781  	if !ok {
   782  		t.Fatalf("Expected to see user Alice")
   783  	}
   784  	if alice.Permissions == nil {
   785  		t.Fatalf("Expected Alice's permissions to be non-nil")
   786  	}
   787  
   788  	if alice.Permissions.Publish == nil {
   789  		t.Fatalf("Expected Alice's publish permissions to be non-nil")
   790  	}
   791  	if len(alice.Permissions.Publish.Allow) != 3 {
   792  		t.Fatalf("Expected Alice's allowed publish permissions to have 3 elements, got %d",
   793  			len(alice.Permissions.Publish.Allow))
   794  	}
   795  	pubPerm := alice.Permissions.Publish.Allow[0]
   796  	if pubPerm != "foo" {
   797  		t.Fatalf("Expected Alice's first allowed publish permission to be 'foo', got %q", pubPerm)
   798  	}
   799  	pubPerm = alice.Permissions.Publish.Allow[1]
   800  	if pubPerm != "bar" {
   801  		t.Fatalf("Expected Alice's second allowed publish permission to be 'bar', got %q", pubPerm)
   802  	}
   803  	pubPerm = alice.Permissions.Publish.Allow[2]
   804  	if pubPerm != "baz" {
   805  		t.Fatalf("Expected Alice's third allowed publish permission to be 'baz', got %q", pubPerm)
   806  	}
   807  	if len(alice.Permissions.Publish.Deny) != 0 {
   808  		t.Fatalf("Expected Alice's denied publish permissions to have 0 elements, got %d",
   809  			len(alice.Permissions.Publish.Deny))
   810  	}
   811  
   812  	if alice.Permissions.Subscribe == nil {
   813  		t.Fatalf("Expected Alice's subscribe permissions to be non-nil")
   814  	}
   815  	if len(alice.Permissions.Subscribe.Allow) != 0 {
   816  		t.Fatalf("Expected Alice's allowed subscribe permissions to have 0 elements, got %d",
   817  			len(alice.Permissions.Subscribe.Allow))
   818  	}
   819  	if len(alice.Permissions.Subscribe.Deny) != 1 {
   820  		t.Fatalf("Expected Alice's denied subscribe permissions to have 1 element, got %d",
   821  			len(alice.Permissions.Subscribe.Deny))
   822  	}
   823  	subPerm := alice.Permissions.Subscribe.Deny[0]
   824  	if subPerm != "$SYS.>" {
   825  		t.Fatalf("Expected Alice's only denied subscribe permission to be '$SYS.>', got %q", subPerm)
   826  	}
   827  
   828  	// Bob
   829  	bob, ok := mu["bob"]
   830  	if !ok {
   831  		t.Fatalf("Expected to see user Bob")
   832  	}
   833  	if bob.Permissions == nil {
   834  		t.Fatalf("Expected Bob's permissions to be non-nil")
   835  	}
   836  
   837  	if bob.Permissions.Publish == nil {
   838  		t.Fatalf("Expected Bobs's publish permissions to be non-nil")
   839  	}
   840  	if len(bob.Permissions.Publish.Allow) != 1 {
   841  		t.Fatalf("Expected Bob's allowed publish permissions to have 1 element, got %d",
   842  			len(bob.Permissions.Publish.Allow))
   843  	}
   844  	pubPerm = bob.Permissions.Publish.Allow[0]
   845  	if pubPerm != "$SYS.>" {
   846  		t.Fatalf("Expected Bob's first allowed publish permission to be '$SYS.>', got %q", pubPerm)
   847  	}
   848  	if len(bob.Permissions.Publish.Deny) != 0 {
   849  		t.Fatalf("Expected Bob's denied publish permissions to have 0 elements, got %d",
   850  			len(bob.Permissions.Publish.Deny))
   851  	}
   852  
   853  	if bob.Permissions.Subscribe == nil {
   854  		t.Fatalf("Expected Bob's subscribe permissions to be non-nil")
   855  	}
   856  	if len(bob.Permissions.Subscribe.Allow) != 0 {
   857  		t.Fatalf("Expected Bob's allowed subscribe permissions to have 0 elements, got %d",
   858  			len(bob.Permissions.Subscribe.Allow))
   859  	}
   860  	if len(bob.Permissions.Subscribe.Deny) != 3 {
   861  		t.Fatalf("Expected Bobs's denied subscribe permissions to have 3 elements, got %d",
   862  			len(bob.Permissions.Subscribe.Deny))
   863  	}
   864  	subPerm = bob.Permissions.Subscribe.Deny[0]
   865  	if subPerm != "foo" {
   866  		t.Fatalf("Expected Bobs's first denied subscribe permission to be 'foo', got %q", subPerm)
   867  	}
   868  	subPerm = bob.Permissions.Subscribe.Deny[1]
   869  	if subPerm != "bar" {
   870  		t.Fatalf("Expected Bobs's second denied subscribe permission to be 'bar', got %q", subPerm)
   871  	}
   872  	subPerm = bob.Permissions.Subscribe.Deny[2]
   873  	if subPerm != "baz" {
   874  		t.Fatalf("Expected Bobs's third denied subscribe permission to be 'baz', got %q", subPerm)
   875  	}
   876  }
   877  
   878  // Test new nkey users
   879  func TestNkeyUsersConfig(t *testing.T) {
   880  	confFileName := createConfFile(t, []byte(`
   881      authorization {
   882        users = [
   883          {nkey: "UDKTV7HZVYJFJN64LLMYQBUR6MTNNYCDC3LAZH4VHURW3GZLL3FULBXV"}
   884          {nkey: "UA3C5TBZYK5GJQJRWPMU6NFY5JNAEVQB2V2TUZFZDHFJFUYVKTTUOFKZ"}
   885        ]
   886      }`))
   887  	opts, err := ProcessConfigFile(confFileName)
   888  	if err != nil {
   889  		t.Fatalf("Received an error reading config file: %v", err)
   890  	}
   891  	lu := len(opts.Nkeys)
   892  	if lu != 2 {
   893  		t.Fatalf("Expected 2 nkey users, got %d", lu)
   894  	}
   895  }
   896  
   897  // Test pinned certificates
   898  func TestTlsPinnedCertificates(t *testing.T) {
   899  	confFileName := createConfFile(t, []byte(`
   900  	tls {
   901  		cert_file: "./configs/certs/server.pem"
   902  		key_file: "./configs/certs/key.pem"
   903  		# Require a client certificate and map user id from certificate
   904  		verify: true
   905  		pinned_certs: ["7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069",
   906  			"a8f407340dcc719864214b85ed96f98d16cbffa8f509d9fa4ca237b7bb3f9c32"]
   907  	}
   908  	cluster {
   909  		port -1
   910  		name cluster-hub
   911  		tls {
   912  			cert_file: "./configs/certs/server.pem"
   913  			key_file: "./configs/certs/key.pem"
   914  			# Require a client certificate and map user id from certificate
   915  			verify: true
   916  			pinned_certs: ["7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069",
   917  				"a8f407340dcc719864214b85ed96f98d16cbffa8f509d9fa4ca237b7bb3f9c32"]
   918  		}
   919  	}
   920  	leafnodes {
   921  		port -1
   922  		tls {
   923  			cert_file: "./configs/certs/server.pem"
   924  			key_file: "./configs/certs/key.pem"
   925  			# Require a client certificate and map user id from certificate
   926  			verify: true
   927  			pinned_certs: ["7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069",
   928  				"a8f407340dcc719864214b85ed96f98d16cbffa8f509d9fa4ca237b7bb3f9c32"]
   929  		}
   930  	}
   931  	gateway {
   932  		name: "A"
   933  		port -1
   934  		tls {
   935  			cert_file: "./configs/certs/server.pem"
   936  			key_file: "./configs/certs/key.pem"
   937  			# Require a client certificate and map user id from certificate
   938  			verify: true
   939  			pinned_certs: ["7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069",
   940  				"a8f407340dcc719864214b85ed96f98d16cbffa8f509d9fa4ca237b7bb3f9c32"]
   941  		}
   942  	}
   943  	websocket {
   944  		port -1
   945  		tls {
   946  			cert_file: "./configs/certs/server.pem"
   947  			key_file: "./configs/certs/key.pem"
   948  			# Require a client certificate and map user id from certificate
   949  			verify: true
   950  			pinned_certs: ["7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069",
   951  				"a8f407340dcc719864214b85ed96f98d16cbffa8f509d9fa4ca237b7bb3f9c32"]
   952  		}
   953  	}
   954  	mqtt {
   955  		port -1
   956  		tls {
   957  			cert_file: "./configs/certs/server.pem"
   958  			key_file: "./configs/certs/key.pem"
   959  			# Require a client certificate and map user id from certificate
   960  			verify: true
   961  			pinned_certs: ["7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069",
   962  				"a8f407340dcc719864214b85ed96f98d16cbffa8f509d9fa4ca237b7bb3f9c32"]
   963  		}
   964  	}`))
   965  	opts, err := ProcessConfigFile(confFileName)
   966  	if err != nil {
   967  		t.Fatalf("Received an error reading config file: %v", err)
   968  	}
   969  	check := func(set PinnedCertSet) {
   970  		t.Helper()
   971  		if l := len(set); l != 2 {
   972  			t.Fatalf("Expected 2 pinned certificates, got got %d", l)
   973  		}
   974  	}
   975  
   976  	check(opts.TLSPinnedCerts)
   977  	check(opts.LeafNode.TLSPinnedCerts)
   978  	check(opts.Cluster.TLSPinnedCerts)
   979  	check(opts.MQTT.TLSPinnedCerts)
   980  	check(opts.Gateway.TLSPinnedCerts)
   981  	check(opts.Websocket.TLSPinnedCerts)
   982  }
   983  
   984  func TestNkeyUsersDefaultPermissionsConfig(t *testing.T) {
   985  	confFileName := createConfFile(t, []byte(`
   986  	authorization {
   987  		default_permissions = {
   988  			publish = "foo"
   989  		}
   990  		users = [
   991  			{ user: "user", password: "pwd"}
   992  			{ user: "other", password: "pwd",
   993  				permissions = {
   994  					subscribe = "bar"
   995  				}
   996  			}
   997  			{ nkey: "UDKTV7HZVYJFJN64LLMYQBUR6MTNNYCDC3LAZH4VHURW3GZLL3FULBXV" }
   998  			{ nkey: "UA3C5TBZYK5GJQJRWPMU6NFY5JNAEVQB2V2TUZFZDHFJFUYVKTTUOFKZ",
   999  				permissions = {
  1000  					subscribe = "bar"
  1001  				}
  1002  			}
  1003  		]
  1004  	}
  1005  	accounts {
  1006  		A {
  1007  			default_permissions = {
  1008  				publish = "foo"
  1009  			}
  1010  			users = [
  1011  				{ user: "accuser", password: "pwd"}
  1012  				{ user: "accother", password: "pwd",
  1013  					permissions = {
  1014  						subscribe = "bar"
  1015  					}
  1016  				}
  1017  				{ nkey: "UC4YEYJHYKTU4LHROX7UEKEIO5RP5OUWDYXELHWXZOQHZYXHUD44LCRS" }
  1018  				{ nkey: "UDLSDF4UY3YW7JJQCYE6T2D4KFDCH6RGF3R65KHK247G3POJPI27VMQ3",
  1019  					permissions = {
  1020  						subscribe = "bar"
  1021  					}
  1022  				}
  1023  			]
  1024  		}
  1025  	}
  1026  	`))
  1027  	checkPerms := func(permsDef *Permissions, permsNonDef *Permissions) {
  1028  		if permsDef.Publish.Allow[0] != "foo" {
  1029  			t.Fatal("Publish allow foo missing")
  1030  		} else if permsDef.Subscribe != nil {
  1031  			t.Fatal("Has unexpected Subscribe permission")
  1032  		} else if permsNonDef.Subscribe.Allow[0] != "bar" {
  1033  			t.Fatal("Subscribe allow bar missing")
  1034  		} else if permsNonDef.Publish != nil {
  1035  			t.Fatal("Has unexpected Publish permission")
  1036  		}
  1037  	}
  1038  	opts, err := ProcessConfigFile(confFileName)
  1039  	if err != nil {
  1040  		t.Fatalf("Received an error reading config file: %v", err)
  1041  	}
  1042  
  1043  	findUsers := func(u1, u2 string) (found []*User) {
  1044  		find := []string{u1, u2}
  1045  		for _, f := range find {
  1046  			for _, u := range opts.Users {
  1047  				if u.Username == f {
  1048  					found = append(found, u)
  1049  					break
  1050  				}
  1051  			}
  1052  		}
  1053  		return
  1054  	}
  1055  
  1056  	findNkeyUsers := func(nk1, nk2 string) (found []*NkeyUser) {
  1057  		find := []string{nk1, nk2}
  1058  		for _, f := range find {
  1059  			for _, u := range opts.Nkeys {
  1060  				if strings.HasPrefix(u.Nkey, f) {
  1061  					found = append(found, u)
  1062  					break
  1063  				}
  1064  			}
  1065  		}
  1066  		return
  1067  	}
  1068  
  1069  	if lu := len(opts.Users); lu != 4 {
  1070  		t.Fatalf("Expected 4 nkey users, got %d", lu)
  1071  	}
  1072  	foundU := findUsers("user", "other")
  1073  	checkPerms(foundU[0].Permissions, foundU[1].Permissions)
  1074  	foundU = findUsers("accuser", "accother")
  1075  	checkPerms(foundU[0].Permissions, foundU[1].Permissions)
  1076  
  1077  	if lu := len(opts.Nkeys); lu != 4 {
  1078  		t.Fatalf("Expected 4 nkey users, got %d", lu)
  1079  	}
  1080  	foundNk := findNkeyUsers("UDK", "UA3")
  1081  	checkPerms(foundNk[0].Permissions, foundNk[1].Permissions)
  1082  	foundNk = findNkeyUsers("UC4", "UDL")
  1083  	checkPerms(foundNk[0].Permissions, foundNk[1].Permissions)
  1084  }
  1085  
  1086  func TestNkeyUsersWithPermsConfig(t *testing.T) {
  1087  	confFileName := createConfFile(t, []byte(`
  1088      authorization {
  1089        users = [
  1090          {nkey: "UDKTV7HZVYJFJN64LLMYQBUR6MTNNYCDC3LAZH4VHURW3GZLL3FULBXV",
  1091           permissions = {
  1092             publish = "$SYS.>"
  1093             subscribe = { deny = ["foo", "bar", "baz"] }
  1094           }
  1095          }
  1096        ]
  1097      }`))
  1098  	opts, err := ProcessConfigFile(confFileName)
  1099  	if err != nil {
  1100  		t.Fatalf("Received an error reading config file: %v", err)
  1101  	}
  1102  	lu := len(opts.Nkeys)
  1103  	if lu != 1 {
  1104  		t.Fatalf("Expected 1 nkey user, got %d", lu)
  1105  	}
  1106  	nk := opts.Nkeys[0]
  1107  	if nk.Permissions == nil {
  1108  		t.Fatal("Expected to have permissions")
  1109  	}
  1110  	if nk.Permissions.Publish == nil {
  1111  		t.Fatal("Expected to have publish permissions")
  1112  	}
  1113  	if nk.Permissions.Publish.Allow[0] != "$SYS.>" {
  1114  		t.Fatalf("Expected publish to allow \"$SYS.>\", but got %v", nk.Permissions.Publish.Allow[0])
  1115  	}
  1116  	if nk.Permissions.Subscribe == nil {
  1117  		t.Fatal("Expected to have subscribe permissions")
  1118  	}
  1119  	if nk.Permissions.Subscribe.Allow != nil {
  1120  		t.Fatal("Expected to have no subscribe allow permissions")
  1121  	}
  1122  	deny := nk.Permissions.Subscribe.Deny
  1123  	if deny == nil || len(deny) != 3 ||
  1124  		deny[0] != "foo" || deny[1] != "bar" || deny[2] != "baz" {
  1125  		t.Fatalf("Expected to have subscribe deny permissions, got %v", deny)
  1126  	}
  1127  }
  1128  
  1129  func TestBadNkeyConfig(t *testing.T) {
  1130  	confFileName := "nkeys_bad.conf"
  1131  	content := `
  1132      authorization {
  1133        users = [ {nkey: "Ufoo"}]
  1134      }`
  1135  	if err := os.WriteFile(confFileName, []byte(content), 0666); err != nil {
  1136  		t.Fatalf("Error writing config file: %v", err)
  1137  	}
  1138  	defer removeFile(t, confFileName)
  1139  	if _, err := ProcessConfigFile(confFileName); err == nil {
  1140  		t.Fatalf("Expected an error from nkey entry with password")
  1141  	}
  1142  }
  1143  
  1144  func TestNkeyWithPassConfig(t *testing.T) {
  1145  	confFileName := "nkeys_pass.conf"
  1146  	content := `
  1147      authorization {
  1148        users = [
  1149          {nkey: "UDKTV7HZVYJFJN64LLMYQBUR6MTNNYCDC3LAZH4VHURW3GZLL3FULBXV", pass: "foo"}
  1150        ]
  1151      }`
  1152  	if err := os.WriteFile(confFileName, []byte(content), 0666); err != nil {
  1153  		t.Fatalf("Error writing config file: %v", err)
  1154  	}
  1155  	defer removeFile(t, confFileName)
  1156  	if _, err := ProcessConfigFile(confFileName); err == nil {
  1157  		t.Fatalf("Expected an error from bad nkey entry")
  1158  	}
  1159  }
  1160  
  1161  func TestTokenWithUserPass(t *testing.T) {
  1162  	confFileName := "test.conf"
  1163  	content := `
  1164  	authorization={
  1165  		user: user
  1166  		pass: password
  1167  		token: $2a$11$whatever
  1168  	}`
  1169  	if err := os.WriteFile(confFileName, []byte(content), 0666); err != nil {
  1170  		t.Fatalf("Error writing config file: %v", err)
  1171  	}
  1172  	defer removeFile(t, confFileName)
  1173  	_, err := ProcessConfigFile(confFileName)
  1174  	if err == nil {
  1175  		t.Fatal("Expected error, got none")
  1176  	}
  1177  	if !strings.Contains(err.Error(), "token") {
  1178  		t.Fatalf("Expected error related to token, got %v", err)
  1179  	}
  1180  }
  1181  
  1182  func TestTokenWithUsers(t *testing.T) {
  1183  	confFileName := "test.conf"
  1184  	content := `
  1185  	authorization={
  1186  		token: $2a$11$whatever
  1187  		users: [
  1188  			{user: test, password: test}
  1189  		]
  1190  	}`
  1191  	if err := os.WriteFile(confFileName, []byte(content), 0666); err != nil {
  1192  		t.Fatalf("Error writing config file: %v", err)
  1193  	}
  1194  	defer removeFile(t, confFileName)
  1195  	_, err := ProcessConfigFile(confFileName)
  1196  	if err == nil {
  1197  		t.Fatal("Expected error, got none")
  1198  	}
  1199  	if !strings.Contains(err.Error(), "token") {
  1200  		t.Fatalf("Expected error related to token, got %v", err)
  1201  	}
  1202  }
  1203  
  1204  func TestParseWriteDeadline(t *testing.T) {
  1205  	confFile := createConfFile(t, []byte("write_deadline: \"1x\""))
  1206  	_, err := ProcessConfigFile(confFile)
  1207  	if err == nil {
  1208  		t.Fatal("Expected error, got none")
  1209  	}
  1210  	if !strings.Contains(err.Error(), "parsing") {
  1211  		t.Fatalf("Expected error related to parsing, got %v", err)
  1212  	}
  1213  	confFile = createConfFile(t, []byte("write_deadline: \"1s\""))
  1214  	opts, err := ProcessConfigFile(confFile)
  1215  	if err != nil {
  1216  		t.Fatalf("Unexpected error: %v", err)
  1217  	}
  1218  	if opts.WriteDeadline != time.Second {
  1219  		t.Fatalf("Expected write_deadline to be 1s, got %v", opts.WriteDeadline)
  1220  	}
  1221  	oldStdout := os.Stdout
  1222  	_, w, _ := os.Pipe()
  1223  	defer func() {
  1224  		w.Close()
  1225  		os.Stdout = oldStdout
  1226  	}()
  1227  	os.Stdout = w
  1228  	confFile = createConfFile(t, []byte("write_deadline: 2"))
  1229  	opts, err = ProcessConfigFile(confFile)
  1230  	if err != nil {
  1231  		t.Fatalf("Unexpected error: %v", err)
  1232  	}
  1233  	if opts.WriteDeadline != 2*time.Second {
  1234  		t.Fatalf("Expected write_deadline to be 2s, got %v", opts.WriteDeadline)
  1235  	}
  1236  }
  1237  
  1238  func TestOptionsClone(t *testing.T) {
  1239  	opts := &Options{
  1240  		ConfigFile:     "./configs/test.conf",
  1241  		Host:           "127.0.0.1",
  1242  		Port:           2222,
  1243  		Username:       "derek",
  1244  		Password:       "porkchop",
  1245  		AuthTimeout:    1.0,
  1246  		Debug:          true,
  1247  		Trace:          true,
  1248  		Logtime:        false,
  1249  		HTTPPort:       DEFAULT_HTTP_PORT,
  1250  		HTTPBasePath:   DEFAULT_HTTP_BASE_PATH,
  1251  		PidFile:        "/tmp/nats-server/nats-server.pid",
  1252  		ProfPort:       6789,
  1253  		Syslog:         true,
  1254  		RemoteSyslog:   "udp://foo.com:33",
  1255  		MaxControlLine: 2048,
  1256  		MaxPayload:     65536,
  1257  		MaxConn:        100,
  1258  		PingInterval:   60 * time.Second,
  1259  		MaxPingsOut:    3,
  1260  		Cluster: ClusterOpts{
  1261  			NoAdvertise:    true,
  1262  			ConnectRetries: 2,
  1263  		},
  1264  		Gateway: GatewayOpts{
  1265  			Name: "A",
  1266  			Gateways: []*RemoteGatewayOpts{
  1267  				{Name: "B", URLs: []*url.URL{{Scheme: "nats", Host: "host:5222"}}},
  1268  				{Name: "C"},
  1269  			},
  1270  		},
  1271  		WriteDeadline: 3 * time.Second,
  1272  		Routes:        []*url.URL{{}},
  1273  		Users:         []*User{{Username: "foo", Password: "bar"}},
  1274  	}
  1275  
  1276  	clone := opts.Clone()
  1277  
  1278  	if !reflect.DeepEqual(opts, clone) {
  1279  		t.Fatalf("Cloned Options are incorrect.\nexpected: %+v\ngot: %+v",
  1280  			clone, opts)
  1281  	}
  1282  
  1283  	clone.Users[0].Password = "baz"
  1284  	if reflect.DeepEqual(opts, clone) {
  1285  		t.Fatal("Expected Options to be different")
  1286  	}
  1287  
  1288  	opts.Gateway.Gateways[0].URLs[0] = nil
  1289  	if reflect.DeepEqual(opts.Gateway.Gateways[0], clone.Gateway.Gateways[0]) {
  1290  		t.Fatal("Expected Options to be different")
  1291  	}
  1292  	if clone.Gateway.Gateways[0].URLs[0].Host != "host:5222" {
  1293  		t.Fatalf("Unexpected URL: %v", clone.Gateway.Gateways[0].URLs[0])
  1294  	}
  1295  }
  1296  
  1297  func TestOptionsCloneNilLists(t *testing.T) {
  1298  	opts := &Options{}
  1299  
  1300  	clone := opts.Clone()
  1301  
  1302  	if clone.Routes != nil {
  1303  		t.Fatalf("Expected Routes to be nil, got: %v", clone.Routes)
  1304  	}
  1305  	if clone.Users != nil {
  1306  		t.Fatalf("Expected Users to be nil, got: %v", clone.Users)
  1307  	}
  1308  }
  1309  
  1310  func TestOptionsCloneNil(t *testing.T) {
  1311  	opts := (*Options)(nil)
  1312  	clone := opts.Clone()
  1313  	if clone != nil {
  1314  		t.Fatalf("Expected nil, got: %+v", clone)
  1315  	}
  1316  }
  1317  
  1318  func TestEmptyConfig(t *testing.T) {
  1319  	opts, err := ProcessConfigFile("")
  1320  
  1321  	if err != nil {
  1322  		t.Fatalf("Expected no error from empty config, got: %+v", err)
  1323  	}
  1324  
  1325  	if opts.ConfigFile != "" {
  1326  		t.Fatalf("Expected empty config, got: %+v", opts)
  1327  	}
  1328  }
  1329  
  1330  func TestMalformedListenAddress(t *testing.T) {
  1331  	opts, err := ProcessConfigFile("./configs/malformed_listen_address.conf")
  1332  	if err == nil {
  1333  		t.Fatalf("Expected an error reading config file: got %+v", opts)
  1334  	}
  1335  }
  1336  
  1337  func TestMalformedClusterAddress(t *testing.T) {
  1338  	opts, err := ProcessConfigFile("./configs/malformed_cluster_address.conf")
  1339  	if err == nil {
  1340  		t.Fatalf("Expected an error reading config file: got %+v", opts)
  1341  	}
  1342  }
  1343  
  1344  func TestPanic(t *testing.T) {
  1345  	conf := createConfFile(t, []byte(`port: "this_string_trips_a_panic"`))
  1346  	opts, err := ProcessConfigFile(conf)
  1347  	if err == nil {
  1348  		t.Fatalf("Expected an error reading config file: got %+v", opts)
  1349  	} else {
  1350  		if !strings.Contains(err.Error(), ":1:0: interface conversion:") {
  1351  			t.Fatalf("This was supposed to trip a panic on interface conversion right at the beginning")
  1352  		}
  1353  	}
  1354  }
  1355  
  1356  func TestPingIntervalOld(t *testing.T) {
  1357  	conf := createConfFile(t, []byte(`ping_interval: 5`))
  1358  	opts := &Options{}
  1359  	err := opts.ProcessConfigFile(conf)
  1360  	if err == nil {
  1361  		t.Fatalf("expected an error")
  1362  	}
  1363  	errTyped, ok := err.(*processConfigErr)
  1364  	if !ok {
  1365  		t.Fatalf("expected an error of type processConfigErr")
  1366  	}
  1367  	if len(errTyped.warnings) != 1 {
  1368  		t.Fatalf("expected processConfigErr to have one warning")
  1369  	}
  1370  	if len(errTyped.errors) != 0 {
  1371  		t.Fatalf("expected processConfigErr to have no error")
  1372  	}
  1373  	if opts.PingInterval != 5*time.Second {
  1374  		t.Fatalf("expected ping interval to be 5 seconds")
  1375  	}
  1376  }
  1377  
  1378  func TestPingIntervalNew(t *testing.T) {
  1379  	conf := createConfFile(t, []byte(`ping_interval: "5m"`))
  1380  	opts := &Options{}
  1381  	if err := opts.ProcessConfigFile(conf); err != nil {
  1382  		t.Fatalf("expected no error")
  1383  	}
  1384  	if opts.PingInterval != 5*time.Minute {
  1385  		t.Fatalf("expected ping interval to be 5 minutes")
  1386  	}
  1387  }
  1388  
  1389  func TestOptionsProcessConfigFile(t *testing.T) {
  1390  	// Create options with default values of Debug and Trace
  1391  	// that are the opposite of what is in the config file.
  1392  	// Set another option that is not present in the config file.
  1393  	logFileName := "test.log"
  1394  	opts := &Options{
  1395  		Debug:   true,
  1396  		Trace:   false,
  1397  		LogFile: logFileName,
  1398  	}
  1399  	configFileName := "./configs/test.conf"
  1400  	if err := opts.ProcessConfigFile(configFileName); err != nil {
  1401  		t.Fatalf("Error processing config file: %v", err)
  1402  	}
  1403  	// Verify that values are as expected
  1404  	if opts.ConfigFile != configFileName {
  1405  		t.Fatalf("Expected ConfigFile to be set to %q, got %v", configFileName, opts.ConfigFile)
  1406  	}
  1407  	if opts.Debug {
  1408  		t.Fatal("Debug option should have been set to false from config file")
  1409  	}
  1410  	if !opts.Trace {
  1411  		t.Fatal("Trace option should have been set to true from config file")
  1412  	}
  1413  	if opts.LogFile != logFileName {
  1414  		t.Fatalf("Expected LogFile to be %q, got %q", logFileName, opts.LogFile)
  1415  	}
  1416  }
  1417  
  1418  func TestConfigureOptions(t *testing.T) {
  1419  	// Options.Configure() will snapshot the flags. This is used by the reload code.
  1420  	// We need to set it back to nil otherwise it will impact reload tests.
  1421  	defer func() { FlagSnapshot = nil }()
  1422  
  1423  	ch := make(chan bool, 1)
  1424  	checkPrintInvoked := func() {
  1425  		ch <- true
  1426  	}
  1427  	usage := func() { panic("should not get there") }
  1428  	var fs *flag.FlagSet
  1429  	type testPrint struct {
  1430  		args                   []string
  1431  		version, help, tlsHelp func()
  1432  	}
  1433  	testFuncs := []testPrint{
  1434  		{[]string{"-v"}, checkPrintInvoked, usage, PrintTLSHelpAndDie},
  1435  		{[]string{"version"}, checkPrintInvoked, usage, PrintTLSHelpAndDie},
  1436  		{[]string{"-h"}, PrintServerAndExit, checkPrintInvoked, PrintTLSHelpAndDie},
  1437  		{[]string{"help"}, PrintServerAndExit, checkPrintInvoked, PrintTLSHelpAndDie},
  1438  		{[]string{"-help_tls"}, PrintServerAndExit, usage, checkPrintInvoked},
  1439  	}
  1440  	for _, tf := range testFuncs {
  1441  		fs = flag.NewFlagSet("test", flag.ContinueOnError)
  1442  		opts, err := ConfigureOptions(fs, tf.args, tf.version, tf.help, tf.tlsHelp)
  1443  		if err != nil {
  1444  			t.Fatalf("Error on configure: %v", err)
  1445  		}
  1446  		if opts != nil {
  1447  			t.Fatalf("Expected options to be nil, got %v", opts)
  1448  		}
  1449  		select {
  1450  		case <-ch:
  1451  		case <-time.After(time.Second):
  1452  			t.Fatalf("Should have invoked print function for args=%v", tf.args)
  1453  		}
  1454  	}
  1455  
  1456  	// Helper function that expect parsing with given args to not produce an error.
  1457  	mustNotFail := func(args []string) *Options {
  1458  		fs := flag.NewFlagSet("test", flag.ContinueOnError)
  1459  		opts, err := ConfigureOptions(fs, args, PrintServerAndExit, fs.Usage, PrintTLSHelpAndDie)
  1460  		if err != nil {
  1461  			stackFatalf(t, "Error on configure: %v", err)
  1462  		}
  1463  		return opts
  1464  	}
  1465  
  1466  	// Helper function that expect configuration to fail.
  1467  	expectToFail := func(args []string, errContent ...string) {
  1468  		fs := flag.NewFlagSet("test", flag.ContinueOnError)
  1469  		// Silence the flagSet so that on failure nothing is printed.
  1470  		// (flagSet would print error message about unknown flags, etc..)
  1471  		silenceOuput := &bytes.Buffer{}
  1472  		fs.SetOutput(silenceOuput)
  1473  		opts, err := ConfigureOptions(fs, args, PrintServerAndExit, fs.Usage, PrintTLSHelpAndDie)
  1474  		if opts != nil || err == nil {
  1475  			stackFatalf(t, "Expected no option and an error, got opts=%v and err=%v", opts, err)
  1476  		}
  1477  		for _, testErr := range errContent {
  1478  			if strings.Contains(err.Error(), testErr) {
  1479  				// We got the error we wanted.
  1480  				return
  1481  			}
  1482  		}
  1483  		stackFatalf(t, "Expected errors containing any of those %v, got %v", errContent, err)
  1484  	}
  1485  
  1486  	// Basic test with port number
  1487  	opts := mustNotFail([]string{"-p", "1234"})
  1488  	if opts.Port != 1234 {
  1489  		t.Fatalf("Expected port to be 1234, got %v", opts.Port)
  1490  	}
  1491  
  1492  	// Should fail because of unknown parameter
  1493  	expectToFail([]string{"foo"}, "command")
  1494  
  1495  	// Should fail because unknown flag
  1496  	expectToFail([]string{"-xxx", "foo"}, "flag")
  1497  
  1498  	// Should fail because of config file missing
  1499  	expectToFail([]string{"-c", "xxx.cfg"}, "file")
  1500  
  1501  	// Should fail because of too many args for signal command
  1502  	expectToFail([]string{"-sl", "quit=pid=foo"}, "signal")
  1503  
  1504  	// Should fail because of invalid pid
  1505  	// On windows, if not running with admin privileges, you would get access denied.
  1506  	expectToFail([]string{"-sl", "quit=pid"}, "pid", "denied")
  1507  
  1508  	// The config file set Trace to true.
  1509  	opts = mustNotFail([]string{"-c", "./configs/test.conf"})
  1510  	if !opts.Trace {
  1511  		t.Fatal("Trace should have been set to true")
  1512  	}
  1513  
  1514  	// The config file set Trace to true, but was overridden by param -V=false
  1515  	opts = mustNotFail([]string{"-c", "./configs/test.conf", "-V=false"})
  1516  	if opts.Trace {
  1517  		t.Fatal("Trace should have been set to false")
  1518  	}
  1519  
  1520  	// The config file set Trace to true, but was overridden by param -DV=false
  1521  	opts = mustNotFail([]string{"-c", "./configs/test.conf", "-DV=false"})
  1522  	if opts.Debug || opts.Trace {
  1523  		t.Fatal("Debug and Trace should have been set to false")
  1524  	}
  1525  
  1526  	// The config file set Trace to true, but was overridden by param -DV
  1527  	opts = mustNotFail([]string{"-c", "./configs/test.conf", "-DV"})
  1528  	if !opts.Debug || !opts.Trace {
  1529  		t.Fatal("Debug and Trace should have been set to true")
  1530  	}
  1531  
  1532  	// This should fail since -cluster is missing
  1533  	expectedURL, _ := url.Parse("nats://127.0.0.1:6223")
  1534  	expectToFail([]string{"-routes", expectedURL.String()}, "solicited routes")
  1535  
  1536  	// Ensure that we can set cluster and routes from command line
  1537  	opts = mustNotFail([]string{"-cluster", "nats://127.0.0.1:6222", "-routes", expectedURL.String()})
  1538  	if opts.Cluster.ListenStr != "nats://127.0.0.1:6222" {
  1539  		t.Fatalf("Unexpected Cluster.ListenStr=%q", opts.Cluster.ListenStr)
  1540  	}
  1541  	if opts.RoutesStr != "nats://127.0.0.1:6223" || len(opts.Routes) != 1 || opts.Routes[0].String() != expectedURL.String() {
  1542  		t.Fatalf("Unexpected RoutesStr: %q and Routes: %v", opts.RoutesStr, opts.Routes)
  1543  	}
  1544  
  1545  	// Use a config with cluster configuration and explicit route defined.
  1546  	// Override with empty routes string.
  1547  	opts = mustNotFail([]string{"-c", "./configs/srv_a.conf", "-routes", ""})
  1548  	if opts.RoutesStr != "" || len(opts.Routes) != 0 {
  1549  		t.Fatalf("Unexpected RoutesStr: %q and Routes: %v", opts.RoutesStr, opts.Routes)
  1550  	}
  1551  
  1552  	// Use a config with cluster configuration and override cluster listen string
  1553  	expectedURL, _ = url.Parse("nats-route://ruser:top_secret@127.0.0.1:7246")
  1554  	opts = mustNotFail([]string{"-c", "./configs/srv_a.conf", "-cluster", "nats://ivan:pwd@127.0.0.1:6222"})
  1555  	if opts.Cluster.Username != "ivan" || opts.Cluster.Password != "pwd" || opts.Cluster.Port != 6222 ||
  1556  		len(opts.Routes) != 1 || opts.Routes[0].String() != expectedURL.String() {
  1557  		t.Fatalf("Unexpected Cluster and/or Routes: %#v - %v", opts.Cluster, opts.Routes)
  1558  	}
  1559  
  1560  	// Disable clustering from command line
  1561  	opts = mustNotFail([]string{"-c", "./configs/srv_a.conf", "-cluster", ""})
  1562  	if opts.Cluster.Port != 0 {
  1563  		t.Fatalf("Unexpected Cluster: %v", opts.Cluster)
  1564  	}
  1565  
  1566  	// Various erros due to malformed cluster listen string.
  1567  	// (adding -routes to have more than 1 set flag to check
  1568  	// that Visit() stops when an error is found).
  1569  	expectToFail([]string{"-cluster", ":", "-routes", ""}, "protocol")
  1570  	expectToFail([]string{"-cluster", "nats://127.0.0.1", "-routes", ""}, "port")
  1571  	expectToFail([]string{"-cluster", "nats://127.0.0.1:xxx", "-routes", ""}, "invalid port")
  1572  	expectToFail([]string{"-cluster", "nats://ivan:127.0.0.1:6222", "-routes", ""}, "colons")
  1573  	expectToFail([]string{"-cluster", "nats://ivan@127.0.0.1:6222", "-routes", ""}, "password")
  1574  
  1575  	// Override config file's TLS configuration from command line, and completely disable TLS
  1576  	opts = mustNotFail([]string{"-c", "./configs/tls.conf", "-tls=false"})
  1577  	if opts.TLSConfig != nil || opts.TLS {
  1578  		t.Fatal("Expected TLS to be disabled")
  1579  	}
  1580  	// Override config file's TLS configuration from command line, and force TLS verification.
  1581  	// However, since TLS config has to be regenerated, user need to provide -tlscert and -tlskey too.
  1582  	// So this should fail.
  1583  	expectToFail([]string{"-c", "./configs/tls.conf", "-tlsverify"}, "valid")
  1584  
  1585  	// Now same than above, but with all valid params.
  1586  	opts = mustNotFail([]string{"-c", "./configs/tls.conf", "-tlsverify", "-tlscert", "./configs/certs/server.pem", "-tlskey", "./configs/certs/key.pem"})
  1587  	if opts.TLSConfig == nil || !opts.TLSVerify {
  1588  		t.Fatal("Expected TLS to be configured and force verification")
  1589  	}
  1590  
  1591  	// Configure TLS, but some TLS params missing
  1592  	expectToFail([]string{"-tls"}, "valid")
  1593  	expectToFail([]string{"-tls", "-tlscert", "./configs/certs/server.pem"}, "valid")
  1594  	// One of the file does not exist
  1595  	expectToFail([]string{"-tls", "-tlscert", "./configs/certs/server.pem", "-tlskey", "./configs/certs/notfound.pem"}, "file")
  1596  
  1597  	// Configure TLS and check that this results in a TLSConfig option.
  1598  	opts = mustNotFail([]string{"-tls", "-tlscert", "./configs/certs/server.pem", "-tlskey", "./configs/certs/key.pem"})
  1599  	if opts.TLSConfig == nil || !opts.TLS {
  1600  		t.Fatal("Expected TLSConfig to be set")
  1601  	}
  1602  	// Check that we use default TLS ciphers
  1603  	if !reflect.DeepEqual(opts.TLSConfig.CipherSuites, defaultCipherSuites()) {
  1604  		t.Fatalf("Default ciphers not set, expected %v, got %v", defaultCipherSuites(), opts.TLSConfig.CipherSuites)
  1605  	}
  1606  }
  1607  
  1608  func TestClusterPermissionsConfig(t *testing.T) {
  1609  	template := `
  1610  		cluster {
  1611  			port: 1234
  1612  			%s
  1613  			authorization {
  1614  				user: ivan
  1615  				password: pwd
  1616  				permissions {
  1617  					import {
  1618  						allow: "foo"
  1619  					}
  1620  					export {
  1621  						allow: "bar"
  1622  					}
  1623  				}
  1624  			}
  1625  		}
  1626  	`
  1627  	conf := createConfFile(t, []byte(fmt.Sprintf(template, "")))
  1628  	opts, err := ProcessConfigFile(conf)
  1629  	if err != nil {
  1630  		if cerr, ok := err.(*processConfigErr); ok && len(cerr.Errors()) > 0 {
  1631  			t.Fatalf("Error processing config file: %v", err)
  1632  		}
  1633  	}
  1634  	if opts.Cluster.Permissions == nil {
  1635  		t.Fatal("Expected cluster permissions to be set")
  1636  	}
  1637  	if opts.Cluster.Permissions.Import == nil {
  1638  		t.Fatal("Expected cluster import permissions to be set")
  1639  	}
  1640  	if len(opts.Cluster.Permissions.Import.Allow) != 1 || opts.Cluster.Permissions.Import.Allow[0] != "foo" {
  1641  		t.Fatalf("Expected cluster import permissions to have %q, got %v", "foo", opts.Cluster.Permissions.Import.Allow)
  1642  	}
  1643  	if opts.Cluster.Permissions.Export == nil {
  1644  		t.Fatal("Expected cluster export permissions to be set")
  1645  	}
  1646  	if len(opts.Cluster.Permissions.Export.Allow) != 1 || opts.Cluster.Permissions.Export.Allow[0] != "bar" {
  1647  		t.Fatalf("Expected cluster export permissions to have %q, got %v", "bar", opts.Cluster.Permissions.Export.Allow)
  1648  	}
  1649  
  1650  	// Now add permissions in top level cluster and check
  1651  	// that this is the one that is being used.
  1652  	conf = createConfFile(t, []byte(fmt.Sprintf(template, `
  1653  		permissions {
  1654  			import {
  1655  				allow: "baz"
  1656  			}
  1657  			export {
  1658  				allow: "bat"
  1659  			}
  1660  		}
  1661  	`)))
  1662  	opts, err = ProcessConfigFile(conf)
  1663  	if err != nil {
  1664  		t.Fatalf("Error processing config file: %v", err)
  1665  	}
  1666  	if opts.Cluster.Permissions == nil {
  1667  		t.Fatal("Expected cluster permissions to be set")
  1668  	}
  1669  	if opts.Cluster.Permissions.Import == nil {
  1670  		t.Fatal("Expected cluster import permissions to be set")
  1671  	}
  1672  	if len(opts.Cluster.Permissions.Import.Allow) != 1 || opts.Cluster.Permissions.Import.Allow[0] != "baz" {
  1673  		t.Fatalf("Expected cluster import permissions to have %q, got %v", "baz", opts.Cluster.Permissions.Import.Allow)
  1674  	}
  1675  	if opts.Cluster.Permissions.Export == nil {
  1676  		t.Fatal("Expected cluster export permissions to be set")
  1677  	}
  1678  	if len(opts.Cluster.Permissions.Export.Allow) != 1 || opts.Cluster.Permissions.Export.Allow[0] != "bat" {
  1679  		t.Fatalf("Expected cluster export permissions to have %q, got %v", "bat", opts.Cluster.Permissions.Export.Allow)
  1680  	}
  1681  
  1682  	// Tests with invalid permissions
  1683  	invalidPerms := []string{
  1684  		`permissions: foo`,
  1685  		`permissions {
  1686  			unknown_field: "foo"
  1687  		}`,
  1688  		`permissions {
  1689  			import: [1, 2, 3]
  1690  		}`,
  1691  		`permissions {
  1692  			import {
  1693  				unknown_field: "foo"
  1694  			}
  1695  		}`,
  1696  		`permissions {
  1697  			import {
  1698  				allow {
  1699  					x: y
  1700  				}
  1701  			}
  1702  		}`,
  1703  		`permissions {
  1704  			import {
  1705  				deny {
  1706  					x: y
  1707  				}
  1708  			}
  1709  		}`,
  1710  		`permissions {
  1711  			export: [1, 2, 3]
  1712  		}`,
  1713  		`permissions {
  1714  			export {
  1715  				unknown_field: "foo"
  1716  			}
  1717  		}`,
  1718  		`permissions {
  1719  			export {
  1720  				allow {
  1721  					x: y
  1722  				}
  1723  			}
  1724  		}`,
  1725  		`permissions {
  1726  			export {
  1727  				deny {
  1728  					x: y
  1729  				}
  1730  			}
  1731  		}`,
  1732  	}
  1733  	for _, perms := range invalidPerms {
  1734  		conf = createConfFile(t, []byte(fmt.Sprintf(`
  1735  			cluster {
  1736  				port: 1234
  1737  				%s
  1738  			}
  1739  		`, perms)))
  1740  		_, err := ProcessConfigFile(conf)
  1741  		if err == nil {
  1742  			t.Fatalf("Expected failure for permissions %s", perms)
  1743  		}
  1744  	}
  1745  
  1746  	for _, perms := range invalidPerms {
  1747  		conf = createConfFile(t, []byte(fmt.Sprintf(`
  1748  			cluster {
  1749  				port: 1234
  1750  				authorization {
  1751  					user: ivan
  1752  					password: pwd
  1753  					%s
  1754  				}
  1755  			}
  1756  		`, perms)))
  1757  		_, err := ProcessConfigFile(conf)
  1758  		if err == nil {
  1759  			t.Fatalf("Expected failure for permissions %s", perms)
  1760  		}
  1761  	}
  1762  }
  1763  
  1764  func TestParseServiceLatency(t *testing.T) {
  1765  	cases := []struct {
  1766  		name    string
  1767  		conf    string
  1768  		want    *serviceLatency
  1769  		wantErr bool
  1770  	}{
  1771  		{
  1772  			name: "block with percent sample default value",
  1773  			conf: `system_account = nats.io
  1774  			accounts {
  1775  				nats.io {
  1776  					exports [{
  1777  						service: nats.add
  1778  						latency: {
  1779  							sampling: 100%
  1780  							subject: latency.tracking.add
  1781  						}
  1782  					}]
  1783  				}
  1784  			}`,
  1785  			want: &serviceLatency{
  1786  				subject:  "latency.tracking.add",
  1787  				sampling: 100,
  1788  			},
  1789  		},
  1790  		{
  1791  			name: "block with percent sample nondefault value",
  1792  			conf: `system_account = nats.io
  1793  			accounts {
  1794  				nats.io {
  1795  					exports [{
  1796  						service: nats.add
  1797  						latency: {
  1798  							sampling: 33%
  1799  							subject: latency.tracking.add
  1800  						}
  1801  					}]
  1802  				}
  1803  			}`,
  1804  			want: &serviceLatency{
  1805  				subject:  "latency.tracking.add",
  1806  				sampling: 33,
  1807  			},
  1808  		},
  1809  		{
  1810  			name: "block with number sample nondefault value",
  1811  			conf: `system_account = nats.io
  1812  			accounts {
  1813  				nats.io {
  1814  					exports [{
  1815  						service: nats.add
  1816  						latency: {
  1817  							sampling: 87
  1818  							subject: latency.tracking.add
  1819  						}
  1820  					}]
  1821  				}
  1822  			}`,
  1823  			want: &serviceLatency{
  1824  				subject:  "latency.tracking.add",
  1825  				sampling: 87,
  1826  			},
  1827  		},
  1828  		{
  1829  			name: "field with subject",
  1830  			conf: `system_account = nats.io
  1831  			accounts {
  1832  				nats.io {
  1833  					exports [{
  1834  						service: nats.add
  1835  						latency: latency.tracking.add
  1836  					}]
  1837  				}
  1838  			}`,
  1839  			want: &serviceLatency{
  1840  				subject:  "latency.tracking.add",
  1841  				sampling: 100,
  1842  			},
  1843  		},
  1844  		{
  1845  			name: "block with missing subject",
  1846  			conf: `system_account = nats.io
  1847  			accounts {
  1848  				nats.io {
  1849  					exports [{
  1850  						service: nats.add
  1851  						latency: {
  1852  							sampling: 87
  1853  						}
  1854  					}]
  1855  				}
  1856  			}`,
  1857  			wantErr: true,
  1858  		},
  1859  	}
  1860  
  1861  	for _, c := range cases {
  1862  		t.Run(c.name, func(t *testing.T) {
  1863  			f := createConfFile(t, []byte(c.conf))
  1864  			opts, err := ProcessConfigFile(f)
  1865  			switch {
  1866  			case c.wantErr && err == nil:
  1867  				t.Fatalf("Expected ProcessConfigFile to fail, but didn't")
  1868  			case c.wantErr && err != nil:
  1869  				// We wanted an error and got one, test passed.
  1870  				return
  1871  			case !c.wantErr && err == nil:
  1872  				// We didn't want an error and didn't get one, keep going.
  1873  				break
  1874  			case !c.wantErr && err != nil:
  1875  				t.Fatalf("Failed to process config: %v", err)
  1876  			}
  1877  
  1878  			if len(opts.Accounts) != 1 {
  1879  				t.Fatalf("Expected accounts to have len %d, got %d", 1, len(opts.Accounts))
  1880  			}
  1881  			if len(opts.Accounts[0].exports.services) != 1 {
  1882  				t.Fatalf("Expected export services to have len %d, got %d", 1, len(opts.Accounts[0].exports.services))
  1883  			}
  1884  			s, ok := opts.Accounts[0].exports.services["nats.add"]
  1885  			if !ok {
  1886  				t.Fatalf("Expected export service nats.add, missing")
  1887  			}
  1888  
  1889  			if !reflect.DeepEqual(s.latency, c.want) {
  1890  				t.Fatalf("Expected latency to be %#v, got %#v", c.want, s.latency)
  1891  			}
  1892  		})
  1893  	}
  1894  }
  1895  
  1896  func TestParseExport(t *testing.T) {
  1897  	conf := `
  1898  		port: -1
  1899  		system_account: sys
  1900  		accounts {
  1901  			sys {
  1902  				exports [{
  1903  					stream "$SYS.SERVER.ACCOUNT.*.CONNS"
  1904  					account_token_position 4
  1905  				}]
  1906  			}
  1907  			accE {
  1908  				exports [{
  1909  					service foo.*
  1910  					account_token_position 2
  1911  				}]
  1912  				users [{
  1913  					user ue
  1914  					password pwd
  1915  				}],
  1916  			}
  1917  			accI1 {
  1918  				imports [{
  1919  					service {
  1920  						account accE
  1921  						subject foo.accI1
  1922  					}
  1923  					to foo
  1924  				},{
  1925  					stream {
  1926  						account sys
  1927  						subject "$SYS.SERVER.ACCOUNT.accI1.CONNS"
  1928  					}
  1929  				}],
  1930  				users [{
  1931  					user u1
  1932  					password pwd
  1933  				}],
  1934  			}
  1935  			accI2 {
  1936  				imports [{
  1937  					service {
  1938  						account accE
  1939  						subject foo.accI2
  1940  					}
  1941  					to foo
  1942  				},{
  1943  					stream {
  1944  						account sys
  1945  						subject "$SYS.SERVER.ACCOUNT.accI2.CONNS"
  1946  					}
  1947  				}],
  1948  				users [{
  1949  					user u2
  1950  					password pwd
  1951  				}],
  1952  			}
  1953  		}`
  1954  	f := createConfFile(t, []byte(conf))
  1955  	s, o := RunServerWithConfig(f)
  1956  	if s == nil {
  1957  		t.Fatal("Failed startup")
  1958  	}
  1959  	defer s.Shutdown()
  1960  	connect := func(user string) *nats.Conn {
  1961  		nc, err := nats.Connect(fmt.Sprintf("nats://%s:pwd@%s:%d", user, o.Host, o.Port))
  1962  		require_NoError(t, err)
  1963  		return nc
  1964  	}
  1965  	nc1 := connect("u1")
  1966  	defer nc1.Close()
  1967  	nc2 := connect("u2")
  1968  	defer nc2.Close()
  1969  
  1970  	// Due to the fact that above CONNECT events are generated and sent from
  1971  	// a system go routine, it is possible that by the time we create the
  1972  	// subscriptions below, the interest would exist and messages be sent,
  1973  	// which was causing issues since wg.Done() was called too many times.
  1974  	// Add a little delay to minimize risk, but also use counter to decide
  1975  	// when to call wg.Done() to avoid panic due to negative number.
  1976  	time.Sleep(100 * time.Millisecond)
  1977  
  1978  	wg := sync.WaitGroup{}
  1979  	wg.Add(1)
  1980  	count := int32(0)
  1981  	// We expect a total of 6 messages
  1982  	expected := int32(6)
  1983  	subscribe := func(nc *nats.Conn, subj string) {
  1984  		t.Helper()
  1985  		_, err := nc.Subscribe(subj, func(msg *nats.Msg) {
  1986  			if msg.Reply != _EMPTY_ {
  1987  				msg.Respond(msg.Data)
  1988  			}
  1989  			if atomic.AddInt32(&count, 1) == expected {
  1990  				wg.Done()
  1991  			}
  1992  		})
  1993  		require_NoError(t, err)
  1994  		nc.Flush()
  1995  	}
  1996  	//Subscribe to CONNS events
  1997  	subscribe(nc1, "$SYS.SERVER.ACCOUNT.accI1.CONNS")
  1998  	subscribe(nc2, "$SYS.SERVER.ACCOUNT.accI2.CONNS")
  1999  	// Trigger 2 CONNS event
  2000  	nc3 := connect("u1")
  2001  	nc3.Close()
  2002  	nc4 := connect("u2")
  2003  	nc4.Close()
  2004  	// test service
  2005  	ncE := connect("ue")
  2006  	defer ncE.Close()
  2007  	subscribe(ncE, "foo.*")
  2008  	request := func(nc *nats.Conn, msg string) {
  2009  		if m, err := nc.Request("foo", []byte(msg), time.Second); err != nil {
  2010  			t.Fatal("Failed request ", msg, err)
  2011  		} else if m == nil {
  2012  			t.Fatal("No response msg")
  2013  		} else if string(m.Data) != msg {
  2014  			t.Fatal("Wrong response msg", string(m.Data))
  2015  		}
  2016  	}
  2017  	request(nc1, "1")
  2018  	request(nc2, "1")
  2019  	wg.Wait()
  2020  }
  2021  
  2022  func TestAccountUsersLoadedProperly(t *testing.T) {
  2023  	conf := createConfFile(t, []byte(`
  2024  	listen: "127.0.0.1:-1"
  2025  	authorization {
  2026  		users [
  2027  			{user: ivan, password: bar}
  2028  			{nkey : UC6NLCN7AS34YOJVCYD4PJ3QB7QGLYG5B5IMBT25VW5K4TNUJODM7BOX}
  2029  		]
  2030  	}
  2031  	accounts {
  2032  		synadia {
  2033  			users [
  2034  				{user: derek, password: foo}
  2035  				{nkey : UBAAQWTW6CG2G6ANGNKB5U2B7HRWHSGMZEZX3AQSAJOQDAUGJD46LD2E}
  2036  			]
  2037  		}
  2038  	}
  2039  	`))
  2040  	check := func(t *testing.T) {
  2041  		t.Helper()
  2042  		s, _ := RunServerWithConfig(conf)
  2043  		defer s.Shutdown()
  2044  		opts := s.getOpts()
  2045  		if n := len(opts.Users); n != 2 {
  2046  			t.Fatalf("Should have 2 users, got %v", n)
  2047  		}
  2048  		if n := len(opts.Nkeys); n != 2 {
  2049  			t.Fatalf("Should have 2 nkeys, got %v", n)
  2050  		}
  2051  	}
  2052  	// Repeat test since issue was with ordering of processing
  2053  	// of authorization vs accounts that depends on range of a map (after actual parsing)
  2054  	for i := 0; i < 20; i++ {
  2055  		check(t)
  2056  	}
  2057  }
  2058  
  2059  func TestParsingGateways(t *testing.T) {
  2060  	content := `
  2061  	gateway {
  2062  		name: "A"
  2063  		listen: "127.0.0.1:4444"
  2064  		host: "127.0.0.1"
  2065  		port: 4444
  2066  		reject_unknown_cluster: true
  2067  		authorization {
  2068  			user: "ivan"
  2069  			password: "pwd"
  2070  			timeout: 2.0
  2071  		}
  2072  		tls {
  2073  			cert_file: "./configs/certs/server.pem"
  2074  			key_file: "./configs/certs/key.pem"
  2075  			timeout: 3.0
  2076  		}
  2077  		advertise: "me:1"
  2078  		connect_retries: 10
  2079  		gateways: [
  2080  			{
  2081  				name: "B"
  2082  				urls: ["nats://user1:pwd1@host2:5222", "nats://user1:pwd1@host3:6222"]
  2083  			}
  2084  			{
  2085  				name: "C"
  2086  				url: "nats://host4:7222"
  2087  			}
  2088  		]
  2089  	}
  2090  	`
  2091  	file := "server_config_gateways.conf"
  2092  	if err := os.WriteFile(file, []byte(content), 0600); err != nil {
  2093  		t.Fatalf("Error writing config file: %v", err)
  2094  	}
  2095  	defer removeFile(t, file)
  2096  	opts, err := ProcessConfigFile(file)
  2097  	if err != nil {
  2098  		t.Fatalf("Error processing file: %v", err)
  2099  	}
  2100  
  2101  	expected := &GatewayOpts{
  2102  		Name:           "A",
  2103  		Host:           "127.0.0.1",
  2104  		Port:           4444,
  2105  		Username:       "ivan",
  2106  		Password:       "pwd",
  2107  		AuthTimeout:    2.0,
  2108  		Advertise:      "me:1",
  2109  		ConnectRetries: 10,
  2110  		TLSTimeout:     3.0,
  2111  		RejectUnknown:  true,
  2112  	}
  2113  	u1, _ := url.Parse("nats://user1:pwd1@host2:5222")
  2114  	u2, _ := url.Parse("nats://user1:pwd1@host3:6222")
  2115  	urls := []*url.URL{u1, u2}
  2116  	gw := &RemoteGatewayOpts{
  2117  		Name: "B",
  2118  		URLs: urls,
  2119  	}
  2120  	expected.Gateways = append(expected.Gateways, gw)
  2121  
  2122  	u1, _ = url.Parse("nats://host4:7222")
  2123  	urls = []*url.URL{u1}
  2124  	gw = &RemoteGatewayOpts{
  2125  		Name: "C",
  2126  		URLs: urls,
  2127  	}
  2128  	expected.Gateways = append(expected.Gateways, gw)
  2129  
  2130  	// Just make sure that TLSConfig is set.. we have aother test
  2131  	// to check proper generating TLSConfig from config file...
  2132  	if opts.Gateway.TLSConfig == nil {
  2133  		t.Fatalf("Expected TLSConfig, got none")
  2134  	}
  2135  	opts.Gateway.TLSConfig = nil
  2136  	opts.Gateway.tlsConfigOpts = nil
  2137  	if !reflect.DeepEqual(&opts.Gateway, expected) {
  2138  		t.Fatalf("Expected %v, got %v", expected, opts.Gateway)
  2139  	}
  2140  }
  2141  
  2142  func TestParsingGatewaysErrors(t *testing.T) {
  2143  	for _, test := range []struct {
  2144  		name        string
  2145  		content     string
  2146  		expectedErr string
  2147  	}{
  2148  		{
  2149  			"bad_type",
  2150  			`gateway: "bad_type"`,
  2151  			"Expected gateway to be a map",
  2152  		},
  2153  		{
  2154  			"bad_listen",
  2155  			`gateway {
  2156  				name: "A"
  2157  				port: -1
  2158  				listen: "bad::address"
  2159  			}`,
  2160  			"parse address",
  2161  		},
  2162  		{
  2163  			"bad_auth",
  2164  			`gateway {
  2165  				name: "A"
  2166  				port: -1
  2167  				authorization {
  2168  					users {
  2169  					}
  2170  				}
  2171  			}`,
  2172  			"be an array",
  2173  		},
  2174  		{
  2175  			"unknown_field",
  2176  			`gateway {
  2177  				name: "A"
  2178  				port: -1
  2179  				reject_unknown_cluster: true
  2180  				unknown_field: 1
  2181  			}`,
  2182  			"unknown field",
  2183  		},
  2184  		{
  2185  			"users_not_supported",
  2186  			`gateway {
  2187  				name: "A"
  2188  				port: -1
  2189  				authorization {
  2190  					users [
  2191  						{user: alice, password: foo}
  2192  						{user: bob,   password: bar}
  2193  					]
  2194  				}
  2195  			}`,
  2196  			"does not allow multiple users",
  2197  		},
  2198  		{
  2199  			"tls_error",
  2200  			`gateway {
  2201  				name: "A"
  2202  				port: -1
  2203  				tls {
  2204  					cert_file: 123
  2205  				}
  2206  			}`,
  2207  			"to be filename",
  2208  		},
  2209  		{
  2210  			"tls_gen_error_cert_file_not_found",
  2211  			`gateway {
  2212  				name: "A"
  2213  				port: -1
  2214  				tls {
  2215  					cert_file: "./configs/certs/missing.pem"
  2216  					key_file: "./configs/certs/server-key.pem"
  2217  				}
  2218  			}`,
  2219  			"certificate/key pair",
  2220  		},
  2221  		{
  2222  			"tls_gen_error_key_file_not_found",
  2223  			`gateway {
  2224  				name: "A"
  2225  				port: -1
  2226  				tls {
  2227  					cert_file: "./configs/certs/server.pem"
  2228  					key_file: "./configs/certs/missing.pem"
  2229  				}
  2230  			}`,
  2231  			"certificate/key pair",
  2232  		},
  2233  		{
  2234  			"tls_gen_error_key_file_missing",
  2235  			`gateway {
  2236  				name: "A"
  2237  				port: -1
  2238  				tls {
  2239  					cert_file: "./configs/certs/server.pem"
  2240  				}
  2241  			}`,
  2242  			`missing 'key_file' in TLS configuration`,
  2243  		},
  2244  		{
  2245  			"tls_gen_error_cert_file_missing",
  2246  			`gateway {
  2247  				name: "A"
  2248  				port: -1
  2249  				tls {
  2250  					key_file: "./configs/certs/server-key.pem"
  2251  				}
  2252  			}`,
  2253  			`missing 'cert_file' in TLS configuration`,
  2254  		},
  2255  		{
  2256  			"tls_gen_error_key_file_not_found",
  2257  			`gateway {
  2258  				name: "A"
  2259  				port: -1
  2260  				tls {
  2261  					cert_file: "./configs/certs/server.pem"
  2262  					key_file: "./configs/certs/missing.pem"
  2263  				}
  2264  			}`,
  2265  			"certificate/key pair",
  2266  		},
  2267  		{
  2268  			"gateways_needs_to_be_an_array",
  2269  			`gateway {
  2270  				name: "A"
  2271  				gateways {
  2272  					name: "B"
  2273  				}
  2274  			}`,
  2275  			"Expected gateways field to be an array",
  2276  		},
  2277  		{
  2278  			"gateways_entry_needs_to_be_a_map",
  2279  			`gateway {
  2280  				name: "A"
  2281  				gateways [
  2282  					"g1", "g2"
  2283  				]
  2284  			}`,
  2285  			"Expected gateway entry to be a map",
  2286  		},
  2287  		{
  2288  			"bad_url",
  2289  			`gateway {
  2290  				name: "A"
  2291  				gateways [
  2292  					{
  2293  						name: "B"
  2294  						url: "nats://wrong url"
  2295  					}
  2296  				]
  2297  			}`,
  2298  			"error parsing gateway url",
  2299  		},
  2300  		{
  2301  			"bad_urls",
  2302  			`gateway {
  2303  				name: "A"
  2304  				gateways [
  2305  					{
  2306  						name: "B"
  2307  						urls: ["nats://wrong url", "nats://host:5222"]
  2308  					}
  2309  				]
  2310  			}`,
  2311  			"error parsing gateway url",
  2312  		},
  2313  		{
  2314  			"gateway_tls_error",
  2315  			`gateway {
  2316  				name: "A"
  2317  				port: -1
  2318  				gateways [
  2319  					{
  2320  						name: "B"
  2321  						tls {
  2322  							cert_file: 123
  2323  						}
  2324  					}
  2325  				]
  2326  			}`,
  2327  			"to be filename",
  2328  		},
  2329  		{
  2330  			"gateway_unknown_field",
  2331  			`gateway {
  2332  				name: "A"
  2333  				port: -1
  2334  				gateways [
  2335  					{
  2336  						name: "B"
  2337  						unknown_field: 1
  2338  					}
  2339  				]
  2340  			}`,
  2341  			"unknown field",
  2342  		},
  2343  	} {
  2344  		t.Run(test.name, func(t *testing.T) {
  2345  			file := fmt.Sprintf("server_config_gateways_%s.conf", test.name)
  2346  			if err := os.WriteFile(file, []byte(test.content), 0600); err != nil {
  2347  				t.Fatalf("Error writing config file: %v", err)
  2348  			}
  2349  			defer removeFile(t, file)
  2350  			_, err := ProcessConfigFile(file)
  2351  			if err == nil {
  2352  				t.Fatalf("Expected to fail, did not. Content:\n%s", test.content)
  2353  			} else if !strings.Contains(err.Error(), test.expectedErr) {
  2354  				t.Fatalf("Expected error containing %q, got %q, for content:\n%s", test.expectedErr, err, test.content)
  2355  			}
  2356  		})
  2357  	}
  2358  }
  2359  
  2360  func TestParsingLeafNodesListener(t *testing.T) {
  2361  	content := `
  2362  	leafnodes {
  2363  		listen: "127.0.0.1:3333"
  2364  		host: "127.0.0.1"
  2365  		port: 3333
  2366  		advertise: "me:22"
  2367  		authorization {
  2368  			user: "derek"
  2369  			password: "s3cr3t!"
  2370  			timeout: 2.2
  2371  		}
  2372  		tls {
  2373  			cert_file: "./configs/certs/server.pem"
  2374  			key_file: "./configs/certs/key.pem"
  2375  			timeout: 3.3
  2376  		}
  2377  	}
  2378  	`
  2379  	conf := createConfFile(t, []byte(content))
  2380  	opts, err := ProcessConfigFile(conf)
  2381  	if err != nil {
  2382  		t.Fatalf("Error processing file: %v", err)
  2383  	}
  2384  
  2385  	expected := &LeafNodeOpts{
  2386  		Host:        "127.0.0.1",
  2387  		Port:        3333,
  2388  		Username:    "derek",
  2389  		Password:    "s3cr3t!",
  2390  		AuthTimeout: 2.2,
  2391  		Advertise:   "me:22",
  2392  		TLSTimeout:  3.3,
  2393  	}
  2394  	if opts.LeafNode.TLSConfig == nil {
  2395  		t.Fatalf("Expected TLSConfig, got none")
  2396  	}
  2397  	if opts.LeafNode.tlsConfigOpts == nil {
  2398  		t.Fatalf("Expected TLSConfig snapshot, got none")
  2399  	}
  2400  	opts.LeafNode.TLSConfig = nil
  2401  	opts.LeafNode.tlsConfigOpts = nil
  2402  	if !reflect.DeepEqual(&opts.LeafNode, expected) {
  2403  		t.Fatalf("Expected %v, got %v", expected, opts.LeafNode)
  2404  	}
  2405  }
  2406  
  2407  func TestParsingLeafNodeRemotes(t *testing.T) {
  2408  	t.Run("parse config file with relative path", func(t *testing.T) {
  2409  		content := `
  2410  		leafnodes {
  2411  			remotes = [
  2412  				{
  2413  					url: nats-leaf://127.0.0.1:2222
  2414  					account: foobar // Local Account to bind to..
  2415  					credentials: "./my.creds"
  2416  				}
  2417  			]
  2418  		}
  2419  		`
  2420  		conf := createConfFile(t, []byte(content))
  2421  		opts, err := ProcessConfigFile(conf)
  2422  		if err != nil {
  2423  			t.Fatalf("Error processing file: %v", err)
  2424  		}
  2425  		if len(opts.LeafNode.Remotes) != 1 {
  2426  			t.Fatalf("Expected 1 remote, got %d", len(opts.LeafNode.Remotes))
  2427  		}
  2428  		expected := &RemoteLeafOpts{
  2429  			LocalAccount: "foobar",
  2430  			Credentials:  "./my.creds",
  2431  		}
  2432  		u, _ := url.Parse("nats-leaf://127.0.0.1:2222")
  2433  		expected.URLs = append(expected.URLs, u)
  2434  		if !reflect.DeepEqual(opts.LeafNode.Remotes[0], expected) {
  2435  			t.Fatalf("Expected %v, got %v", expected, opts.LeafNode.Remotes[0])
  2436  		}
  2437  	})
  2438  
  2439  	t.Run("parse config file with tilde path", func(t *testing.T) {
  2440  		if runtime.GOOS == "windows" {
  2441  			t.SkipNow()
  2442  		}
  2443  
  2444  		origHome := os.Getenv("HOME")
  2445  		defer os.Setenv("HOME", origHome)
  2446  		os.Setenv("HOME", "/home/foo")
  2447  
  2448  		content := `
  2449  		leafnodes {
  2450  			remotes = [
  2451  				{
  2452  					url: nats-leaf://127.0.0.1:2222
  2453  					account: foobar // Local Account to bind to..
  2454  					credentials: "~/my.creds"
  2455  				}
  2456  			]
  2457  		}
  2458  		`
  2459  		conf := createConfFile(t, []byte(content))
  2460  		opts, err := ProcessConfigFile(conf)
  2461  		if err != nil {
  2462  			t.Fatalf("Error processing file: %v", err)
  2463  		}
  2464  		expected := &RemoteLeafOpts{
  2465  			LocalAccount: "foobar",
  2466  			Credentials:  "/home/foo/my.creds",
  2467  		}
  2468  		u, _ := url.Parse("nats-leaf://127.0.0.1:2222")
  2469  		expected.URLs = append(expected.URLs, u)
  2470  		if !reflect.DeepEqual(opts.LeafNode.Remotes[0], expected) {
  2471  			t.Fatalf("Expected %v, got %v", expected, opts.LeafNode.Remotes[0])
  2472  		}
  2473  	})
  2474  
  2475  	t.Run("url ordering", func(t *testing.T) {
  2476  		// 16! possible permutations.
  2477  		orderedURLs := make([]string, 0, 16)
  2478  		for i := 0; i < cap(orderedURLs); i++ {
  2479  			orderedURLs = append(orderedURLs, fmt.Sprintf("nats-leaf://host%d:7422", i))
  2480  		}
  2481  		confURLs, err := json.Marshal(orderedURLs)
  2482  		if err != nil {
  2483  			t.Fatal(err)
  2484  		}
  2485  
  2486  		content := `
  2487  		port: -1
  2488  		leafnodes {
  2489  			remotes = [
  2490  				{
  2491  					dont_randomize: true
  2492  					urls: %[1]s
  2493  				}
  2494  				{
  2495  					urls: %[1]s
  2496  				}
  2497  			]
  2498  		}
  2499  		`
  2500  		conf := createConfFile(t, []byte(fmt.Sprintf(content, confURLs)))
  2501  
  2502  		s, _ := RunServerWithConfig(conf)
  2503  		defer s.Shutdown()
  2504  
  2505  		s.mu.Lock()
  2506  		r1 := s.leafRemoteCfgs[0]
  2507  		r2 := s.leafRemoteCfgs[1]
  2508  		s.mu.Unlock()
  2509  
  2510  		r1.RLock()
  2511  		gotOrdered := r1.urls
  2512  		r1.RUnlock()
  2513  		if got, want := len(gotOrdered), len(orderedURLs); got != want {
  2514  			t.Fatalf("Unexpected rem0 len URLs, got %d, want %d", got, want)
  2515  		}
  2516  
  2517  		// These should be IN order.
  2518  		for i := range orderedURLs {
  2519  			if got, want := gotOrdered[i].String(), orderedURLs[i]; got != want {
  2520  				t.Fatalf("Unexpected ordered url, got %s, want %s", got, want)
  2521  			}
  2522  		}
  2523  
  2524  		r2.RLock()
  2525  		gotRandom := r2.urls
  2526  		r2.RUnlock()
  2527  		if got, want := len(gotRandom), len(orderedURLs); got != want {
  2528  			t.Fatalf("Unexpected rem1 len URLs, got %d, want %d", got, want)
  2529  		}
  2530  
  2531  		// These should be OUT of order.
  2532  		var random bool
  2533  		for i := range orderedURLs {
  2534  			if gotRandom[i].String() != orderedURLs[i] {
  2535  				random = true
  2536  				break
  2537  			}
  2538  		}
  2539  		if !random {
  2540  			t.Fatal("Expected urls to be random")
  2541  		}
  2542  	})
  2543  }
  2544  
  2545  func TestLargeMaxControlLine(t *testing.T) {
  2546  	confFileName := createConfFile(t, []byte(`
  2547  		max_control_line = 3000000000
  2548  	`))
  2549  	if _, err := ProcessConfigFile(confFileName); err == nil {
  2550  		t.Fatalf("Expected an error from too large of a max_control_line entry")
  2551  	}
  2552  }
  2553  
  2554  func TestLargeMaxPayload(t *testing.T) {
  2555  	confFileName := createConfFile(t, []byte(`
  2556  		max_payload = 3000000000
  2557  	`))
  2558  	if _, err := ProcessConfigFile(confFileName); err == nil {
  2559  		t.Fatalf("Expected an error from too large of a max_payload entry")
  2560  	}
  2561  
  2562  	confFileName = createConfFile(t, []byte(`
  2563  		max_payload = 100000
  2564  		max_pending = 50000
  2565  	`))
  2566  	o := LoadConfig(confFileName)
  2567  	s, err := NewServer(o)
  2568  	if err == nil || !strings.Contains(err.Error(), "cannot be higher") {
  2569  		if s != nil {
  2570  			s.Shutdown()
  2571  		}
  2572  		t.Fatalf("Unexpected error: %v", err)
  2573  	}
  2574  }
  2575  
  2576  func TestHandleUnknownTopLevelConfigurationField(t *testing.T) {
  2577  	conf := createConfFile(t, []byte(`
  2578  		port: 1234
  2579  		streaming {
  2580  			id: "me"
  2581  		}
  2582  	`))
  2583  
  2584  	// Verify that we get an error because of unknown "streaming" field.
  2585  	opts := &Options{}
  2586  	if err := opts.ProcessConfigFile(conf); err == nil || !strings.Contains(err.Error(), "streaming") {
  2587  		t.Fatal("Expected error, got none")
  2588  	}
  2589  
  2590  	// Verify that if that is set, we get no error
  2591  	NoErrOnUnknownFields(true)
  2592  	defer NoErrOnUnknownFields(false)
  2593  
  2594  	if err := opts.ProcessConfigFile(conf); err != nil {
  2595  		t.Fatalf("Unexpected error: %v", err)
  2596  	}
  2597  	if opts.Port != 1234 {
  2598  		t.Fatalf("Port was not parsed correctly: %v", opts.Port)
  2599  	}
  2600  
  2601  	// Verify that ignore works only on top level fields.
  2602  	changeCurrentConfigContentWithNewContent(t, conf, []byte(`
  2603  		port: 1234
  2604  		cluster {
  2605  			non_top_level_unknown_field: 123
  2606  		}
  2607  		streaming {
  2608  			id: "me"
  2609  		}
  2610  	`))
  2611  	if err := opts.ProcessConfigFile(conf); err == nil || !strings.Contains(err.Error(), "non_top_level") {
  2612  		t.Fatal("Expected error, got none")
  2613  	}
  2614  }
  2615  
  2616  func TestSublistNoCacheConfig(t *testing.T) {
  2617  	confFileName := createConfFile(t, []byte(`
  2618        disable_sublist_cache: true
  2619      `))
  2620  	opts, err := ProcessConfigFile(confFileName)
  2621  	if err != nil {
  2622  		t.Fatalf("Received an error reading config file: %v", err)
  2623  	}
  2624  	if !opts.NoSublistCache {
  2625  		t.Fatalf("Expected sublist cache to be disabled")
  2626  	}
  2627  }
  2628  
  2629  func TestSublistNoCacheConfigOnAccounts(t *testing.T) {
  2630  	confFileName := createConfFile(t, []byte(`
  2631  	  listen: "127.0.0.1:-1"
  2632        disable_sublist_cache: true
  2633  
  2634  	  accounts {
  2635  		synadia {
  2636  			users [ {nkey : UBAAQWTW6CG2G6ANGNKB5U2B7HRWHSGMZEZX3AQSAJOQDAUGJD46LD2E} ]
  2637  		}
  2638  		nats.io {
  2639  			users [ {nkey : UC6NLCN7AS34YOJVCYD4PJ3QB7QGLYG5B5IMBT25VW5K4TNUJODM7BOX} ]
  2640  		}
  2641  	  }
  2642  	  no_sys_acc = true
  2643      `))
  2644  
  2645  	s, _ := RunServerWithConfig(confFileName)
  2646  	defer s.Shutdown()
  2647  
  2648  	// Check that all account sublists do not have caching enabled.
  2649  	ta := s.numReservedAccounts() + 2
  2650  	if la := s.numAccounts(); la != ta {
  2651  		t.Fatalf("Expected to have a server with %d active accounts, got %v", ta, la)
  2652  	}
  2653  
  2654  	s.accounts.Range(func(k, v any) bool {
  2655  		acc := v.(*Account)
  2656  		if acc == nil {
  2657  			t.Fatalf("Expected non-nil sublist for account")
  2658  		}
  2659  		if acc.sl.CacheEnabled() {
  2660  			t.Fatalf("Expected the account sublist to not have caching enabled")
  2661  		}
  2662  		return true
  2663  	})
  2664  }
  2665  
  2666  func TestParsingResponsePermissions(t *testing.T) {
  2667  	template := `
  2668  		listen: "127.0.0.1:-1"
  2669  		authorization {
  2670  			users [
  2671  				{
  2672  					user: ivan
  2673  					password: pwd
  2674  					permissions {
  2675  						allow_responses {
  2676  							%s
  2677  							%s
  2678  						}
  2679  					}
  2680  				}
  2681  			]
  2682  		}
  2683  	`
  2684  
  2685  	check := func(t *testing.T, conf string, expectedError string, expectedMaxMsgs int, expectedTTL time.Duration) {
  2686  		t.Helper()
  2687  		opts, err := ProcessConfigFile(conf)
  2688  		if expectedError != "" {
  2689  			if err == nil || !strings.Contains(err.Error(), expectedError) {
  2690  				t.Fatalf("Expected error about %q, got %q", expectedError, err)
  2691  			}
  2692  			// OK!
  2693  			return
  2694  		}
  2695  		if err != nil {
  2696  			t.Fatalf("Error on process: %v", err)
  2697  		}
  2698  		u := opts.Users[0]
  2699  		p := u.Permissions.Response
  2700  		if p == nil {
  2701  			t.Fatalf("Expected response permissions to be set, it was not")
  2702  		}
  2703  		if n := p.MaxMsgs; n != expectedMaxMsgs {
  2704  			t.Fatalf("Expected response max msgs to be %v, got %v", expectedMaxMsgs, n)
  2705  		}
  2706  		if ttl := p.Expires; ttl != expectedTTL {
  2707  			t.Fatalf("Expected response ttl to be %v, got %v", expectedTTL, ttl)
  2708  		}
  2709  	}
  2710  
  2711  	// Check defaults
  2712  	conf := createConfFile(t, []byte(fmt.Sprintf(template, "", "")))
  2713  	check(t, conf, "", DEFAULT_ALLOW_RESPONSE_MAX_MSGS, DEFAULT_ALLOW_RESPONSE_EXPIRATION)
  2714  
  2715  	conf = createConfFile(t, []byte(fmt.Sprintf(template, "max: 10", "")))
  2716  	check(t, conf, "", 10, DEFAULT_ALLOW_RESPONSE_EXPIRATION)
  2717  
  2718  	conf = createConfFile(t, []byte(fmt.Sprintf(template, "", "ttl: 5s")))
  2719  	check(t, conf, "", DEFAULT_ALLOW_RESPONSE_MAX_MSGS, 5*time.Second)
  2720  
  2721  	conf = createConfFile(t, []byte(fmt.Sprintf(template, "max: 0", "")))
  2722  	check(t, conf, "", DEFAULT_ALLOW_RESPONSE_MAX_MSGS, DEFAULT_ALLOW_RESPONSE_EXPIRATION)
  2723  
  2724  	conf = createConfFile(t, []byte(fmt.Sprintf(template, "", `ttl: "0s"`)))
  2725  	check(t, conf, "", DEFAULT_ALLOW_RESPONSE_MAX_MSGS, DEFAULT_ALLOW_RESPONSE_EXPIRATION)
  2726  
  2727  	// Check normal values
  2728  	conf = createConfFile(t, []byte(fmt.Sprintf(template, "max: 10", `ttl: "5s"`)))
  2729  	check(t, conf, "", 10, 5*time.Second)
  2730  
  2731  	// Check negative values ok
  2732  	conf = createConfFile(t, []byte(fmt.Sprintf(template, "max: -1", `ttl: "5s"`)))
  2733  	check(t, conf, "", -1, 5*time.Second)
  2734  
  2735  	conf = createConfFile(t, []byte(fmt.Sprintf(template, "max: 10", `ttl: "-1s"`)))
  2736  	check(t, conf, "", 10, -1*time.Second)
  2737  
  2738  	conf = createConfFile(t, []byte(fmt.Sprintf(template, "max: -1", `ttl: "-1s"`)))
  2739  	check(t, conf, "", -1, -1*time.Second)
  2740  
  2741  	// Check parsing errors
  2742  	conf = createConfFile(t, []byte(fmt.Sprintf(template, "unknown_field: 123", "")))
  2743  	check(t, conf, "Unknown field", 0, 0)
  2744  
  2745  	conf = createConfFile(t, []byte(fmt.Sprintf(template, "max: 10", "ttl: 123")))
  2746  	check(t, conf, "not a duration string", 0, 0)
  2747  
  2748  	conf = createConfFile(t, []byte(fmt.Sprintf(template, "max: 10", "ttl: xyz")))
  2749  	check(t, conf, "error parsing expires", 0, 0)
  2750  }
  2751  
  2752  func TestExpandPath(t *testing.T) {
  2753  	if runtime.GOOS == "windows" {
  2754  		origUserProfile := os.Getenv("USERPROFILE")
  2755  		origHomeDrive, origHomePath := os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH")
  2756  		defer func() {
  2757  			os.Setenv("USERPROFILE", origUserProfile)
  2758  			os.Setenv("HOMEDRIVE", origHomeDrive)
  2759  			os.Setenv("HOMEPATH", origHomePath)
  2760  		}()
  2761  
  2762  		cases := []struct {
  2763  			path        string
  2764  			userProfile string
  2765  			homeDrive   string
  2766  			homePath    string
  2767  
  2768  			wantPath string
  2769  			wantErr  bool
  2770  		}{
  2771  			// Missing HOMEDRIVE and HOMEPATH.
  2772  			{path: "/Foo/Bar", userProfile: `C:\Foo\Bar`, wantPath: "/Foo/Bar"},
  2773  			{path: "Foo/Bar", userProfile: `C:\Foo\Bar`, wantPath: "Foo/Bar"},
  2774  			{path: "~/Fizz", userProfile: `C:\Foo\Bar`, wantPath: `C:\Foo\Bar\Fizz`},
  2775  			{path: `${HOMEDRIVE}${HOMEPATH}\Fizz`, homeDrive: `C:`, homePath: `\Foo\Bar`, wantPath: `C:\Foo\Bar\Fizz`},
  2776  
  2777  			// Missing USERPROFILE.
  2778  			{path: "~/Fizz", homeDrive: "X:", homePath: `\Foo\Bar`, wantPath: `X:\Foo\Bar\Fizz`},
  2779  
  2780  			// Set all environment variables. HOMEDRIVE and HOMEPATH take
  2781  			// precedence.
  2782  			{path: "~/Fizz", userProfile: `C:\Foo\Bar`,
  2783  				homeDrive: "X:", homePath: `\Foo\Bar`, wantPath: `X:\Foo\Bar\Fizz`},
  2784  
  2785  			// Missing all environment variables.
  2786  			{path: "~/Fizz", wantErr: true},
  2787  		}
  2788  		for i, c := range cases {
  2789  			t.Run(fmt.Sprintf("windows case %d", i), func(t *testing.T) {
  2790  				os.Setenv("USERPROFILE", c.userProfile)
  2791  				os.Setenv("HOMEDRIVE", c.homeDrive)
  2792  				os.Setenv("HOMEPATH", c.homePath)
  2793  
  2794  				gotPath, err := expandPath(c.path)
  2795  				if !c.wantErr && err != nil {
  2796  					t.Fatalf("unexpected error: got=%v; want=%v", err, nil)
  2797  				} else if c.wantErr && err == nil {
  2798  					t.Fatalf("unexpected success: got=%v; want=%v", nil, "err")
  2799  				}
  2800  
  2801  				if gotPath != c.wantPath {
  2802  					t.Fatalf("unexpected path: got=%v; want=%v", gotPath, c.wantPath)
  2803  				}
  2804  			})
  2805  		}
  2806  
  2807  		return
  2808  	}
  2809  
  2810  	// Unix tests
  2811  
  2812  	origHome := os.Getenv("HOME")
  2813  	defer os.Setenv("HOME", origHome)
  2814  
  2815  	cases := []struct {
  2816  		path     string
  2817  		home     string
  2818  		wantPath string
  2819  		wantErr  bool
  2820  	}{
  2821  		{path: "/foo/bar", home: "/fizz/buzz", wantPath: "/foo/bar"},
  2822  		{path: "foo/bar", home: "/fizz/buzz", wantPath: "foo/bar"},
  2823  		{path: "~/fizz", home: "/foo/bar", wantPath: "/foo/bar/fizz"},
  2824  		{path: "$HOME/fizz", home: "/foo/bar", wantPath: "/foo/bar/fizz"},
  2825  
  2826  		// missing HOME env var
  2827  		{path: "~/fizz", wantErr: true},
  2828  	}
  2829  	for i, c := range cases {
  2830  		t.Run(fmt.Sprintf("unix case %d", i), func(t *testing.T) {
  2831  			os.Setenv("HOME", c.home)
  2832  
  2833  			gotPath, err := expandPath(c.path)
  2834  			if !c.wantErr && err != nil {
  2835  				t.Fatalf("unexpected error: got=%v; want=%v", err, nil)
  2836  			} else if c.wantErr && err == nil {
  2837  				t.Fatalf("unexpected success: got=%v; want=%v", nil, "err")
  2838  			}
  2839  
  2840  			if gotPath != c.wantPath {
  2841  				t.Fatalf("unexpected path: got=%v; want=%v", gotPath, c.wantPath)
  2842  			}
  2843  		})
  2844  	}
  2845  }
  2846  
  2847  func TestNoAuthUserCode(t *testing.T) {
  2848  	confFileName := createConfFile(t, []byte(`
  2849  		listen: "127.0.0.1:-1"
  2850  		no_auth_user: $NO_AUTH_USER
  2851  
  2852  		accounts {
  2853  			synadia {
  2854  				users [
  2855  					{user: "a", password: "a"},
  2856  					{nkey : UBAAQWTW6CG2G6ANGNKB5U2B7HRWHSGMZEZX3AQSAJOQDAUGJD46LD2E},
  2857  				]
  2858  			}
  2859  			acc {
  2860  				users [
  2861  					{user: "c", password: "c"}
  2862  				]
  2863  			}
  2864  		}
  2865  		# config for $G
  2866  		authorization {
  2867  			users [
  2868  				{user: "b", password: "b"}
  2869  			]
  2870  		}
  2871  	`))
  2872  	defer os.Unsetenv("NO_AUTH_USER")
  2873  
  2874  	for _, user := range []string{"a", "b", "b"} {
  2875  		t.Run(user, func(t *testing.T) {
  2876  			os.Setenv("NO_AUTH_USER", user)
  2877  			opts, err := ProcessConfigFile(confFileName)
  2878  			if err != nil {
  2879  				t.Fatalf("Received unexpected error %s", err)
  2880  			} else {
  2881  				opts.NoLog = true
  2882  				srv := RunServer(opts)
  2883  				nc, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", opts.Port))
  2884  				if err != nil {
  2885  					t.Fatalf("couldn't connect %s", err)
  2886  				}
  2887  				nc.Close()
  2888  				srv.Shutdown()
  2889  			}
  2890  		})
  2891  	}
  2892  
  2893  	for _, badUser := range []string{"notthere", "UBAAQWTW6CG2G6ANGNKB5U2B7HRWHSGMZEZX3AQSAJOQDAUGJD46LD2F"} {
  2894  		t.Run(badUser, func(t *testing.T) {
  2895  			os.Setenv("NO_AUTH_USER", badUser)
  2896  			opts, err := ProcessConfigFile(confFileName)
  2897  			if err != nil {
  2898  				t.Fatalf("Received unexpected error %s", err)
  2899  			}
  2900  			s, err := NewServer(opts)
  2901  			if err != nil {
  2902  				if !strings.HasPrefix(err.Error(), "no_auth_user") {
  2903  					t.Fatalf("Received unexpected error %s", err)
  2904  				}
  2905  				return // error looks as expected
  2906  			}
  2907  			s.Shutdown()
  2908  			t.Fatalf("Received no error, where no_auth_user error was expected")
  2909  		})
  2910  	}
  2911  
  2912  }
  2913  
  2914  const operatorJwtWithSysAccAndUrlResolver = `
  2915  	listen: "127.0.0.1:-1"
  2916  	operator: eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJqdGkiOiJJVEdJNjNCUUszM1VNN1pBSzZWT1RXNUZEU01ESlNQU1pRQ0RMNUlLUzZQTVhBU0ROQ01RIiwiaWF0IjoxNTg5ODM5MjA1LCJpc3MiOiJPQ1k2REUyRVRTTjNVT0RGVFlFWEJaTFFMSTdYNEdTWFI1NE5aQzRCQkxJNlFDVFpVVDY1T0lWTiIsIm5hbWUiOiJPUCIsInN1YiI6Ik9DWTZERTJFVFNOM1VPREZUWUVYQlpMUUxJN1g0R1NYUjU0TlpDNEJCTEk2UUNUWlVUNjVPSVZOIiwidHlwZSI6Im9wZXJhdG9yIiwibmF0cyI6eyJhY2NvdW50X3NlcnZlcl91cmwiOiJodHRwOi8vbG9jYWxob3N0OjgwMDAvand0L3YxIiwib3BlcmF0b3Jfc2VydmljZV91cmxzIjpbIm5hdHM6Ly9sb2NhbGhvc3Q6NDIyMiJdLCJzeXN0ZW1fYWNjb3VudCI6IkFEWjU0N0IyNFdIUExXT0s3VE1MTkJTQTdGUUZYUjZVTTJOWjRISE5JQjdSREZWWlFGT1o0R1FRIn19.3u710KqMLwgXwsMvhxfEp9xzK84XyAZ-4dd6QY0T6hGj8Bw9mS-HcQ7HbvDDNU01S61tNFfpma_JR6LtB3ixBg
  2917  `
  2918  
  2919  func TestReadOperatorJWT(t *testing.T) {
  2920  	confFileName := createConfFile(t, []byte(operatorJwtWithSysAccAndUrlResolver))
  2921  	opts, err := ProcessConfigFile(confFileName)
  2922  	if err != nil {
  2923  		t.Fatalf("Received unexpected error %s", err)
  2924  	}
  2925  	if opts.SystemAccount != "ADZ547B24WHPLWOK7TMLNBSA7FQFXR6UM2NZ4HHNIB7RDFVZQFOZ4GQQ" {
  2926  		t.Fatalf("Expected different SystemAccount: %s", opts.SystemAccount)
  2927  	}
  2928  	if r, ok := opts.AccountResolver.(*URLAccResolver); !ok {
  2929  		t.Fatalf("Expected different SystemAccount: %s", opts.SystemAccount)
  2930  	} else if r.url != "http://localhost:8000/jwt/v1/accounts/" {
  2931  		t.Fatalf("Expected different SystemAccount: %s", r.url)
  2932  	}
  2933  }
  2934  
  2935  // using memory resolver so this test does not have to start the memory resolver
  2936  const operatorJwtWithSysAccAndMemResolver = `
  2937  	listen: "127.0.0.1:-1"
  2938  	// Operator "TESTOP"
  2939  	operator: eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJqdGkiOiJLRTZRU0tWTU1VWFFKNFZCTDNSNDdGRFlIWElaTDRZSE1INjVIT0k1UjZCNUpPUkxVQlZBIiwiaWF0IjoxNTg5OTE2MzgyLCJpc3MiOiJPQVRUVkJYTElVTVRRT1FXVUEySU0zRkdUQlFRSEFHUEZaQTVET05NTlFSUlRQUjYzTERBTDM1WiIsIm5hbWUiOiJURVNUT1AiLCJzdWIiOiJPQVRUVkJYTElVTVRRT1FXVUEySU0zRkdUQlFRSEFHUEZaQTVET05NTlFSUlRQUjYzTERBTDM1WiIsInR5cGUiOiJvcGVyYXRvciIsIm5hdHMiOnsic3lzdGVtX2FjY291bnQiOiJBRFNQT1lNSFhKTjZKVllRQ0xSWjVYUTVJVU42QTNTMzNYQTROVjRWSDc0NDIzVTdVN1lSNFlWVyJ9fQ.HiyUtlk8kectKHeQHtuqFcjFt0RbYZE_WAqPCcoWlV2IFVdXuOTzShYEMgDmtgvsFG_zxNQOj08Gr6a06ovwBA
  2940  	resolver: MEMORY
  2941  	resolver_preload: {
  2942    		// Account "TESTSYS"
  2943    		ADSPOYMHXJN6JVYQCLRZ5XQ5IUN6A3S33XA4NV4VH74423U7U7YR4YVW: eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJqdGkiOiI2WEtYUFZNTjdEVFlBSUE0R1JDWUxXUElSM1ZEM1Q2UVk2RFg3NURHTVFVWkdVWTJSRFNRIiwiaWF0IjoxNTg5OTE2MzIzLCJpc3MiOiJPQVRUVkJYTElVTVRRT1FXVUEySU0zRkdUQlFRSEFHUEZaQTVET05NTlFSUlRQUjYzTERBTDM1WiIsIm5hbWUiOiJURVNUU1lTIiwic3ViIjoiQURTUE9ZTUhYSk42SlZZUUNMUlo1WFE1SVVONkEzUzMzWEE0TlY0Vkg3NDQyM1U3VTdZUjRZVlciLCJ0eXBlIjoiYWNjb3VudCIsIm5hdHMiOnsibGltaXRzIjp7InN1YnMiOi0xLCJjb25uIjotMSwibGVhZiI6LTEsImltcG9ydHMiOi0xLCJleHBvcnRzIjotMSwiZGF0YSI6LTEsInBheWxvYWQiOi0xLCJ3aWxkY2FyZHMiOnRydWV9fX0.vhtWanIrOncdNfg-yO-7L61ccc-yRacvVtEsaIgWBEmW4czlEPhsiF1MkUKG91rtgcbwUf73ZIFEfja5MgFBAQ
  2944  	}
  2945  `
  2946  
  2947  func TestReadOperatorJWTSystemAccountMatch(t *testing.T) {
  2948  	confFileName := createConfFile(t, []byte(operatorJwtWithSysAccAndMemResolver+`
  2949  		system_account: ADSPOYMHXJN6JVYQCLRZ5XQ5IUN6A3S33XA4NV4VH74423U7U7YR4YVW
  2950  	`))
  2951  	opts, err := ProcessConfigFile(confFileName)
  2952  	if err != nil {
  2953  		t.Fatalf("Received unexpected error %s", err)
  2954  	}
  2955  	s, err := NewServer(opts)
  2956  	if err != nil {
  2957  		t.Fatalf("Received unexpected error %s", err)
  2958  	}
  2959  	s.Shutdown()
  2960  }
  2961  
  2962  func TestReadOperatorJWTSystemAccountMismatch(t *testing.T) {
  2963  	confFileName := createConfFile(t, []byte(operatorJwtWithSysAccAndMemResolver+`
  2964  		system_account: ADXJJCDCSRSMCOV25FXQW7R4QOG7R763TVEXBNWJHLBMBGWOJYG5XZBG
  2965  	`))
  2966  	opts, err := ProcessConfigFile(confFileName)
  2967  	if err != nil {
  2968  		t.Fatalf("Received unexpected error %s", err)
  2969  	}
  2970  	s, err := NewServer(opts)
  2971  	if err == nil {
  2972  		s.Shutdown()
  2973  		t.Fatalf("Received no error")
  2974  	} else if !strings.Contains(err.Error(), "system_account in config and operator JWT must be identical") {
  2975  		t.Fatalf("Received unexpected error %s", err)
  2976  	}
  2977  }
  2978  
  2979  func TestReadOperatorAssertVersion(t *testing.T) {
  2980  	kp, _ := nkeys.CreateOperator()
  2981  	pk, _ := kp.PublicKey()
  2982  	op := jwt.NewOperatorClaims(pk)
  2983  	op.AssertServerVersion = "1.2.3"
  2984  	jwt, err := op.Encode(kp)
  2985  	if err != nil {
  2986  		t.Fatalf("Received unexpected error %s", err)
  2987  	}
  2988  	confFileName := createConfFile(t, []byte(fmt.Sprintf(`
  2989  		operator: %s
  2990  		resolver: MEM
  2991  	`, jwt)))
  2992  	opts, err := ProcessConfigFile(confFileName)
  2993  	if err != nil {
  2994  		t.Fatalf("Received unexpected error %s", err)
  2995  	}
  2996  	s, err := NewServer(opts)
  2997  	if err != nil {
  2998  		t.Fatalf("Received unexpected error %s", err)
  2999  	}
  3000  	s.Shutdown()
  3001  }
  3002  
  3003  func TestReadOperatorAssertVersionFail(t *testing.T) {
  3004  	kp, _ := nkeys.CreateOperator()
  3005  	pk, _ := kp.PublicKey()
  3006  	op := jwt.NewOperatorClaims(pk)
  3007  	op.AssertServerVersion = "10.20.30"
  3008  	jwt, err := op.Encode(kp)
  3009  	if err != nil {
  3010  		t.Fatalf("Received unexpected error %s", err)
  3011  	}
  3012  	confFileName := createConfFile(t, []byte(fmt.Sprintf(`
  3013  		operator: %s
  3014  		resolver: MEM
  3015  	`, jwt)))
  3016  	opts, err := ProcessConfigFile(confFileName)
  3017  	if err != nil {
  3018  		t.Fatalf("Received unexpected error %s", err)
  3019  	}
  3020  	s, err := NewServer(opts)
  3021  	if err == nil {
  3022  		s.Shutdown()
  3023  		t.Fatalf("Received no error")
  3024  	} else if !strings.Contains(err.Error(), "expected major version 10 > server major version") {
  3025  		t.Fatal("expected different error got: ", err)
  3026  	}
  3027  }
  3028  
  3029  func TestClusterNameAndGatewayNameConflict(t *testing.T) {
  3030  	conf := createConfFile(t, []byte(`
  3031  		listen: 127.0.0.1:-1
  3032  		cluster {
  3033  			name: A
  3034  			listen: 127.0.0.1:-1
  3035  		}
  3036  		gateway {
  3037  			name: B
  3038  			listen: 127.0.0.1:-1
  3039  		}
  3040  	`))
  3041  
  3042  	opts, err := ProcessConfigFile(conf)
  3043  	if err != nil {
  3044  		t.Fatalf("Unexpected error: %v", err)
  3045  	}
  3046  
  3047  	if err := validateOptions(opts); err != ErrClusterNameConfigConflict {
  3048  		t.Fatalf("Expected ErrClusterNameConfigConflict got %v", err)
  3049  	}
  3050  }
  3051  
  3052  func TestDefaultAuthTimeout(t *testing.T) {
  3053  	opts := DefaultOptions()
  3054  	opts.AuthTimeout = 0
  3055  	s := RunServer(opts)
  3056  	defer s.Shutdown()
  3057  
  3058  	sopts := s.getOpts()
  3059  	if at := time.Duration(sopts.AuthTimeout * float64(time.Second)); at != AUTH_TIMEOUT {
  3060  		t.Fatalf("Expected auth timeout to be %v, got %v", AUTH_TIMEOUT, at)
  3061  	}
  3062  	s.Shutdown()
  3063  
  3064  	opts = DefaultOptions()
  3065  	tc := &TLSConfigOpts{
  3066  		CertFile: "../test/configs/certs/server-cert.pem",
  3067  		KeyFile:  "../test/configs/certs/server-key.pem",
  3068  		CaFile:   "../test/configs/certs/ca.pem",
  3069  		Timeout:  4.0,
  3070  	}
  3071  	tlsConfig, err := GenTLSConfig(tc)
  3072  	if err != nil {
  3073  		t.Fatalf("Error generating tls config: %v", err)
  3074  	}
  3075  	opts.TLSConfig = tlsConfig
  3076  	opts.TLSTimeout = tc.Timeout
  3077  	s = RunServer(opts)
  3078  	defer s.Shutdown()
  3079  
  3080  	sopts = s.getOpts()
  3081  	if sopts.AuthTimeout != 5 {
  3082  		t.Fatalf("Expected auth timeout to be %v, got %v", 5, sopts.AuthTimeout)
  3083  	}
  3084  }
  3085  
  3086  func TestQueuePermissions(t *testing.T) {
  3087  	cfgFmt := `
  3088  		listen: 127.0.0.1:-1
  3089  		no_auth_user: u
  3090  		authorization {
  3091  			users [{
  3092  				user: u, password: pwd, permissions: { sub: { %s: ["foo.> *.dev"] } }
  3093  			}]
  3094  		}`
  3095  	errChan := make(chan error, 1)
  3096  	defer close(errChan)
  3097  	for _, test := range []struct {
  3098  		permType    string
  3099  		queue       string
  3100  		errExpected bool
  3101  	}{
  3102  		{"allow", "queue.dev", false},
  3103  		{"allow", "", true},
  3104  		{"allow", "bad", true},
  3105  		{"deny", "", false},
  3106  		{"deny", "queue.dev", true},
  3107  	} {
  3108  		t.Run(test.permType+test.queue, func(t *testing.T) {
  3109  			confFileName := createConfFile(t, []byte(fmt.Sprintf(cfgFmt, test.permType)))
  3110  			opts, err := ProcessConfigFile(confFileName)
  3111  			if err != nil {
  3112  				t.Fatalf("Received unexpected error %s", err)
  3113  			}
  3114  			opts.NoLog, opts.NoSigs = true, true
  3115  			s := RunServer(opts)
  3116  			defer s.Shutdown()
  3117  			nc, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", opts.Port),
  3118  				nats.ErrorHandler(func(conn *nats.Conn, s *nats.Subscription, err error) {
  3119  					errChan <- err
  3120  				}))
  3121  			if err != nil {
  3122  				t.Fatalf("No error expected: %v", err)
  3123  			}
  3124  			defer nc.Close()
  3125  			if test.queue == "" {
  3126  				if _, err := nc.Subscribe("foo.bar", func(msg *nats.Msg) {}); err != nil {
  3127  					t.Fatalf("no error expected: %v", err)
  3128  				}
  3129  			} else {
  3130  				if _, err := nc.QueueSubscribe("foo.bar", test.queue, func(msg *nats.Msg) {}); err != nil {
  3131  					t.Fatalf("no error expected: %v", err)
  3132  				}
  3133  			}
  3134  			nc.Flush()
  3135  			select {
  3136  			case err := <-errChan:
  3137  				if !test.errExpected {
  3138  					t.Fatalf("Expected no error, got %v", err)
  3139  				}
  3140  				if !strings.Contains(err.Error(), `Permissions Violation for Subscription to "foo.bar"`) {
  3141  					t.Fatalf("error %v", err)
  3142  				}
  3143  			case <-time.After(150 * time.Millisecond):
  3144  				if test.errExpected {
  3145  					t.Fatal("Expected an error")
  3146  				}
  3147  			}
  3148  		})
  3149  
  3150  	}
  3151  }
  3152  
  3153  func TestResolverPinnedAccountsFail(t *testing.T) {
  3154  	cfgFmt := `
  3155  		operator: %s
  3156  		resolver: URL(foo.bar)
  3157  		resolver_pinned_accounts: [%s]
  3158  	`
  3159  
  3160  	conf := createConfFile(t, []byte(fmt.Sprintf(cfgFmt, ojwt, "f")))
  3161  	srv, err := NewServer(LoadConfig(conf))
  3162  	defer srv.Shutdown()
  3163  	require_Error(t, err)
  3164  	require_Contains(t, err.Error(), " is not a valid public account nkey")
  3165  
  3166  	conf = createConfFile(t, []byte(fmt.Sprintf(cfgFmt, ojwt, "1, x")))
  3167  	_, err = ProcessConfigFile(conf)
  3168  	require_Error(t, err)
  3169  	require_Contains(t, "parsing resolver_pinned_accounts: unsupported type")
  3170  }
  3171  
  3172  func TestMaxSubTokens(t *testing.T) {
  3173  	conf := createConfFile(t, []byte(`
  3174  		listen: 127.0.0.1:-1
  3175  		max_sub_tokens: 4
  3176  	`))
  3177  
  3178  	s, _ := RunServerWithConfig(conf)
  3179  	defer s.Shutdown()
  3180  
  3181  	nc, err := nats.Connect(s.ClientURL())
  3182  	require_NoError(t, err)
  3183  	defer nc.Close()
  3184  
  3185  	errs := make(chan error, 1)
  3186  
  3187  	nc.SetErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) {
  3188  		errs <- err
  3189  	})
  3190  
  3191  	bad := "a.b.c.d.e"
  3192  	_, err = nc.SubscribeSync(bad)
  3193  	require_NoError(t, err)
  3194  
  3195  	select {
  3196  	case e := <-errs:
  3197  		if !strings.Contains(e.Error(), "too many tokens") {
  3198  			t.Fatalf("Got wrong error: %v", err)
  3199  		}
  3200  	case <-time.After(2 * time.Second):
  3201  		t.Fatal("Did not get the permissions error")
  3202  	}
  3203  }
  3204  
  3205  func TestGetStorageSize(t *testing.T) {
  3206  	tt := []struct {
  3207  		input string
  3208  		want  int64
  3209  		err   bool
  3210  	}{
  3211  		{"1K", 1024, false},
  3212  		{"1M", 1048576, false},
  3213  		{"1G", 1073741824, false},
  3214  		{"1T", 1099511627776, false},
  3215  		{"1L", 0, true},
  3216  		{"TT", 0, true},
  3217  		{"", 0, false},
  3218  	}
  3219  
  3220  	for _, v := range tt {
  3221  		var testErr bool
  3222  		got, err := getStorageSize(v.input)
  3223  		if err != nil {
  3224  			testErr = true
  3225  		}
  3226  
  3227  		if got != v.want || v.err != testErr {
  3228  			t.Errorf("Got: %v, want %v with error: %v", got, v.want, testErr)
  3229  		}
  3230  	}
  3231  
  3232  }
  3233  
  3234  func TestAuthorizationAndAccountsMisconfigurations(t *testing.T) {
  3235  	// There is a test called TestConfigCheck but we can't use it
  3236  	// because the place where the error will be reported will depend
  3237  	// if the error is found while parsing authorization{} or
  3238  	// accounts{}, but we can't control the internal parsing of those
  3239  	// (due to lexer giving back a map and iteration over map is random)
  3240  	// regardless of the ordering in the configuration file.
  3241  	// The test is also repeated
  3242  	for _, test := range []struct {
  3243  		name   string
  3244  		config string
  3245  		err    string
  3246  	}{
  3247  		{
  3248  			"duplicate users",
  3249  			`
  3250  			authorization = {users = [ {user: "user1", pass: "pwd"} ] }
  3251  			accounts { ACC { users = [ {user: "user1"} ] } }
  3252  			`,
  3253  			fmt.Sprintf("Duplicate user %q detected", "user1"),
  3254  		},
  3255  		{
  3256  			"duplicate nkey",
  3257  			`
  3258  			authorization = {users = [ {nkey: UC6NLCN7AS34YOJVCYD4PJ3QB7QGLYG5B5IMBT25VW5K4TNUJODM7BOX} ] }
  3259  			accounts { ACC { users = [ {nkey: UC6NLCN7AS34YOJVCYD4PJ3QB7QGLYG5B5IMBT25VW5K4TNUJODM7BOX} ] } }
  3260  			`,
  3261  			fmt.Sprintf("Duplicate nkey %q detected", "UC6NLCN7AS34YOJVCYD4PJ3QB7QGLYG5B5IMBT25VW5K4TNUJODM7BOX"),
  3262  		},
  3263  		{
  3264  			"auth single user and password and accounts users",
  3265  			`
  3266  			authorization = {user: "user1", password: "pwd"}
  3267  			accounts = { ACC { users = [ {user: "user2", pass: "pwd"} ] } }
  3268  			`,
  3269  			"Can not have a single user/pass",
  3270  		},
  3271  		{
  3272  			"auth single user and password and accounts nkeys",
  3273  			`
  3274  			authorization = {user: "user1", password: "pwd"}
  3275  			accounts = { ACC { users = [ {nkey: UC6NLCN7AS34YOJVCYD4PJ3QB7QGLYG5B5IMBT25VW5K4TNUJODM7BOX} ] } }
  3276  			`,
  3277  			"Can not have a single user/pass",
  3278  		},
  3279  		{
  3280  			"auth token and accounts users",
  3281  			`
  3282  			authorization = {token: "my_token"}
  3283  			accounts = { ACC { users = [ {user: "user2", pass: "pwd"} ] } }
  3284  			`,
  3285  			"Can not have a token",
  3286  		},
  3287  		{
  3288  			"auth token and accounts nkeys",
  3289  			`
  3290  			authorization = {token: "my_token"}
  3291  			accounts = { ACC { users = [ {nkey: UC6NLCN7AS34YOJVCYD4PJ3QB7QGLYG5B5IMBT25VW5K4TNUJODM7BOX} ] } }
  3292  			`,
  3293  			"Can not have a token",
  3294  		},
  3295  	} {
  3296  		t.Run(test.name, func(t *testing.T) {
  3297  			conf := createConfFile(t, []byte(test.config))
  3298  			if _, err := ProcessConfigFile(conf); err == nil || !strings.Contains(err.Error(), test.err) {
  3299  				t.Fatalf("Expected error %q, got %q", test.err, err.Error())
  3300  			}
  3301  		})
  3302  	}
  3303  }