apg-go/config.go
Winni Neessen 5a29d4bc19
Added optional HIBP database check
Even though the generated passwords are generated in a secure
way, there is a minimal chance, that the same password was used
by someone before and this password was part of a leak.

If you want to be on the safe side, you can now use the "-p"
parameter, to have your newly generated password against the
HIBP (https://haveibeenpwned.com) database. This feature is
disabled by default, since it requires internet access and also
the API call might take ~500ms to 1sec.
2021-04-29 12:22:10 +02:00

164 lines
4.4 KiB
Go

package main
import (
"flag"
"log"
)
// Parse the CLI flags
func parseFlags() Config {
var switchConf Config
defaultSwitches := Config{
useLowerCase: true,
useUpperCase: true,
useNumber: true,
useSpecial: false,
useComplex: false,
humanReadable: false,
}
config := Config{
useLowerCase: defaultSwitches.useLowerCase,
useUpperCase: defaultSwitches.useUpperCase,
useNumber: defaultSwitches.useNumber,
useSpecial: defaultSwitches.useSpecial,
useComplex: defaultSwitches.useComplex,
humanReadable: defaultSwitches.humanReadable,
}
// Read and set all flags
flag.BoolVar(&switchConf.useLowerCase, "L", false, "Use lower case characters in passwords")
flag.BoolVar(&switchConf.useUpperCase, "U", false, "Use upper case characters in passwords")
flag.BoolVar(&switchConf.useNumber, "N", false, "Use numerich characters in passwords")
flag.BoolVar(&switchConf.useSpecial, "S", false, "Use special characters in passwords")
flag.BoolVar(&switchConf.useComplex, "C", false, "Generate complex passwords (implies -L -U -N -S, disables -H)")
flag.BoolVar(&switchConf.humanReadable, "H", false, "Generate human-readable passwords")
flag.BoolVar(&config.spellPassword, "l", false, "Spell generated password")
flag.BoolVar(&config.checkHibp, "p", false, "Check the HIBP database if the generated password was leaked before")
flag.BoolVar(&config.showVersion, "v", false, "Show version")
flag.IntVar(&config.minPassLen, "m", DefaultMinLenght, "Minimum password length")
flag.IntVar(&config.maxPassLen, "x", DefaultMaxLenght, "Maxiumum password length")
flag.IntVar(&config.numOfPass, "n", 6, "Number of passwords to generate")
flag.StringVar(&config.excludeChars, "E", "", "Exclude list of characters from generated password")
flag.StringVar(&config.newStyleModes, "M", "",
"New style password parameters (higher priority than single parameters)")
flag.Parse()
// Invert-switch the defaults
if switchConf.useLowerCase {
config.useLowerCase = !defaultSwitches.useLowerCase
}
if switchConf.useUpperCase {
config.useUpperCase = !defaultSwitches.useUpperCase
}
if switchConf.useNumber {
config.useNumber = !defaultSwitches.useNumber
}
if switchConf.useSpecial {
config.useSpecial = !defaultSwitches.useSpecial
}
if switchConf.useComplex {
config.useComplex = !defaultSwitches.useComplex
}
if switchConf.humanReadable {
config.humanReadable = !defaultSwitches.humanReadable
}
// Parse additional parameters and new-style switches
parseParams(&config)
return config
}
// Parse the parameters and set the according config flags
func parseParams(config *Config) {
parseNewStyleParams(config)
// Complex overrides everything
if config.useComplex {
config.useUpperCase = true
config.useLowerCase = true
config.useSpecial = true
config.useNumber = true
config.humanReadable = false
}
if config.useUpperCase == false &&
config.useLowerCase == false &&
config.useNumber == false &&
config.useSpecial == false {
log.Fatalf("No password mode set. Cannot generate password from empty character set.")
}
// Set output mode
if config.spellPassword {
config.outputMode = 1
}
}
// Get the password length from the given cli flags
func getPwLengthFromParams(config *Config) int {
if config.minPassLen > config.maxPassLen {
config.maxPassLen = config.minPassLen
}
lenDiff := config.maxPassLen - config.minPassLen + 1
randAdd, err := getRandNum(lenDiff)
if err != nil {
log.Fatalf("Failed to generated password length: %v", err)
}
retVal := config.minPassLen + randAdd
if retVal <= 0 {
return 1
}
return retVal
}
// Parse the new style parameters
func parseNewStyleParams(config *Config) {
if config.newStyleModes == "" {
return
}
for _, curParam := range config.newStyleModes {
switch curParam {
case 'S':
config.useSpecial = true
break
case 's':
config.useSpecial = false
break
case 'N':
config.useNumber = true
break
case 'n':
config.useNumber = false
break
case 'L':
config.useLowerCase = true
break
case 'l':
config.useLowerCase = false
break
case 'U':
config.useUpperCase = true
break
case 'u':
config.useUpperCase = false
break
case 'H':
config.humanReadable = true
break
case 'h':
config.humanReadable = false
break
case 'C':
config.useComplex = true
break
case 'c':
config.useComplex = false
break
default:
log.Fatalf("Unknown password style parameter: %q\n", string(curParam))
}
}
}