mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 12:33:44 +02:00
Certificate plumbing in Go.
This commit is contained in:
parent
825b19aedc
commit
81530e5990
16 changed files with 202 additions and 100 deletions
|
@ -222,7 +222,7 @@ if(NOT PACKAGE_STATIC)
|
||||||
CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64"
|
CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64"
|
||||||
)
|
)
|
||||||
message("++ Adding flags for processor ${CMAKE_SYSTEM_PROCESSOR}")
|
message("++ Adding flags for processor ${CMAKE_SYSTEM_PROCESSOR}")
|
||||||
add_compile_options(-maes -mrdrnd -mpclmul -msse -msse2 -mssse3)
|
add_compile_options(-maes -mrdrnd -mpclmul -msse -msse2 -mssse3 -msse4)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(GO_BUILD_TAGS)
|
set(GO_BUILD_TAGS)
|
||||||
|
|
|
@ -13,5 +13,101 @@
|
||||||
|
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
func Cert(basePath, authToken string, args []string, jsonOutput bool) {
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"zerotier/pkg/zerotier"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func Cert(basePath, authToken string, args []string, jsonOutput bool) int {
|
||||||
|
if len(args) < 1 {
|
||||||
|
Help()
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
switch args[0] {
|
||||||
|
|
||||||
|
case "newsid":
|
||||||
|
if len(args) > 2 {
|
||||||
|
Help()
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
uniqueId, uniqueIdPrivate, err := zerotier.NewCertificateSubjectUniqueId(zerotier.CertificateUniqueIdTypeNistP384)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR: unable to create unique ID and private key: %s\n", err.Error())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
sec, err := json.MarshalIndent(&zerotier.CertificateSubjectUniqueIDSecret{UniqueID: uniqueId, UniqueIDSecret: uniqueIdPrivate}, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR: unable to create unique ID and private key: %s\n", err.Error())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if len(args) == 1 {
|
||||||
|
fmt.Println(string(sec))
|
||||||
|
} else {
|
||||||
|
_ = ioutil.WriteFile(args[1], sec, 0600)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "newcsr":
|
||||||
|
if len(args) < 3 {
|
||||||
|
Help()
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
var cs zerotier.CertificateSubject
|
||||||
|
csb, err := ioutil.ReadFile(args[1])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR: unable to read subject from %s: %s\n", args[1], err.Error())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(csb, &cs)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR: unable to read subject from %s: %s\n", args[1], err.Error())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
var subj zerotier.CertificateSubjectUniqueIDSecret
|
||||||
|
subjb, err := ioutil.ReadFile(args[2])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR: unable to read unique ID secret from %s: %s\n", args[2], err.Error())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(subjb, &subj)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR: unable to read unique ID secret from %s: %s\n", args[2], err.Error())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
csr, err := zerotier.NewCertificateCSR(&cs, subj.UniqueID, subj.UniqueIDSecret)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR: problem creating CSR: %s\n", err.Error())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if len(args) == 3 {
|
||||||
|
_, _ = os.Stdout.Write(csr)
|
||||||
|
} else {
|
||||||
|
_ = ioutil.WriteFile(args[3], csr, 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "sign":
|
||||||
|
|
||||||
|
case "verify":
|
||||||
|
|
||||||
|
case "show":
|
||||||
|
if len(args) != 1 {
|
||||||
|
Help()
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
case "import":
|
||||||
|
|
||||||
|
case "restore":
|
||||||
|
|
||||||
|
case "export":
|
||||||
|
|
||||||
|
case "delete":
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,14 +76,14 @@ Commands:
|
||||||
sign <identity> <file> Sign a file with an identity's key
|
sign <identity> <file> Sign a file with an identity's key
|
||||||
verify <identity> <file> <sig> Verify a signature
|
verify <identity> <file> <sig> Verify a signature
|
||||||
cert <command> [args] - Certificate commands
|
cert <command> [args] - Certificate commands
|
||||||
newsubject <subject> <secret> Create a new subject and secret
|
newsid [secret] Create a new subject unique ID
|
||||||
newcsr <subject> <secret> Create a subject CSR
|
newcsr <subject> <secret> [csr] Create a subject CSR
|
||||||
sign <csr> <identity> <certificate> Sign a CSR to create a certificate
|
sign <csr> <identity> [certificate] Sign a CSR to create a certificate
|
||||||
verify <certificate> Verify a certificate
|
verify <certificate> Verify a certificate
|
||||||
show List certificate for current node
|
|
||||||
import <certificate> [<trust>] Import certificate into this node
|
import <certificate> [<trust>] Import certificate into this node
|
||||||
export <serial> Export a certificate from this node
|
restore Re-import default certificates
|
||||||
delete <serial> Delete certificate from this node
|
export <serial> [path] Export a certificate from this node
|
||||||
|
delete <serial|ALL> Delete certificate from this node
|
||||||
|
|
||||||
An <address> may be specified as a 10-digit short ZeroTier address, a
|
An <address> may be specified as a 10-digit short ZeroTier address, a
|
||||||
fingerprint containing both an address and a SHA384 hash, or an identity.
|
fingerprint containing both an address and a SHA384 hash, or an identity.
|
||||||
|
|
|
@ -17,13 +17,12 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"zerotier/pkg/zerotier"
|
"zerotier/pkg/zerotier"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Identity(args []string) {
|
func Identity(args []string) int {
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
switch args[0] {
|
switch args[0] {
|
||||||
|
|
||||||
|
@ -32,7 +31,7 @@ func Identity(args []string) {
|
||||||
if len(args) > 1 {
|
if len(args) > 1 {
|
||||||
if len(args) > 2 {
|
if len(args) > 2 {
|
||||||
Help()
|
Help()
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
switch args[1] {
|
switch args[1] {
|
||||||
case "c25519", "C25519", "0":
|
case "c25519", "C25519", "0":
|
||||||
|
@ -41,37 +40,37 @@ func Identity(args []string) {
|
||||||
idType = zerotier.IdentityTypeP384
|
idType = zerotier.IdentityTypeP384
|
||||||
default:
|
default:
|
||||||
Help()
|
Help()
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id, err := zerotier.NewIdentity(idType)
|
id, err := zerotier.NewIdentity(idType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: internal error generating identity: %s\n", err.Error())
|
fmt.Printf("ERROR: internal error generating identity: %s\n", err.Error())
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
fmt.Println(id.PrivateKeyString())
|
fmt.Println(id.PrivateKeyString())
|
||||||
os.Exit(0)
|
return 0
|
||||||
|
|
||||||
case "getpublic":
|
case "getpublic":
|
||||||
if len(args) == 2 {
|
if len(args) == 2 {
|
||||||
fmt.Println(readIdentity(args[1]).String())
|
fmt.Println(readIdentity(args[1]).String())
|
||||||
os.Exit(0)
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
case "fingerprint":
|
case "fingerprint":
|
||||||
if len(args) == 2 {
|
if len(args) == 2 {
|
||||||
fmt.Println(readIdentity(args[1]).Fingerprint().String())
|
fmt.Println(readIdentity(args[1]).Fingerprint().String())
|
||||||
os.Exit(0)
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
case "validate":
|
case "validate":
|
||||||
if len(args) == 2 {
|
if len(args) == 2 {
|
||||||
if readIdentity(args[1]).LocallyValidate() {
|
if readIdentity(args[1]).LocallyValidate() {
|
||||||
fmt.Println("OK")
|
fmt.Println("OK")
|
||||||
os.Exit(0)
|
return 0
|
||||||
}
|
}
|
||||||
fmt.Println("FAILED")
|
fmt.Println("FAILED")
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
case "sign", "verify":
|
case "sign", "verify":
|
||||||
|
@ -80,7 +79,7 @@ func Identity(args []string) {
|
||||||
msg, err := ioutil.ReadFile(args[2])
|
msg, err := ioutil.ReadFile(args[2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: unable to read input file: %s\n", err.Error())
|
fmt.Printf("ERROR: unable to read input file: %s\n", err.Error())
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if args[0] == "verify" {
|
if args[0] == "verify" {
|
||||||
|
@ -88,28 +87,29 @@ func Identity(args []string) {
|
||||||
sig, err := hex.DecodeString(strings.TrimSpace(args[3]))
|
sig, err := hex.DecodeString(strings.TrimSpace(args[3]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("FAILED")
|
fmt.Println("FAILED")
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
if id.Verify(msg, sig) {
|
if id.Verify(msg, sig) {
|
||||||
fmt.Println("OK")
|
fmt.Println("OK")
|
||||||
os.Exit(0)
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("FAILED")
|
fmt.Println("FAILED")
|
||||||
os.Exit(1)
|
return 1
|
||||||
} else {
|
} else {
|
||||||
sig, err := id.Sign(msg)
|
sig, err := id.Sign(msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: internal error signing message: %s\n", err.Error())
|
fmt.Printf("ERROR: internal error signing message: %s\n", err.Error())
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
fmt.Println(hex.EncodeToString(sig))
|
fmt.Println(hex.EncodeToString(sig))
|
||||||
os.Exit(0)
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Help()
|
Help()
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,25 +23,23 @@ import (
|
||||||
"zerotier/pkg/zerotier"
|
"zerotier/pkg/zerotier"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Join(basePath, authToken string, args []string) {
|
func Join(basePath, authToken string, args []string) int {
|
||||||
joinOpts := flag.NewFlagSet("join", flag.ContinueOnError)
|
joinOpts := flag.NewFlagSet("join", flag.ContinueOnError)
|
||||||
controllerAuthToken := joinOpts.String("a", "", "")
|
controllerAuthToken := joinOpts.String("a", "", "")
|
||||||
controllerFingerprint := joinOpts.String("c", "", "")
|
controllerFingerprint := joinOpts.String("c", "", "")
|
||||||
err := joinOpts.Parse(os.Args[1:])
|
err := joinOpts.Parse(os.Args[1:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Help()
|
Help()
|
||||||
os.Exit(1)
|
return 1
|
||||||
return
|
|
||||||
}
|
}
|
||||||
args = joinOpts.Args()
|
args = joinOpts.Args()
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
Help()
|
Help()
|
||||||
os.Exit(1)
|
return 1
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if len(args[0]) != zerotier.NetworkIDStringLength {
|
if len(args[0]) != zerotier.NetworkIDStringLength {
|
||||||
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = *controllerAuthToken // TODO: not implemented yet
|
_ = *controllerAuthToken // TODO: not implemented yet
|
||||||
|
@ -52,13 +50,13 @@ func Join(basePath, authToken string, args []string) {
|
||||||
fp, err = zerotier.NewFingerprintFromString(*controllerFingerprint)
|
fp, err = zerotier.NewFingerprintFromString(*controllerFingerprint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: invalid network controller fingerprint: %s\n", *controllerFingerprint)
|
fmt.Printf("ERROR: invalid network controller fingerprint: %s\n", *controllerFingerprint)
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
id, err := zerotier.NewIdentityFromString(*controllerFingerprint)
|
id, err := zerotier.NewIdentityFromString(*controllerFingerprint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: invalid network controller identity: %s\n", *controllerFingerprint)
|
fmt.Printf("ERROR: invalid network controller identity: %s\n", *controllerFingerprint)
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
fp = id.Fingerprint()
|
fp = id.Fingerprint()
|
||||||
}
|
}
|
||||||
|
@ -67,7 +65,7 @@ func Join(basePath, authToken string, args []string) {
|
||||||
nwid, err := strconv.ParseUint(args[0], 16, 64)
|
nwid, err := strconv.ParseUint(args[0], 16, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
nwids := fmt.Sprintf("%.16x", nwid)
|
nwids := fmt.Sprintf("%.16x", nwid)
|
||||||
|
|
||||||
|
@ -85,5 +83,5 @@ func Join(basePath, authToken string, args []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Exit(0)
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,29 +15,29 @@ package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"zerotier/pkg/zerotier"
|
"zerotier/pkg/zerotier"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Leave(basePath, authToken string, args []string) {
|
func Leave(basePath, authToken string, args []string) int {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
Help()
|
Help()
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args[0]) != zerotier.NetworkIDStringLength {
|
if len(args[0]) != zerotier.NetworkIDStringLength {
|
||||||
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
nwid, err := strconv.ParseUint(args[0], 16, 64)
|
nwid, err := strconv.ParseUint(args[0], 16, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
nwids := fmt.Sprintf("%.16x", nwid)
|
nwids := fmt.Sprintf("%.16x", nwid)
|
||||||
|
|
||||||
apiDelete(basePath, authToken, "/network/"+nwids, nil)
|
apiDelete(basePath, authToken, "/network/"+nwids, nil)
|
||||||
fmt.Printf("OK %s", nwids)
|
fmt.Printf("OK %s", nwids)
|
||||||
os.Exit(0)
|
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -85,20 +84,20 @@ func showNetwork(nwids string, network *zerotier.APINetwork, jsonOutput bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Network(basePath, authToken string, args []string, jsonOutput bool) {
|
func Network(basePath, authToken string, args []string, jsonOutput bool) int {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
Help()
|
Help()
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args[0]) != zerotier.NetworkIDStringLength {
|
if len(args[0]) != zerotier.NetworkIDStringLength {
|
||||||
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
nwid, err := strconv.ParseUint(args[0], 16, 64)
|
nwid, err := strconv.ParseUint(args[0], 16, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
fmt.Printf("ERROR: invalid network ID: %s\n", args[0])
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
nwids := fmt.Sprintf("%.16x", nwid)
|
nwids := fmt.Sprintf("%.16x", nwid)
|
||||||
|
|
||||||
|
@ -114,6 +113,7 @@ func Network(basePath, authToken string, args []string, jsonOutput bool) {
|
||||||
case "set":
|
case "set":
|
||||||
if len(args) > 3 {
|
if len(args) > 3 {
|
||||||
Help()
|
Help()
|
||||||
|
return 1
|
||||||
} else if len(args) > 2 {
|
} else if len(args) > 2 {
|
||||||
fieldName := strings.ToLower(strings.TrimSpace(args[2]))
|
fieldName := strings.ToLower(strings.TrimSpace(args[2]))
|
||||||
var field *bool
|
var field *bool
|
||||||
|
@ -130,7 +130,7 @@ func Network(basePath, authToken string, args []string, jsonOutput bool) {
|
||||||
field = &network.Settings.AllowDefaultRouteOverride
|
field = &network.Settings.AllowDefaultRouteOverride
|
||||||
default:
|
default:
|
||||||
Help()
|
Help()
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) == 3 {
|
if len(args) == 3 {
|
||||||
|
@ -148,5 +148,5 @@ func Network(basePath, authToken string, args []string, jsonOutput bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Exit(0)
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,12 +15,10 @@ package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
|
|
||||||
"zerotier/pkg/zerotier"
|
"zerotier/pkg/zerotier"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Networks(basePath, authToken string, args []string, jsonOutput bool) {
|
func Networks(basePath, authToken string, args []string, jsonOutput bool) int {
|
||||||
var networks []zerotier.APINetwork
|
var networks []zerotier.APINetwork
|
||||||
apiGet(basePath, authToken, "/network", &networks)
|
apiGet(basePath, authToken, "/network", &networks)
|
||||||
|
|
||||||
|
@ -44,5 +42,5 @@ func Networks(basePath, authToken string, args []string, jsonOutput bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Exit(0)
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,12 @@ package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"zerotier/pkg/zerotier"
|
"zerotier/pkg/zerotier"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Peers(basePath, authToken string, args []string, jsonOutput bool, rootsOnly bool) {
|
func Peers(basePath, authToken string, args []string, jsonOutput bool, rootsOnly bool) int {
|
||||||
var peers []zerotier.Peer
|
var peers []zerotier.Peer
|
||||||
apiGet(basePath, authToken, "/peer", &peers)
|
apiGet(basePath, authToken, "/peer", &peers)
|
||||||
|
|
||||||
|
@ -64,5 +63,5 @@ func Peers(basePath, authToken string, args []string, jsonOutput bool, rootsOnly
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Exit(0)
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,10 @@ import (
|
||||||
"zerotier/pkg/zerotier"
|
"zerotier/pkg/zerotier"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Service(basePath string, args []string) {
|
func Service(basePath string, args []string) int {
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
Help()
|
Help()
|
||||||
os.Exit(1)
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
pidPath := path.Join(basePath, "zerotier.pid")
|
pidPath := path.Join(basePath, "zerotier.pid")
|
||||||
|
@ -45,5 +45,5 @@ func Service(basePath string, args []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = os.Remove(pidPath)
|
_ = os.Remove(pidPath)
|
||||||
os.Exit(1)
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,5 +13,6 @@
|
||||||
|
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
func Set(basePath, authToken string, args []string) {
|
func Set(basePath, authToken string, args []string) int {
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,12 +15,10 @@ package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
|
|
||||||
"zerotier/pkg/zerotier"
|
"zerotier/pkg/zerotier"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Status(basePath, authToken string, args []string, jsonOutput bool) {
|
func Status(basePath, authToken string, args []string, jsonOutput bool) int {
|
||||||
var status zerotier.APIStatus
|
var status zerotier.APIStatus
|
||||||
apiGet(basePath, authToken, "/status", &status)
|
apiGet(basePath, authToken, "/status", &status)
|
||||||
|
|
||||||
|
@ -70,5 +68,5 @@ func Status(basePath, authToken string, args []string, jsonOutput bool) {
|
||||||
fmt.Printf("\n")
|
fmt.Printf("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Exit(0)
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,33 +27,30 @@ import (
|
||||||
"zerotier/pkg/zerotier"
|
"zerotier/pkg/zerotier"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getAuthTokenPaths(basePath string) (p []string) {
|
func authToken(basePath, tflag, tTflag string) string {
|
||||||
p = append(p, path.Join(basePath, "authtoken.secret"))
|
|
||||||
userHome, _ := os.UserHomeDir()
|
|
||||||
if len(userHome) > 0 {
|
|
||||||
if runtime.GOOS == "darwin" {
|
|
||||||
p = append(p, path.Join(userHome, "Library", "Application Support", "ZeroTier", "authtoken.secret"))
|
|
||||||
p = append(p, path.Join(userHome, "Library", "Application Support", "ZeroTier", "One", "authtoken.secret"))
|
|
||||||
}
|
|
||||||
p = append(p, path.Join(userHome, ".zerotierauth"))
|
|
||||||
p = append(p, path.Join(userHome, ".zeroTierOneAuthToken"))
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func authTokenRequired(basePath, tflag, tTflag string) string {
|
|
||||||
authTokenPaths := getAuthTokenPaths(basePath)
|
|
||||||
var authToken string
|
var authToken string
|
||||||
if len(tflag) > 0 {
|
if len(tflag) > 0 {
|
||||||
at, err := ioutil.ReadFile(tflag)
|
at, err := ioutil.ReadFile(tflag)
|
||||||
if err != nil || len(at) == 0 {
|
if err != nil || len(at) == 0 {
|
||||||
fmt.Println("FATAL: unable to read local service API authorization token from " + tflag)
|
fmt.Println("FATAL: unable to read local service API authorization token from " + tflag)
|
||||||
os.Exit(1)
|
return ""
|
||||||
}
|
}
|
||||||
authToken = string(at)
|
authToken = string(at)
|
||||||
} else if len(tTflag) > 0 {
|
} else if len(tTflag) > 0 {
|
||||||
authToken = tTflag
|
authToken = tTflag
|
||||||
} else {
|
} else {
|
||||||
|
var authTokenPaths []string
|
||||||
|
authTokenPaths = append(authTokenPaths, path.Join(basePath, "authtoken.secret"))
|
||||||
|
userHome, _ := os.UserHomeDir()
|
||||||
|
if len(userHome) > 0 {
|
||||||
|
if runtime.GOOS == "darwin" {
|
||||||
|
authTokenPaths = append(authTokenPaths, path.Join(userHome, "Library", "Application Support", "ZeroTier", "authtoken.secret"))
|
||||||
|
authTokenPaths = append(authTokenPaths, path.Join(userHome, "Library", "Application Support", "ZeroTier", "One", "authtoken.secret"))
|
||||||
|
}
|
||||||
|
authTokenPaths = append(authTokenPaths, path.Join(userHome, ".zerotierauth"))
|
||||||
|
authTokenPaths = append(authTokenPaths, path.Join(userHome, ".zeroTierOneAuthToken"))
|
||||||
|
}
|
||||||
|
|
||||||
for _, p := range authTokenPaths {
|
for _, p := range authTokenPaths {
|
||||||
tmp, _ := ioutil.ReadFile(p)
|
tmp, _ := ioutil.ReadFile(p)
|
||||||
if len(tmp) > 0 {
|
if len(tmp) > 0 {
|
||||||
|
@ -61,19 +58,22 @@ func authTokenRequired(basePath, tflag, tTflag string) string {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(authToken) == 0 {
|
if len(authToken) == 0 {
|
||||||
fmt.Println("FATAL: unable to read local service API authorization token from any of:")
|
fmt.Println("FATAL: unable to read local service API authorization token from any of:")
|
||||||
for _, p := range authTokenPaths {
|
for _, p := range authTokenPaths {
|
||||||
fmt.Println(" " + p)
|
fmt.Println(" " + p)
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
authToken = strings.TrimSpace(authToken)
|
authToken = strings.TrimSpace(authToken)
|
||||||
if len(authToken) == 0 {
|
if len(authToken) == 0 {
|
||||||
fmt.Println("FATAL: unable to read API authorization token from command line or any filesystem location.")
|
fmt.Println("FATAL: unable to read API authorization token from command line or any filesystem location.")
|
||||||
os.Exit(1)
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return authToken
|
return authToken
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,37 +111,39 @@ func main() {
|
||||||
basePath = *pflag
|
basePath = *pflag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exitCode := 0
|
||||||
switch args[0] {
|
switch args[0] {
|
||||||
default:
|
default:
|
||||||
//case "help":
|
cli.Help()
|
||||||
|
exitCode = 1
|
||||||
|
case "help":
|
||||||
cli.Help()
|
cli.Help()
|
||||||
case "version":
|
case "version":
|
||||||
fmt.Printf("%d.%d.%d\n", zerotier.CoreVersionMajor, zerotier.CoreVersionMinor, zerotier.CoreVersionRevision)
|
fmt.Printf("%d.%d.%d\n", zerotier.CoreVersionMajor, zerotier.CoreVersionMinor, zerotier.CoreVersionRevision)
|
||||||
case "service":
|
case "service":
|
||||||
cli.Service(basePath, cmdArgs)
|
exitCode = cli.Service(basePath, cmdArgs)
|
||||||
case "status", "info":
|
case "status", "info":
|
||||||
cli.Status(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs, *jflag)
|
exitCode = cli.Status(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs, *jflag)
|
||||||
case "join":
|
case "join":
|
||||||
cli.Join(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs)
|
exitCode = cli.Join(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs)
|
||||||
case "leave":
|
case "leave":
|
||||||
cli.Leave(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs)
|
exitCode = cli.Leave(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs)
|
||||||
case "networks", "listnetworks":
|
case "networks", "listnetworks":
|
||||||
cli.Networks(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs, *jflag)
|
exitCode = cli.Networks(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs, *jflag)
|
||||||
case "network":
|
case "network":
|
||||||
cli.Network(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs, *jflag)
|
exitCode = cli.Network(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs, *jflag)
|
||||||
case "peers", "listpeers", "lspeers":
|
case "peers", "listpeers", "lspeers":
|
||||||
cli.Peers(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs, *jflag, false)
|
exitCode = cli.Peers(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs, *jflag, false)
|
||||||
case "peer":
|
case "peer":
|
||||||
authTokenRequired(basePath, *tflag, *tTflag)
|
|
||||||
case "roots":
|
case "roots":
|
||||||
cli.Peers(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs, *jflag, true)
|
exitCode = cli.Peers(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs, *jflag, true)
|
||||||
case "controller":
|
case "controller":
|
||||||
case "set":
|
case "set":
|
||||||
cli.Set(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs)
|
exitCode = cli.Set(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs)
|
||||||
case "identity":
|
case "identity":
|
||||||
cli.Identity(cmdArgs)
|
exitCode = cli.Identity(cmdArgs)
|
||||||
case "cert":
|
case "cert":
|
||||||
cli.Cert(basePath, authTokenRequired(basePath, *tflag, *tTflag), cmdArgs, *jflag)
|
exitCode = cli.Cert(basePath, authToken(basePath, *tflag, *tTflag), cmdArgs, *jflag)
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,9 @@
|
||||||
* 9 - 1.2.0 ... 1.2.14
|
* 9 - 1.2.0 ... 1.2.14
|
||||||
* 10 - 1.4.0 ... 1.4.6
|
* 10 - 1.4.0 ... 1.4.6
|
||||||
* + Contained early pre-alpha versions of multipath, which are deprecated
|
* + Contained early pre-alpha versions of multipath, which are deprecated
|
||||||
* 11 - 2.0.0 ... CURRENT
|
* 11 - 1.4.8 ... CURRENT 1.4
|
||||||
|
* + AES-GMAC-SIV backported for faster peer-to-peer crypto
|
||||||
|
* 20 - 2.0.0 ... CURRENT
|
||||||
* + New more WAN-efficient P2P-assisted multicast algorithm
|
* + New more WAN-efficient P2P-assisted multicast algorithm
|
||||||
* + HELLO and OK(HELLO) include an extra HMAC to harden authentication
|
* + HELLO and OK(HELLO) include an extra HMAC to harden authentication
|
||||||
* + HELLO and OK(HELLO) carry meta-data in a dictionary that's encrypted
|
* + HELLO and OK(HELLO) carry meta-data in a dictionary that's encrypted
|
||||||
|
@ -117,7 +119,7 @@
|
||||||
* + Short probe packets to reduce probe bandwidth
|
* + Short probe packets to reduce probe bandwidth
|
||||||
* + More aggressive NAT traversal techniques for IPv4 symmetric NATs
|
* + More aggressive NAT traversal techniques for IPv4 symmetric NATs
|
||||||
*/
|
*/
|
||||||
#define ZT_PROTO_VERSION 11
|
#define ZT_PROTO_VERSION 20
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimum supported protocol version
|
* Minimum supported protocol version
|
||||||
|
|
|
@ -16,11 +16,13 @@
|
||||||
|
|
||||||
#include "Constants.hpp"
|
#include "Constants.hpp"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdint.h>
|
#include <stdexcept>
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,12 @@ type Certificate struct {
|
||||||
Signature []byte `json:"signature,omitempty"`
|
Signature []byte `json:"signature,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CertificateSubjectUniqueIDSecret bundles a certificate subject unique ID and its secret key.
|
||||||
|
type CertificateSubjectUniqueIDSecret struct {
|
||||||
|
UniqueID []byte `json:"uniqueId,omitempty"`
|
||||||
|
UniqueIDSecret []byte `json:"uniqueIdSecret,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
func certificateErrorToError(cerr int) error {
|
func certificateErrorToError(cerr int) error {
|
||||||
switch cerr {
|
switch cerr {
|
||||||
case C.ZT_CERTIFICATE_ERROR_NONE:
|
case C.ZT_CERTIFICATE_ERROR_NONE:
|
||||||
|
|
Loading…
Add table
Reference in a new issue