info_windows_test.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. //go:build windows
  2. package localapi
  3. import (
  4. "context"
  5. "io"
  6. "net"
  7. "net/http"
  8. "testing"
  9. "time"
  10. "github.com/Microsoft/go-winio"
  11. "github.com/slackhq/nebula/commands"
  12. "github.com/slackhq/nebula/test"
  13. "github.com/stretchr/testify/assert"
  14. "github.com/stretchr/testify/require"
  15. "golang.org/x/sys/windows"
  16. )
  17. // TestInfoIsServedOnAPipe: the info API serves HTTP on a named pipe, whose security
  18. // descriptor is its access control the way a socket's mode is on unix; a group named
  19. // in the config is admitted by it.
  20. func TestInfoIsServedOnAPipe(t *testing.T) {
  21. users, err := windows.CreateWellKnownSid(windows.WinBuiltinUsersSid)
  22. require.NoError(t, err)
  23. group := &Group{Name: "Users", ID: users.String()}
  24. s := NewInfoServer(test.NewLogger(), commands.New())
  25. path := pipePrefix + "nebula-info-test"
  26. require.NoError(t, s.Rebind(context.Background(), path, Access{Mode: groupSocketMode, Group: group}))
  27. t.Cleanup(s.Stop)
  28. assert.Equal(t, path, s.Path())
  29. client := &http.Client{Transport: &http.Transport{
  30. DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
  31. timeout := 2 * time.Second
  32. return winio.DialPipe(path, &timeout)
  33. },
  34. }}
  35. res, err := client.Get("http://nebula/v1")
  36. require.NoError(t, err)
  37. defer res.Body.Close()
  38. body, err := io.ReadAll(res.Body)
  39. require.NoError(t, err)
  40. assert.Equal(t, http.StatusOK, res.StatusCode)
  41. assert.Contains(t, string(body), `"help"`)
  42. // A change of group means a new pipe under the same name, still serving.
  43. require.NoError(t, s.Rebind(context.Background(), path, Access{Mode: groupSocketMode}))
  44. res, err = client.Get("http://nebula/v1")
  45. require.NoError(t, err)
  46. res.Body.Close()
  47. assert.Equal(t, http.StatusOK, res.StatusCode)
  48. }