From 5031ae15d0062d834742ab9b4cc31b2761c0748a Mon Sep 17 00:00:00 2001 From: Gilbert Chen Date: Mon, 25 Sep 2017 21:31:35 -0400 Subject: [PATCH 1/5] When resetPassword is true, the entered password should be the same as that in environment or preference --- src/duplicacy_utils.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/duplicacy_utils.go b/src/duplicacy_utils.go index f4a7370..35b4880 100644 --- a/src/duplicacy_utils.go +++ b/src/duplicacy_utils.go @@ -182,12 +182,12 @@ func GetPasswordFromPreference(preference Preference, passwordType string) strin // (i.e., preference.Name) in the key, so the key name should really be passwordType rather // than passwordID; we're using passwordID here only for backward compatibility if len(preference.Keys) > 0 && len(preference.Keys[passwordID]) > 0 { - LOG_DEBUG("PASSWORD_KEYCHAIN", "Reading %s from preferences", passwordID) + LOG_DEBUG("PASSWORD_PREFERENCE", "Reading %s from preferences", passwordID) return preference.Keys[passwordID] } if len(preference.Keys) > 0 && len(preference.Keys[passwordType]) > 0 { - LOG_DEBUG("PASSWORD_KEYCHAIN", "Reading %s from preferences", passwordType) + LOG_DEBUG("PASSWORD_PREFERENCE", "Reading %s from preferences", passwordType) return preference.Keys[passwordType] } @@ -198,9 +198,10 @@ func GetPasswordFromPreference(preference Preference, passwordType string) strin func GetPassword(preference Preference, passwordType string, prompt string, showPassword bool, resetPassword bool) string { passwordID := passwordType - password := GetPasswordFromPreference(preference, passwordType) - if password != "" { - return password + + preferencePassword := GetPasswordFromPreference(preference, passwordType) + if preferencePassword != "" && !resetPassword { + return preferencePassword } if preference.Name != "default" { @@ -212,6 +213,7 @@ func GetPassword(preference Preference, passwordType string, prompt string, } else { password := keyringGet(passwordID) if password != "" { + LOG_DEBUG("PASSWORD_KEYCHAIN", "Reading %s from keychain/keyring", passwordType) return password } @@ -222,7 +224,7 @@ func GetPassword(preference Preference, passwordType string, prompt string, } - password = "" + password := "" fmt.Printf("%s", prompt) if showPassword { scanner := bufio.NewScanner(os.Stdin) @@ -237,6 +239,11 @@ func GetPassword(preference Preference, passwordType string, prompt string, password = string(passwordInBytes) } + if resetPassword && preferencePassword != "" && preferencePassword != password { + LOG_ERROR("PASSWORD_MISMATCH", "The password entered is different from what is in the environment or preference") + return "" + } + return password } From 8841ced1f54ed0fb48c521ee83169af5e72e919d Mon Sep 17 00:00:00 2001 From: Gilbert Chen Date: Mon, 25 Sep 2017 21:52:49 -0400 Subject: [PATCH 2/5] Storage name can't be 'ssh' otherwise the ssh password of the default storage nad the storage password of the 'ssh' storage will share the same keychain entry --- duplicacy/duplicacy_main.go | 5 +++++ src/duplicacy_preference.go | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/duplicacy/duplicacy_main.go b/duplicacy/duplicacy_main.go index cb9e805..b01902f 100644 --- a/duplicacy/duplicacy_main.go +++ b/duplicacy/duplicacy_main.go @@ -223,6 +223,11 @@ func configRepository(context *cli.Context, init bool) { storageName = context.Args()[0] snapshotID = context.Args()[1] storageURL = context.Args()[2] + + if strings.ToLower(storageName) == "ssh" { + duplicacy.LOG_ERROR("PREFERENCE_INVALID", "'%s' is an invalid storage name", storageName) + return + } } var repository string diff --git a/src/duplicacy_preference.go b/src/duplicacy_preference.go index 1ae910f..f9eaeb1 100644 --- a/src/duplicacy_preference.go +++ b/src/duplicacy_preference.go @@ -74,6 +74,13 @@ func LoadPreferences(repository string) bool { return false } + for _, preference := range Preferences { + if strings.ToLower(preference.Name) == "ssh" { + LOG_ERROR("PREFERENCE_INVALID", "'%s' is an invalid storage name", preference.Name) + return false + } + } + return true } From ce52ec1e5ddcfccd44472f672a39e5c6cecd178a Mon Sep 17 00:00:00 2001 From: Gilbert Chen Date: Tue, 26 Sep 2017 10:37:06 -0400 Subject: [PATCH 3/5] The info command should not overwrite the default password if reset-passwords is on --- duplicacy/duplicacy_main.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/duplicacy/duplicacy_main.go b/duplicacy/duplicacy_main.go index b01902f..e7d87fc 100644 --- a/duplicacy/duplicacy_main.go +++ b/duplicacy/duplicacy_main.go @@ -1122,6 +1122,7 @@ func infoStorage(context *cli.Context) { duplicacy.SetKeyringFile(path.Join(preferencePath, "keyring")) } + resetPasswords := context.Bool("reset-passwords") isEncrypted := context.Bool("e") preference := duplicacy.Preference{ Name: "default", @@ -1131,12 +1132,18 @@ func infoStorage(context *cli.Context) { DoNotSavePassword: true, } - password := "" - if isEncrypted { - password = duplicacy.GetPassword(preference, "password", "Enter the storage password:", false, false) + if resetPasswords { + // We don't want password entered for the info command to overwrite the saved password for the default storage, + // so we simply assign an empty name. + preference.Name = "" } - storage := duplicacy.CreateStorage(preference, context.Bool("reset-passwords"), 1) + password := "" + if isEncrypted { + password = duplicacy.GetPassword(preference, "password", "Enter the storage password:", false, resetPasswords) + } + + storage := duplicacy.CreateStorage(preference, resetPasswords, 1) config, isStorageEncrypted, err := duplicacy.DownloadConfig(storage, password) if isStorageEncrypted { From 80742ce2ba349c74e534613dbcc2604085cc9bcd Mon Sep 17 00:00:00 2001 From: Gilbert Chen Date: Tue, 26 Sep 2017 10:41:18 -0400 Subject: [PATCH 4/5] Don't verify SSH host if the preference path is not set --- src/duplicacy_storage.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/duplicacy_storage.go b/src/duplicacy_storage.go index 97c2b9a..c147a6b 100644 --- a/src/duplicacy_storage.go +++ b/src/duplicacy_storage.go @@ -77,7 +77,9 @@ func (storage *RateLimitedStorage) SetRateLimits(downloadRateLimit int, uploadRa func checkHostKey(hostname string, remote net.Addr, key ssh.PublicKey) error { - preferencePath := GetDuplicacyPreferencePath() + if preferencePath == "" { + return fmt.Errorf("Can't verify SSH host since the preference path is not set") + } hostFile := path.Join(preferencePath, "known_hosts") file, err := os.OpenFile(hostFile, os.O_RDWR|os.O_CREATE, 0600) if err != nil { From 7162d8916effe2c894ddaf8a70b6124f12b4d791 Mon Sep 17 00:00:00 2001 From: Gilbert Chen Date: Fri, 29 Sep 2017 22:20:37 -0400 Subject: [PATCH 5/5] Use math.MaxInt32 to avoid a build error on 32-bit platforms --- src/duplicacy_snapshotmanager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/duplicacy_snapshotmanager.go b/src/duplicacy_snapshotmanager.go index 337d68f..fea6832 100644 --- a/src/duplicacy_snapshotmanager.go +++ b/src/duplicacy_snapshotmanager.go @@ -968,7 +968,7 @@ func (manager *SnapshotManager) ShowStatisticsTabular(snapshotMap map[string][]* for _, snapshot := range snapshotList { for _, chunkID := range manager.GetSnapshotChunks(snapshot) { if earliestSeenChunks[chunkID] == 0 { - earliestSeenChunks[chunkID] = math.MaxInt64 + earliestSeenChunks[chunkID] = math.MaxInt32 } earliestSeenChunks[chunkID] = MinInt(earliestSeenChunks[chunkID], snapshot.Revision) }