diff --git a/cmd/btcctl/config.go b/cmd/btcctl/config.go index 339b2ed5..fbdb7790 100644 --- a/cmd/btcctl/config.go +++ b/cmd/btcctl/config.go @@ -175,20 +175,13 @@ func loadConfig() (*config, []string, error) { RPCCert: defaultRPCCertFile, } - // Create the home directory if it doesn't already exist. - err := os.MkdirAll(btcdHomeDir, 0700) - if err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - os.Exit(-1) - } - // Pre-parse the command line options to see if an alternative config // file, the version flag, or the list commands flag was specified. Any // errors aside from the help message error can be ignored here since // they will be caught by the final parse below. preCfg := cfg preParser := flags.NewParser(&preCfg, flags.HelpFlag) - _, err = preParser.Parse() + _, err := preParser.Parse() if err != nil { if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp { fmt.Fprintln(os.Stderr, err) @@ -282,9 +275,6 @@ func loadConfig() (*config, []string, error) { // For this it tries to read the btcd config file at its default path, and extract // the RPC user and password from it. func createDefaultConfigFile(destinationPath string) error { - // Create the destination directory if it does not exists - os.MkdirAll(filepath.Dir(destinationPath), 0700) - // Read btcd.conf from its default path btcdConfigPath := filepath.Join(btcdHomeDir, "btcd.conf") btcdConfigFile, err := os.Open(btcdConfigPath) @@ -319,14 +309,22 @@ func createDefaultConfigFile(destinationPath string) error { return nil } + // Create the destination directory if it does not exists + err = os.MkdirAll(filepath.Dir(destinationPath), 0700) + if err != nil { + return err + } + // Create the destination file and write the rpcuser and rpcpass to it - dest, err := os.OpenFile(destinationPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0700) + dest, err := os.OpenFile(destinationPath, + os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { return err } defer dest.Close() - dest.WriteString(fmt.Sprintf("rpcuser=%s\nrpcpass=%s", string(userSubmatches[1]), string(passSubmatches[1]))) + dest.WriteString(fmt.Sprintf("rpcuser=%s\nrpcpass=%s", + string(userSubmatches[1]), string(passSubmatches[1]))) return nil } diff --git a/config.go b/config.go index 7dff0200..87d2df6f 100644 --- a/config.go +++ b/config.go @@ -52,18 +52,19 @@ const ( defaultMaxOrphanTransactions = 1000 defaultMaxOrphanTxSize = 5000 defaultSigCacheMaxSize = 100000 + sampleConfigFilename = "sample-btcd.conf" defaultTxIndex = false defaultAddrIndex = false ) var ( - btcdHomeDir = btcutil.AppDataDir("btcd", false) - defaultConfigFile = filepath.Join(btcdHomeDir, defaultConfigFilename) - defaultDataDir = filepath.Join(btcdHomeDir, defaultDataDirname) + defaultHomeDir = btcutil.AppDataDir("btcd", false) + defaultConfigFile = filepath.Join(defaultHomeDir, defaultConfigFilename) + defaultDataDir = filepath.Join(defaultHomeDir, defaultDataDirname) knownDbTypes = database.SupportedDrivers() - defaultRPCKeyFile = filepath.Join(btcdHomeDir, "rpc.key") - defaultRPCCertFile = filepath.Join(btcdHomeDir, "rpc.cert") - defaultLogDir = filepath.Join(btcdHomeDir, defaultLogDirname) + defaultRPCKeyFile = filepath.Join(defaultHomeDir, "rpc.key") + defaultRPCCertFile = filepath.Join(defaultHomeDir, "rpc.cert") + defaultLogDir = filepath.Join(defaultHomeDir, defaultLogDirname) ) // runServiceCommand is only set to a real function on Windows. It is used @@ -153,7 +154,7 @@ type config struct { minRelayTxFee btcutil.Amount } -// serviceOptions defines the configuration options for btcd as a service on +// serviceOptions defines the configuration options for the daemon as a service on // Windows. type serviceOptions struct { ServiceCommand string `short:"s" long:"service" description:"Service command {install, remove, start, stop}"` @@ -164,7 +165,7 @@ type serviceOptions struct { func cleanAndExpandPath(path string) string { // Expand initial ~ to OS specific home directory. if strings.HasPrefix(path, "~") { - homeDir := filepath.Dir(btcdHomeDir) + homeDir := filepath.Dir(defaultHomeDir) path = strings.Replace(path, "~", homeDir, 1) } @@ -440,7 +441,7 @@ func loadConfig() (*config, []string, error) { // Create the home directory if it doesn't already exist. funcName := "loadConfig" - err = os.MkdirAll(btcdHomeDir, 0700) + err = os.MkdirAll(defaultHomeDir, 0700) if err != nil { // Show a nicer error message if it's because a symlink is // linked to a directory that does not exist (probably because @@ -931,15 +932,21 @@ func loadConfig() (*config, []string, error) { // and populates it with some randomly generated RPC username and password. func createDefaultConfigFile(destinationPath string) error { // Create the destination directory if it does not exists - os.MkdirAll(filepath.Dir(destinationPath), 0700) + err := os.MkdirAll(filepath.Dir(destinationPath), 0700) + if err != nil { + return err + } - // We get the sample config file path, which is in the same directory as this file. - _, path, _, _ := runtime.Caller(0) - sampleConfigPath := filepath.Join(filepath.Dir(path), "sample-btcd.conf") + // We assume sample config file path is same as binary + path, err := filepath.Abs(filepath.Dir(os.Args[0])) + if err != nil { + return err + } + sampleConfigPath := filepath.Join(path, sampleConfigFilename) // We generate a random user and password randomBytes := make([]byte, 20) - _, err := rand.Read(randomBytes) + _, err = rand.Read(randomBytes) if err != nil { return err } @@ -957,7 +964,8 @@ func createDefaultConfigFile(destinationPath string) error { } defer src.Close() - dest, err := os.OpenFile(destinationPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0700) + dest, err := os.OpenFile(destinationPath, + os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { return err } diff --git a/config_test.go b/config_test.go index 4083c544..e54a9f5f 100644 --- a/config_test.go +++ b/config_test.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "regexp" + "runtime" "testing" ) @@ -14,15 +15,39 @@ var ( ) func TestCreateDefaultConfigFile(t *testing.T) { + // find out where the sample config lives + _, path, _, ok := runtime.Caller(0) + if !ok { + t.Fatalf("Failed finding config file path") + } + sampleConfigFile := filepath.Join(filepath.Dir(path), "sample-btcd.conf") + // Setup a temporary directory tmpDir, err := ioutil.TempDir("", "btcd") if err != nil { t.Fatalf("Failed creating a temporary directory: %v", err) } testpath := filepath.Join(tmpDir, "test.conf") + + // copy config file to location of btcd binary + data, err := ioutil.ReadFile(sampleConfigFile) + if err != nil { + t.Fatalf("Failed reading sample config file: %v", err) + } + appPath, err := filepath.Abs(filepath.Dir(os.Args[0])) + if err != nil { + t.Fatalf("Failed obtaining app path: %v", err) + } + tmpConfigFile := filepath.Join(appPath, "sample-btcd.conf") + err = ioutil.WriteFile(tmpConfigFile, data, 0644) + if err != nil { + t.Fatalf("Failed copying sample config file: %v", err) + } + // Clean-up defer func() { os.Remove(testpath) + os.Remove(tmpConfigFile) os.Remove(tmpDir) }() diff --git a/service_windows.go b/service_windows.go index d5881873..be642ad5 100644 --- a/service_windows.go +++ b/service_windows.go @@ -37,7 +37,7 @@ var elog *eventlog.Log func logServiceStartOfDay(srvr *server) { var message string message += fmt.Sprintf("Version %s\n", version()) - message += fmt.Sprintf("Configuration directory: %s\n", btcdHomeDir) + message += fmt.Sprintf("Configuration directory: %s\n", defaultHomeDir) message += fmt.Sprintf("Configuration file: %s\n", cfg.ConfigFile) message += fmt.Sprintf("Data directory: %s\n", cfg.DataDir) diff --git a/upgrade.go b/upgrade.go index 4140f41c..78bc6f2d 100644 --- a/upgrade.go +++ b/upgrade.go @@ -111,7 +111,7 @@ func upgradeDBPaths() error { func upgradeDataPaths() error { // No need to migrate if the old and new home paths are the same. oldHomePath := oldBtcdHomeDir() - newHomePath := btcdHomeDir + newHomePath := defaultHomeDir if oldHomePath == newHomePath { return nil }