github.com/lbryio/lbcd@v0.22.119/cmd/gencerts/gencerts.go (about) 1 // Copyright (c) 2013-2014 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "fmt" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 "strings" 13 "time" 14 15 flags "github.com/jessevdk/go-flags" 16 btcutil "github.com/lbryio/lbcutil" 17 ) 18 19 type config struct { 20 Directory string `short:"d" long:"directory" description:"Directory to write certificate pair"` 21 Force bool `short:"f" long:"force" description:"Force overwriting of any old certs and keys"` 22 ExtraHosts []string `short:"H" long:"host" description:"Additional hosts/IPs to create certificate for"` 23 Organization string `short:"o" long:"org" description:"Organization in certificate"` 24 Years int `short:"y" long:"years" description:"How many years a certificate is valid for"` 25 } 26 27 func main() { 28 cfg := config{ 29 Years: 10, 30 Organization: "gencerts", 31 } 32 parser := flags.NewParser(&cfg, flags.Default) 33 _, err := parser.Parse() 34 if err != nil { 35 if e, ok := err.(*flags.Error); !ok || e.Type != flags.ErrHelp { 36 parser.WriteHelp(os.Stderr) 37 } 38 return 39 } 40 41 if cfg.Directory == "" { 42 var err error 43 cfg.Directory, err = os.Getwd() 44 if err != nil { 45 fmt.Fprintf(os.Stderr, "no directory specified and cannot get working directory\n") 46 os.Exit(1) 47 } 48 } 49 cfg.Directory = cleanAndExpandPath(cfg.Directory) 50 certFile := filepath.Join(cfg.Directory, "rpc.cert") 51 keyFile := filepath.Join(cfg.Directory, "rpc.key") 52 53 if !cfg.Force { 54 if fileExists(certFile) || fileExists(keyFile) { 55 fmt.Fprintf(os.Stderr, "%v: certificate and/or key files exist; use -f to force\n", cfg.Directory) 56 os.Exit(1) 57 } 58 } 59 60 validUntil := time.Now().Add(time.Duration(cfg.Years) * 365 * 24 * time.Hour) 61 cert, key, err := btcutil.NewTLSCertPair(cfg.Organization, validUntil, cfg.ExtraHosts) 62 if err != nil { 63 fmt.Fprintf(os.Stderr, "cannot generate certificate pair: %v\n", err) 64 os.Exit(1) 65 } 66 67 // Write cert and key files. 68 if err = ioutil.WriteFile(certFile, cert, 0666); err != nil { 69 fmt.Fprintf(os.Stderr, "cannot write cert: %v\n", err) 70 os.Exit(1) 71 } 72 if err = ioutil.WriteFile(keyFile, key, 0600); err != nil { 73 os.Remove(certFile) 74 fmt.Fprintf(os.Stderr, "cannot write key: %v\n", err) 75 os.Exit(1) 76 } 77 } 78 79 // cleanAndExpandPath expands environement variables and leading ~ in the 80 // passed path, cleans the result, and returns it. 81 func cleanAndExpandPath(path string) string { 82 // Expand initial ~ to OS specific home directory. 83 if strings.HasPrefix(path, "~") { 84 appHomeDir := btcutil.AppDataDir("gencerts", false) 85 homeDir := filepath.Dir(appHomeDir) 86 path = strings.Replace(path, "~", homeDir, 1) 87 } 88 89 // NOTE: The os.ExpandEnv doesn't work with Windows-style %VARIABLE%, 90 // but they variables can still be expanded via POSIX-style $VARIABLE. 91 return filepath.Clean(os.ExpandEnv(path)) 92 } 93 94 // filesExists reports whether the named file or directory exists. 95 func fileExists(name string) bool { 96 if _, err := os.Stat(name); err != nil { 97 if os.IsNotExist(err) { 98 return false 99 } 100 } 101 return true 102 }