Improve StringGen to allow creating file name-safe complex strings; remove in-code references to future additions

This commit is contained in:
2024-07-18 17:04:48 -04:00
parent 85fddc0382
commit 530fde8f11
8 changed files with 22 additions and 15 deletions
-1
View File
@@ -47,7 +47,6 @@ Manually synchronizing entries with the server:
help Bring up the help menu help Bring up the help menu
version Display version and license information version Display version and license information
init Set up MUTN (generates libmutton.ini) init Set up MUTN (generates libmutton.ini)
tweak Change configuration options (NOT YET IMPLEMENTED)
copy Copy details of an entry to your clipboard copy Copy details of an entry to your clipboard
edit Edit an existing entry edit Edit an existing entry
gen Generate a new password gen Generate a new password
+3 -3
View File
@@ -2,11 +2,12 @@ package main
import ( import (
"fmt" "fmt"
"os"
"strings"
"github.com/rwinkhart/MUTN/src/backend" "github.com/rwinkhart/MUTN/src/backend"
"github.com/rwinkhart/MUTN/src/cli" "github.com/rwinkhart/MUTN/src/cli"
"github.com/rwinkhart/MUTN/src/sync" "github.com/rwinkhart/MUTN/src/sync"
"os"
"strings"
) )
func main() { func main() {
@@ -165,7 +166,6 @@ func main() {
case "tweak": case "tweak":
fmt.Println(backend.AnsiError + "\"tweak\" is not yet implemented" + backend.AnsiReset) fmt.Println(backend.AnsiError + "\"tweak\" is not yet implemented" + backend.AnsiReset)
os.Exit(0) os.Exit(0)
// TODO backend.Tweak()
case "copy": case "copy":
cli.HelpCopy() cli.HelpCopy()
case "edit": case "edit":
+11 -4
View File
@@ -11,8 +11,6 @@ import (
"strings" "strings"
) )
const extendedCharset = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
// TargetIsFile TargetStatusCheck checks if the targetLocation is a file, directory, or is inaccessible // TargetIsFile TargetStatusCheck checks if the targetLocation is a file, directory, or is inaccessible
// failCondition: 0 = fail on inaccessible, 1 = fail on inaccessible/file, 2 = fail on inaccessible/directory // failCondition: 0 = fail on inaccessible, 1 = fail on inaccessible/file, 2 = fail on inaccessible/directory
// returns: isFile, isAccessible // returns: isFile, isAccessible
@@ -88,15 +86,24 @@ func RemoveTrailingEmptyStrings(slice []string) []string {
} }
// StringGen generates a random string of a specified length and complexity // StringGen generates a random string of a specified length and complexity
// safeForFileName: if true, the generated string will only contain special characters that are safe for file names (only impacts complex strings)
// complexity: minimum percentage of special characters to be returned in the generated string (only impacts complex strings) // complexity: minimum percentage of special characters to be returned in the generated string (only impacts complex strings)
func StringGen(length int, complex bool, complexity float64) string { func StringGen(length int, complex bool, complexity float64, safeForFileName bool) string {
var actualSpecialChars int // track the number of special characters in the generated string var actualSpecialChars int // track the number of special characters in the generated string
var minSpecialChars int // track the minimum number of special characters to accept var minSpecialChars int // track the minimum number of special characters to accept
var extendedCharset string // additions to character set used for complex strings
charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" // default character set used for all strings charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" // default character set used for all strings
const extendedCharsetFiles = "!#$%&'()+,-.;=@[]^_`{}~" // additional special characters for complex strings (safe in file names)
const extendedCharsetPassword = "\"*:><?/\\|" // additional special characters for complex strings (NOT safe in file names)
if complex { if complex {
minSpecialChars = int(math.Round(float64(length) * complexity)) // determine minimum number of special characters to accept minSpecialChars = int(math.Round(float64(length) * complexity)) // determine minimum number of special characters to accept
charset = charset + extendedCharset if !safeForFileName {
extendedCharset = extendedCharsetFiles + extendedCharsetPassword
} else {
extendedCharset = extendedCharsetFiles
}
charset += extendedCharset
} }
// loop until a string of the desired complexity is generated // loop until a string of the desired complexity is generated
+3 -2
View File
@@ -2,8 +2,9 @@ package cli
import ( import (
"fmt" "fmt"
"github.com/rwinkhart/MUTN/src/backend"
"os" "os"
"github.com/rwinkhart/MUTN/src/backend"
) )
// AddEntry creates a new entry at targetLocation by taking user input via CLI prompts // AddEntry creates a new entry at targetLocation by taking user input via CLI prompts
@@ -25,7 +26,7 @@ func AddEntry(targetLocation string, hideSecrets bool, entryType uint8) {
if entryType == 0 { if entryType == 0 {
password = inputHidden("Password:") password = inputHidden("Password:")
} else { } else {
password = backend.StringGen(inputInt("Password length:", -1), inputBinary("Generate a complex (special characters) password?"), 0.2) password = backend.StringGen(inputInt("Password length:", -1), inputBinary("Generate a complex (special characters) password?"), 0.2, false)
} }
totp := inputHidden("TOTP secret:") totp := inputHidden("TOTP secret:")
+1 -1
View File
@@ -60,7 +60,7 @@ func GenUpdate(targetLocation string, hideSecrets bool) {
unencryptedEntry := backend.GetOldEntryData(targetLocation, 0) unencryptedEntry := backend.GetOldEntryData(targetLocation, 0)
// generate a new password // generate a new password
unencryptedEntry[0] = backend.StringGen(inputInt("Password length:", -1), inputBinary("Generate a complex (special characters) password?"), 0.2) unencryptedEntry[0] = backend.StringGen(inputInt("Password length:", -1), inputBinary("Generate a complex (special characters) password?"), 0.2, false)
// write and preview the modified entry // write and preview the modified entry
writeEntryCLI(targetLocation, unencryptedEntry, hideSecrets) writeEntryCLI(targetLocation, unencryptedEntry, hideSecrets)
+1 -1
View File
@@ -38,7 +38,7 @@ func TempInitCli() {
sshUser := input("Remote SSH username:") sshUser := input("Remote SSH username:")
sshPort := input("Remote SSH port:") sshPort := input("Remote SSH port:")
sshIP := input("Remote SSH IP/domain:") sshIP := input("Remote SSH IP/domain:")
sshKey := expandPathWithHome(input("SSH private identity file path:")) // TODO implement generator and selector sshKey := expandPathWithHome(input("SSH private identity file path:"))
sshKeyProtected := inputBinary("Is the identity file password-protected?") sshKeyProtected := inputBinary("Is the identity file password-protected?")
// initialize libmutton directories // initialize libmutton directories
-1
View File
@@ -24,7 +24,6 @@ This program comes with absolutely no warranty; type "mutn version" for details.
help Bring up this menu help Bring up this menu
version Display version and license information version Display version and license information
init Set up MUTN (generates libmutton.ini) init Set up MUTN (generates libmutton.ini)
tweak Change configuration options (NOT YET IMPLEMENTED)
copy Copy details of an entry to your clipboard copy Copy details of an entry to your clipboard
edit Edit an existing entry edit Edit an existing entry
gen Generate a new password gen Generate a new password
+3 -2
View File
@@ -2,12 +2,13 @@ package sync
import ( import (
"fmt" "fmt"
"github.com/rwinkhart/MUTN/src/backend"
"math/rand" "math/rand"
"os" "os"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"github.com/rwinkhart/MUTN/src/backend"
) )
// DeviceIDGen generates a new client device ID and registers it with the server // DeviceIDGen generates a new client device ID and registers it with the server
@@ -16,7 +17,7 @@ import (
// returns the remote EntryRoot and OS type (OS type is a bool: backend.IsWindows) // returns the remote EntryRoot and OS type (OS type is a bool: backend.IsWindows)
func DeviceIDGen() (string, string) { func DeviceIDGen() (string, string) {
deviceIDPrefix, _ := os.Hostname() deviceIDPrefix, _ := os.Hostname()
deviceIDSuffix := backend.StringGen(rand.Intn(32)+48, false, 0) + "-" + strconv.FormatInt(time.Now().Unix(), 10) // TODO consider using complex string generator and removing unsafe characters manually deviceIDSuffix := backend.StringGen(rand.Intn(32)+48, true, 0.2, true) + "-" + strconv.FormatInt(time.Now().Unix(), 10)
deviceID := deviceIDPrefix + "-" + deviceIDSuffix deviceID := deviceIDPrefix + "-" + deviceIDSuffix
_, err := os.Create(backend.ConfigDir + backend.PathSeparator + "devices" + backend.PathSeparator + deviceID) // TODO remove existing device ID file if it exists (from both client and server) _, err := os.Create(backend.ConfigDir + backend.PathSeparator + "devices" + backend.PathSeparator + deviceID) // TODO remove existing device ID file if it exists (from both client and server)
if err != nil { if err != nil {