aboutsummaryrefslogtreecommitdiffstats
path: root/go/makepass.go
diff options
context:
space:
mode:
authorDennis Eriksen <d@ennis.no>2023-09-14 20:25:53 +0200
committerDennis Eriksen <d@ennis.no>2023-09-14 20:25:53 +0200
commit3116390ed05f46983dc955f9852d8dbeea041e15 (patch)
tree9d10bc2e1d28980d518b6b2d82867fa5bcf96fc5 /go/makepass.go
parentUpdated build-instructions for rust-version (diff)
downloadmakepass-3116390ed05f46983dc955f9852d8dbeea041e15.tar.gz
Updated build-instructions for go-version
Diffstat (limited to 'go/makepass.go')
-rw-r--r--go/makepass.go331
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)
-
-}