diff options
author | Dennis Eriksen <d@ennis.no> | 2023-09-14 20:25:53 +0200 |
---|---|---|
committer | Dennis Eriksen <d@ennis.no> | 2023-09-14 20:25:53 +0200 |
commit | 3116390ed05f46983dc955f9852d8dbeea041e15 (patch) | |
tree | 9d10bc2e1d28980d518b6b2d82867fa5bcf96fc5 /go/makepass.go | |
parent | Updated build-instructions for rust-version (diff) | |
download | makepass-3116390ed05f46983dc955f9852d8dbeea041e15.tar.gz |
Updated build-instructions for go-version
Diffstat (limited to 'go/makepass.go')
-rw-r--r-- | go/makepass.go | 331 |
1 files changed, 0 insertions, 331 deletions
diff --git a/go/makepass.go b/go/makepass.go deleted file mode 100644 index a5241a3..0000000 --- a/go/makepass.go +++ /dev/null @@ -1,331 +0,0 @@ -// -// Author : Dennis Eriksen <d@ennis.no> -// File : makepass.go -// Created : 2023-09-05 -// Licence : BSD-3-Clause -// -// Copyright (c) 2018-2023 Dennis Eriksen <d@ennis.no> - -package main - -import ( - "bufio" - "flag" - "fmt" - "golang.org/x/term" - "math/rand" - "os" - "strconv" - "strings" - "time" -) - -// Basic constant definitions -const ( - max = 255 // Maximum length of passwords - rangeMax = 42 // Maximum range for password length - rangeMin = 8 // Minimum range for password length - passWords = 8 // Number of words in passphrases - - lower = "abcdefghijklmnopqrstuvwxyz" - upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - digit = "0123456789" - other = "!$%&#/()=?+-_,.;:<>[]{}|@*" // Special characters for special passwords - - defaultFile = "/usr/share/dict/words" // Default path to the file of words used for passphrases -) - -// Variables for different types of passwords -var ( - alpha []string = strings.Split(lower+upper, "") // Array of alphabets (lowercase and uppercase) - alnum []string = append(alpha, strings.Split(digit, "")...) // Array of alphanumeric characters - every []string = append(alnum, strings.Split(other, "")...) // Array of all characters (alphabet, digit and special) - normal []string = append(alnum, "-", "_") // Characters for normal passwords - special []string = every // Characters for special passwords - wordlist string = defaultFile // Path to a dictionary to use for passphrases - colWidth int = 1 - colNum int = 1 - - length int = 0 // Length of passwords - number int = 10 - printBool bool = false - printLen int = 0 - help bool = false -) - -func main() { - - // define error-vars - var errl error // err for length - var errn error // err for number - - // Handle environment - if len(os.Getenv("MAKEPASS_LENGTH")) > 0 { - length, errl = strconv.Atoi(os.Getenv("MAKEPASS_LENGTH")) - } - if len(os.Getenv("MAKEPASS_NUMBER")) > 0 { - number, errn = strconv.Atoi(os.Getenv("MAKEPASS_NUMBER")) - } - // Get wordlist from env - if len(os.Getenv("MAKEPASS_WORDLIST")) > 0 { - wordlist = os.Getenv("MAKEPASS_WORDLIST") - } - - // - // Flag handling - // - flag.BoolVar(&help, "h", help, "print helptext") - flag.IntVar(&length, "l", length, "length of passwords to output\nmust be a number between 0 and "+strconv.Itoa(max)) - flag.IntVar(&number, "n", number, "number of passwords to output\nmust be a number between 1 and "+strconv.Itoa(max)) - flag.BoolVar(&printBool, "p", printBool, "print length of each password") - flag.Parse() - - if help { - printHelp() - } - - // Handle cmd-line args that are not flags - if len(flag.Args()) == 1 { - length, errl = strconv.Atoi(flag.Arg(0)) - } - - // - // Error handling - // - - // We take max one argument - if len(flag.Args()) > 1 { - fmt.Println("only one argument") - os.Exit(1) - } - - // If there is an error in conversion, or if the length is not within limits, exit the program with an error message - if errl != nil || (length > max || length < 0) { - fmt.Printf("length must be a number between 0 and %d.\n", max) - os.Exit(1) - } - if errn != nil || (number < 1 || max < number) { - fmt.Printf("number-argument must be between 1 and %d.\n", max) - os.Exit(1) - } - - // - // move on - // - - // initialise the random seed - // TODO: Get seed from /dev/random, like we do in the perl- and zsh-versions? - rand.Seed(time.Now().UnixNano()) - - // get screen width - termWidth, _, err := term.GetSize(0) - if err != nil { - termWidth = 0 - } - - // col width of printLen - if printBool { - // convert length to string and count length of string, and add one for space - // In the other versions we add the space when calculating colNum, but go doesn't support ternary operators. This way we don't need an extra if-statement. Just subtract the space when printing the length in printColumns(). - if length <= 100 { - printLen = 2 + 1 - } else { - printLen = 3 + 1 - } - } else { - printLen = 0 - } - - // column width - colWidth = rangeMax + 2 - if length > 0 { - colWidth = length + 2 - } - - // number of colums - colNum = termWidth / (colWidth + printLen) - if colNum == 0 { - colNum = 1 - } - - // - // print passwords - // - - // Generate and print normal and special passwords - printColumns("Normal passwords:", number, normal) - - fmt.Println("") - - printColumns("Passwords with special characters:", number/3*2+1, special) - - // Generate and print passphrases if wordlist exists - if _, err := os.Stat(wordlist); err == nil { - // Read wordlist from file - file, err := os.Open(wordlist) - if err != nil { - fmt.Printf("failed to open file: %s", err) - } - scanner := bufio.NewScanner(file) - scanner.Split(bufio.ScanLines) - var words []string - for scanner.Scan() { - words = append(words, scanner.Text()) - } - file.Close() - - // Print it - fmt.Println("") - fmt.Println("Passphrases:") - - for i := 0; i < number/2; i++ { - fmt.Println(passphrase(words)) - } - } -} - -// Function to generate and print passwords -func printColumns(title string, num int, chars []string) { - var strings []string - - for i := 0; i < num; i++ { - strings = append(strings, randstring(chars)) - } - - // Print title - fmt.Println(title) - - // Print passwords in neat columns - for i, str := range strings { - if printBool { - fmt.Printf("%0[1]*[2]d ", printLen-1, len(str)) - } - fmt.Printf("%-[1]*[2]s", colWidth, str) - if (i+1)%colNum == 0 || (i+1 == num && (i+1)%colNum > 0) { // Add newlines - fmt.Println("") - } - } -} - -// Function to generate a random string of given length from given characters -func randstring(chars []string) string { - l := length - if length == 0 { // Random length if not specified - l = rand.Intn(rangeMax-rangeMin+1) + rangeMin - } - var str strings.Builder - - // Add random characters to str - for i := 1; i <= l; i++ { - if i == 1 { // don't want passwords to start or end with special characters - str.WriteString(alnum[rand.Intn(len(alpha))]) - } else if i == l { - str.WriteString(alnum[rand.Intn(len(alnum))]) - } else { - str.WriteString(chars[rand.Intn(len(chars))]) - } - } - return str.String() -} - -// Function to generate passphrases -func passphrase(words []string) string { - var str strings.Builder - for i := 0; i < passWords; i++ { - str.WriteString(words[rand.Intn(len(words))]) // Write a random word to the passphrase - if i != passWords-1 { - str.WriteString("-") // Add hyphen between words - } - } - return str.String() -} - -// Help-function -func printHelp() { - fmt.Println(`NAME - makepass - create several random passwords - -SYNOPSIS - makepass [OPTIONS] [NUM] - - If a NUM is provided, passwords will be NUM characters long. - - By default ` + "`makepass`" + ` will output passwords from the three following classes: - - - Normal passwords - random strings with letters (both lower and upper - case), numbers, and dashes and underscores. - - - Passwords with special characters - random strings generated from lower - and upper case letters, numbers, and the following characters: - !#$%&/()=?+-_,.;:<>[]{}|@* - - - Passphrases - if we find a dictionary, a series of eight random words - from the dictionary, separated by dashes. The number of words can not be - changed, but you do not have to use all of them. Use as mane as you want. - - The first character will always be alphabetic, and the last will always be - alphanumeric. - -DESCRIPTION - makepass has the following options: - - -h - output this help-text - -l - length of passwords. See MAKEPASS_LENGTH below - -n - number of passwords. See MAKEPASS_NUMBER below - -p - print length of number - -ENVIRONMENT - makepass examines the following environmental variables. - - MAKEPASS_LENGTH - Specifies the length of passwords. Valid values are 0-255. If 0, a - random value between 8 and 42 will be used for each password. -l - overrides this environmental variable, and the argument NUM overrides - that again. So ` + "MAKEPASS_LENGTH=10 makepass -l 12 14" + ` will give - passwords that are 14 characters long, even though both -l and - MAKEPASS_LENGTH also specifies a length. - - MAKEPASS_NUMBER - The number of passwords to generate. This formula is used to determine - how many passwords from each group should be generated: - - (n) normal passwords - - (n / 3 * 2 + 1) special passwords - - (n / 2) passphrases - Where n is 10 by default. Valid values for n are 1-255. Floating-poing - math is not used, so results may vary. - - MAKEPASS_PRINTLEN - If 1, print length of all passwords. If 0, don\'t. - - MAKEPASS_NORMAL - String of characters from which to generate "normal" passwords. - Defaults to: - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_ - - MAKEPASS_SPECIAL - String of characters from which to generate passwords with special - characters. Defaults to the same characters as in MAKEPASS_NORMAL, plus - these: - !#$%&/()=?+-_,.;:<>[]{}|@* - - MAKEPASS_WORDLIST - Specifies the dictionary we find words for passphrases in. If this is - unset or empty, we try "/usr/share/dict/words". If that file does not - exist, no passphrases will be provided. - -NOTES - This scripts makes use of $RANDOM - a builtin in zsh which produces a - pseudo-random integer between 0 and 32767, newly generated each time the - parameter is referenced. We initially seed the random number generator with - a random 32bit integer generated from /dev/random. This should provide - enough randomnes to generate sufficiently secure passwords. - -AUTHOR - Dennis Eriksen <https://dnns.no>`) - os.Exit(0) - -} |