zerotier.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (c)2013-2020 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2024-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. package main
  14. import (
  15. "flag"
  16. "fmt"
  17. "io/ioutil"
  18. "os"
  19. "path"
  20. "runtime"
  21. "runtime/debug"
  22. "strings"
  23. "zerotier/cmd/zerotier/cli"
  24. "zerotier/pkg/zerotier"
  25. )
  26. func getAuthTokenPaths(basePath string) (p []string) {
  27. p = append(p,path.Join(basePath,"authtoken.secret"))
  28. userHome, _ := os.UserHomeDir()
  29. if len(userHome) > 0 {
  30. if runtime.GOOS == "darwin" {
  31. p = append(p,path.Join(userHome,"Library","Application Support","ZeroTier","authtoken.secret"))
  32. p = append(p,path.Join(userHome,"Library","Application Support","ZeroTier","One","authtoken.secret"))
  33. }
  34. p = append(p,path.Join(userHome,".zerotierauth"))
  35. p = append(p,path.Join(userHome,".zeroTierOneAuthToken"))
  36. }
  37. return p
  38. }
  39. func authTokenRequired(authToken string) {
  40. if len(authToken) == 0 {
  41. fmt.Println("FATAL: unable to read API authorization token from command line or any filesystem location.")
  42. os.Exit(1)
  43. }
  44. }
  45. func main() {
  46. // Reduce Go's thread and memory footprint. This would slow things down if the Go code
  47. // were doing a lot, but it's not. It just manages the core and is not directly involved
  48. // in pushing a lot of packets around. If that ever changes this should be adjusted.
  49. runtime.GOMAXPROCS(1)
  50. debug.SetGCPercent(20)
  51. globalOpts := flag.NewFlagSet("global", flag.ContinueOnError)
  52. hflag := globalOpts.Bool("h", false, "") // support -h to be canonical with other Unix utilities
  53. jflag := globalOpts.Bool("j", false, "")
  54. pflag := globalOpts.String("p", "", "")
  55. tflag := globalOpts.String("t", "", "")
  56. tTflag := globalOpts.String("T", "", "")
  57. err := globalOpts.Parse(os.Args[1:])
  58. if err != nil {
  59. cli.Help()
  60. os.Exit(1)
  61. return
  62. }
  63. args := globalOpts.Args()
  64. if len(args) < 1 || *hflag {
  65. cli.Help()
  66. os.Exit(0)
  67. return
  68. }
  69. var cmdArgs []string
  70. if len(args) > 1 {
  71. cmdArgs = args[1:]
  72. }
  73. basePath := zerotier.PlatformDefaultHomePath
  74. if len(*pflag) > 0 {
  75. basePath = *pflag
  76. }
  77. authTokenPaths := getAuthTokenPaths(basePath)
  78. var authToken string
  79. if len(*tflag) > 0 {
  80. at, err := ioutil.ReadFile(*tflag)
  81. if err != nil || len(at) == 0 {
  82. fmt.Println("FATAL: unable to read local service API authorization token from " + *tflag)
  83. os.Exit(1)
  84. }
  85. authToken = string(at)
  86. } else if len(*tTflag) > 0 {
  87. authToken = *tTflag
  88. } else {
  89. for _, p := range authTokenPaths {
  90. tmp, _ := ioutil.ReadFile(p)
  91. if len(tmp) > 0 {
  92. authToken = string(tmp)
  93. break;
  94. }
  95. }
  96. if len(authToken) == 0 {
  97. fmt.Println("FATAL: unable to read local service API authorization token from any of:")
  98. for _, p := range authTokenPaths {
  99. fmt.Println(" " + p)
  100. }
  101. os.Exit(1)
  102. }
  103. }
  104. authToken = strings.TrimSpace(authToken)
  105. switch args[0] {
  106. case "help":
  107. cli.Help()
  108. os.Exit(0)
  109. case "version":
  110. fmt.Printf("%d.%d.%d\n", zerotier.CoreVersionMajor, zerotier.CoreVersionMinor, zerotier.CoreVersionRevision)
  111. os.Exit(0)
  112. case "service":
  113. cli.Service(basePath, authToken, cmdArgs)
  114. case "status", "info":
  115. authTokenRequired(authToken)
  116. cli.Status(basePath, authToken, cmdArgs, *jflag)
  117. case "join":
  118. authTokenRequired(authToken)
  119. cli.Join(basePath, authToken, cmdArgs)
  120. case "leave":
  121. authTokenRequired(authToken)
  122. cli.Leave(basePath, authToken, cmdArgs)
  123. case "networks", "listnetworks":
  124. authTokenRequired(authToken)
  125. cli.Networks(basePath, authToken, cmdArgs, *jflag)
  126. case "network":
  127. authTokenRequired(authToken)
  128. cli.Network(basePath, authToken, cmdArgs, *jflag)
  129. case "peers", "listpeers", "lspeers":
  130. authTokenRequired(authToken)
  131. cli.Peers(basePath, authToken, cmdArgs, *jflag, false)
  132. case "peer":
  133. authTokenRequired(authToken)
  134. case "roots":
  135. authTokenRequired(authToken)
  136. cli.Peers(basePath, authToken, cmdArgs, *jflag, true)
  137. case "root":
  138. authTokenRequired(authToken)
  139. cli.Root(basePath, authToken, cmdArgs, *jflag)
  140. case "set":
  141. authTokenRequired(authToken)
  142. cli.Set(basePath, authToken, cmdArgs)
  143. case "controller":
  144. authTokenRequired(authToken)
  145. cli.Controller(basePath, authToken, cmdArgs, *jflag)
  146. case "identity":
  147. cli.Identity(cmdArgs)
  148. }
  149. // Commands in the 'cli' sub-package do not return, so if we make
  150. // it here the command was not recognized.
  151. cli.Help()
  152. os.Exit(1)
  153. }