zerotier.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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: 2025-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 authToken(basePath, tflag, tTflag string) string {
  27. var authToken string
  28. if len(tflag) > 0 {
  29. at, err := ioutil.ReadFile(tflag)
  30. if err != nil || len(at) == 0 {
  31. fmt.Println("FATAL: unable to read local service API authorization token from " + tflag)
  32. return ""
  33. }
  34. authToken = string(at)
  35. } else if len(tTflag) > 0 {
  36. authToken = tTflag
  37. } else {
  38. var authTokenPaths []string
  39. authTokenPaths = append(authTokenPaths, path.Join(basePath, "authtoken.secret"))
  40. userHome, _ := os.UserHomeDir()
  41. if len(userHome) > 0 {
  42. if runtime.GOOS == "darwin" {
  43. authTokenPaths = append(authTokenPaths, path.Join(userHome, "Library", "Application Support", "ZeroTier", "authtoken.secret"))
  44. authTokenPaths = append(authTokenPaths, path.Join(userHome, "Library", "Application Support", "ZeroTier", "One", "authtoken.secret"))
  45. }
  46. authTokenPaths = append(authTokenPaths, path.Join(userHome, ".zerotierauth"))
  47. authTokenPaths = append(authTokenPaths, path.Join(userHome, ".zeroTierOneAuthToken"))
  48. }
  49. for _, p := range authTokenPaths {
  50. tmp, _ := ioutil.ReadFile(p)
  51. if len(tmp) > 0 {
  52. authToken = string(tmp)
  53. break
  54. }
  55. }
  56. if len(authToken) == 0 {
  57. fmt.Println("FATAL: unable to read local service API authorization token from any of:")
  58. for _, p := range authTokenPaths {
  59. fmt.Println(" " + p)
  60. }
  61. return ""
  62. }
  63. }
  64. authToken = strings.TrimSpace(authToken)
  65. if len(authToken) == 0 {
  66. fmt.Println("FATAL: unable to read API authorization token from command line or any filesystem location.")
  67. return ""
  68. }
  69. return authToken
  70. }
  71. func main() {
  72. // Reduce Go's thread and memory footprint. This would slow things down if the Go code
  73. // were doing a lot, but it's not. It just manages the core and is not directly involved
  74. // in pushing a lot of packets around. If that ever changes this should be adjusted.
  75. if runtime.NumCPU() > 1 {
  76. runtime.GOMAXPROCS(2)
  77. } else {
  78. runtime.GOMAXPROCS(1)
  79. }
  80. debug.SetGCPercent(10)
  81. globalOpts := flag.NewFlagSet("global", flag.ContinueOnError)
  82. hflag := globalOpts.Bool("h", false, "") // support -h to be canonical with other Unix utilities
  83. jflag := globalOpts.Bool("j", false, "")
  84. pflag := globalOpts.String("p", "", "")
  85. tflag := globalOpts.String("t", "", "")
  86. tTflag := globalOpts.String("T", "", "")
  87. err := globalOpts.Parse(os.Args[1:])
  88. if err != nil {
  89. cli.Help()
  90. os.Exit(1)
  91. return
  92. }
  93. args := globalOpts.Args()
  94. if len(args) < 1 || *hflag {
  95. cli.Help()
  96. os.Exit(0)
  97. return
  98. }
  99. var cmdArgs []string
  100. if len(args) > 1 {
  101. cmdArgs = args[1:]
  102. }
  103. basePath := zerotier.PlatformDefaultHomePath
  104. if len(*pflag) > 0 {
  105. basePath = *pflag
  106. }
  107. exitCode := 0
  108. switch args[0] {
  109. default:
  110. cli.Help()
  111. exitCode = 1
  112. case "help":
  113. cli.Help()
  114. case "version":
  115. fmt.Printf("%d.%d.%d\n", zerotier.CoreVersionMajor, zerotier.CoreVersionMinor, zerotier.CoreVersionRevision)
  116. case "service":
  117. exitCode = cli.Service(basePath, cmdArgs)
  118. case "status", "info":
  119. exitCode = cli.Status(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs, *jflag)
  120. case "join":
  121. exitCode = cli.Join(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs)
  122. case "leave":
  123. exitCode = cli.Leave(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs)
  124. case "networks", "listnetworks":
  125. exitCode = cli.Networks(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs, *jflag)
  126. case "network":
  127. exitCode = cli.Network(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs, *jflag)
  128. case "peers", "listpeers", "lspeers":
  129. exitCode = cli.Peers(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs, *jflag, false)
  130. case "peer":
  131. case "roots":
  132. exitCode = cli.Peers(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs, *jflag, true)
  133. case "controller":
  134. case "set":
  135. exitCode = cli.Set(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs)
  136. case "identity":
  137. exitCode = cli.Identity(cmdArgs)
  138. case "locator":
  139. exitCode = cli.Locator(cmdArgs)
  140. case "certs", "listcerts", "lscerts": // same as "cert show" with no specific serial to show
  141. exitCode = cli.Cert(basePath, authToken(basePath, *tflag, *tTflag), []string{"show"}, *jflag)
  142. case "cert":
  143. exitCode = cli.Cert(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs, *jflag)
  144. }
  145. os.Exit(exitCode)
  146. }