github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/cmd/gencerts/gencerts.go (about)

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