From 4f56a291eb828a9bc793bd3863e41a3a61153db6 Mon Sep 17 00:00:00 2001 From: Raghuram Subramani Date: Thu, 3 Mar 2022 19:18:56 +0530 Subject: add room --- overpass/overpass.go | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 overpass/overpass.go (limited to 'overpass/overpass.go') diff --git a/overpass/overpass.go b/overpass/overpass.go new file mode 100644 index 0000000..ef6d7df --- /dev/null +++ b/overpass/overpass.go @@ -0,0 +1,192 @@ +package main + +import ( + "bufio" + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "github.com/mitchellh/go-homedir" +) + +type passListEntry struct { + Name string `json:"name"` + Pass string `json:"pass"` +} + +//Secure encryption algorithm from https://socketloop.com/tutorials/golang-rotate-47-caesar-cipher-by-47-characters-example +func rot47(input string) string { + var result []string + for i := range input[:len(input)] { + j := int(input[i]) + if (j >= 33) && (j <= 126) { + result = append(result, string(rune(33+((j+14)%94)))) + } else { + result = append(result, string(input[i])) + } + } + return strings.Join(result, "") +} + +//Encrypt the credentials and write them to a file. +func saveCredsToFile(filepath string, passlist []passListEntry) string { + file, err := os.OpenFile(filepath, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + fmt.Println(err.Error()) + return err.Error() + } + defer file.Close() + stringToWrite := rot47(credsToJSON(passlist)) + if _, err := file.WriteString(stringToWrite); err != nil { + fmt.Println(err.Error()) + return err.Error() + } + return "Success" +} + +//Load the credentials from the encrypted file +func loadCredsFromFile(filepath string) ([]passListEntry, string) { + buff, err := ioutil.ReadFile(filepath) + if err != nil { + fmt.Println(err.Error()) + return nil, "Failed to open or read file" + } + //Decrypt passwords + buff = []byte(rot47(string(buff))) + //Load decrypted passwords + var passlist []passListEntry + err = json.Unmarshal(buff, &passlist) + if err != nil { + fmt.Println(err.Error()) + return nil, "Failed to load creds" + } + return passlist, "Ok" +} + +//Convert the array of credentials to JSON +func credsToJSON(passlist []passListEntry) string { + jsonBuffer, err := json.Marshal(passlist) + if err != nil { + fmt.Println(err.Error()) + return "Something went wrong" + } + return string(jsonBuffer) +} + +//Python style input function +func input(prompt string) string { + fmt.Print(prompt) + scanner := bufio.NewScanner(os.Stdin) + if scanner.Scan() { + return scanner.Text() + + } + return "" +} + +func serviceSearch(passlist []passListEntry, serviceName string) (int, passListEntry) { + //A linear search is the best I can do, Steve says it's Oh Log N whatever that means + for index, entry := range passlist { + if entry.Name == serviceName { + return index, entry + } + } + return -1, passListEntry{} +} + +func getPwdForService(passlist []passListEntry, serviceName string) string { + index, entry := serviceSearch(passlist, serviceName) + if index != -1 { + return entry.Pass + } + return "Pass not found" +} + +func setPwdForService(passlist []passListEntry, serviceName string, newPwd string) []passListEntry { + index, entry := serviceSearch(passlist, serviceName) + //If service exists, update entry + if index != -1 { + entry.Pass = newPwd + passlist[index] = entry + return passlist + } + //If it doesn't, create an entry + entry = passListEntry{Name: serviceName, Pass: newPwd} + passlist = append(passlist, entry) + return passlist +} + +func deletePwdByService(passlist []passListEntry, serviceName string) (resultList []passListEntry, status string) { + index, _ := serviceSearch(passlist, serviceName) + if index != -1 { + //remove Pwd from passlist + resultList = append(passlist[:index], passlist[index+1:]...) + status = "Ok" + return + } + return passlist, "Pass not found" +} + +func printAllPasswords(passlist []passListEntry) { + for _, entry := range passlist { + fmt.Println(entry.Name, "\t", entry.Pass) + } +} + +func main() { + credsPath, err := homedir.Expand("~/.overpass") + if err != nil { + fmt.Println("Error finding home path:", err.Error()) + } + //Load credentials + passlist, status := loadCredsFromFile(credsPath) + if status != "Ok" { + fmt.Println(status) + fmt.Println("Continuing with new password file.") + passlist = make([]passListEntry, 0) + } + + fmt.Println("Welcome to Overpass") + + //Determine function + option := -1 + fmt.Print( + "Options:\n" + + "1\tRetrieve Password For Service\n" + + "2\tSet or Update Password For Service\n" + + "3\tDelete Password For Service\n" + + "4\tRetrieve All Passwords\n" + + "5\tExit\n") + + for option > 5 || option < 1 { + optionString := input("Choose an option:\t") + optionChoice, err := strconv.Atoi(optionString) + if err != nil || optionChoice > 5 || optionChoice < 1 { + fmt.Println("Please enter a valid number") + } + option = optionChoice + } + + switch option { + case 1: + service := input("Enter Service Name:\t") + getPwdForService(passlist, service) + case 2: + service := input("Enter Service Name:\t") + newPwd := input("Enter new password:\t") + passlist = setPwdForService(passlist, service, newPwd) + saveCredsToFile(credsPath, passlist) + case 3: + service := input("Enter Service Name:\t") + passlist, status := deletePwdByService(passlist, service) + if status != "Ok" { + fmt.Println(status) + } + saveCredsToFile(credsPath, passlist) + case 4: + printAllPasswords(passlist) + } +} -- cgit v1.2.3