OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / cmd / gencerts / gencerts.go
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         "github.com/btcsuite/btcutil"
16         flags "github.com/jessevdk/go-flags"
17 )
18
19 type config struct {
20         Directory    string   `short:"d" long:"directory" description:"Directory to write certificate pair"`
21         Years        int      `short:"y" long:"years" description:"How many years a certificate is valid for"`
22         Organization string   `short:"o" long:"org" description:"Organization in certificate"`
23         ExtraHosts   []string `short:"H" long:"host" description:"Additional hosts/IPs to create certificate for"`
24         Force        bool     `short:"f" long:"force" description:"Force overwriting of any old certs and keys"`
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 }