before adding cryptoshuffler

This commit is contained in:
brent s. 2022-03-03 05:51:22 -05:00
parent 480dcd7e24
commit 77d5271b5a
Signed by: bts
GPG Key ID: 8C004C2F93481F6B
5 changed files with 116 additions and 23 deletions

View File

@ -2,16 +2,17 @@ package main

// Arguments contains the invocation arguments.
type Arguments struct {
NoAlpha bool `short:"a" long:"disable-alpha" description:"If specified, do NOT include the Alphabetical (letter) charset."`
NoNum bool `short:"n" long:"disable-num" description:"If specified, do NOT include the Numerical (number) charset."`
NoSymbols bool `short:"s" long:"disable-symbols" description:"If specified, do NOT include the Simple Symbols charset."`
ExtendSymbols bool `short:"S" long:"enable-extended-symbols" description:"If specified, include the Extended Symbols charset (these characters may cause issues in some applications)."`
NumUpper uint `short:"u" long:"count-upper" description:"The number of minimum uppercase characters. If not specified, this is random (if in the charset)."`
NumLower uint `short:"U" long:"count-lower" description:"The number of minimum lowercase characters. If not specified, this is random (if in the charset)."`
NumSymbols uint `short:"y" long:"count-symbols" description:"The number of minimum simple symbol characters. If not specified, this is random (if in the charset)."`
NumExtended uint `short:"Y" long:"count-extended" description:"The number of minimum extended symbol characters. If not specified, this is random (if in the charset)."`
DisableChars uint `short:"d" long:"disable-chars" description:"If specified, this string of chars should be explicitly excluded from the charset(s)."`
MinLen uint `short:"l" long:"min-length" default:"16" description:"The minimum length for passwords; use 0 for no minimum limit. Set this to the same as -L/--max-length to use a fixed length."`
MaxLen uint `short:"L" long:"max-length" default:"64" description:"The maximum length for passwords; use 0 for no maximum limit (this is hard-capped to 256 for performance reasons). Set this to the same as -l/--min-length for a fixed length. Must be >= -l/--min-length."`
Count uint `short:"c" long:"count" default:"1" description:"The number of passwords to generate."`
NoAlpha bool `short:"a" long:"disable-alpha" description:"If specified, do NOT include the Alphabetical (letter) charset."`
NoNum bool `short:"n" long:"disable-num" description:"If specified, do NOT include the Numerical (number) charset."`
NoSymbols bool `short:"s" long:"disable-symbols" description:"If specified, do NOT include the Simple Symbols charset."`
ExtendSymbols bool `short:"S" long:"enable-extended-symbols" description:"If specified, include the Extended Symbols charset (these characters may cause issues in some applications)."`
NumUpper uint `short:"u" long:"count-upper" description:"The number of minimum uppercase characters. If not specified, this is random (if in the charset)."`
NumLower uint `short:"U" long:"count-lower" description:"The number of minimum lowercase characters. If not specified, this is random (if in the charset)."`
NumSymbols uint `short:"y" long:"count-symbols" description:"The number of minimum simple symbol characters. If not specified, this is random (if in the charset)."`
NumExtended uint `short:"Y" long:"count-extended" description:"The number of minimum extended symbol characters. If not specified, this is random (if in the charset)."`
DisableChars []string `short:"d" long:"disable-chars" description:"If specified, these chars should be explicitly excluded from the charset(s). Can be specified multiple times with multiple chars per switch."`
ExplicitChars []string `short:"e" long:"explicit-chars" description:"If specified, ignore all charset selection and only use these characters to select from. Can be specified multiple times."`
MinLen uint `short:"l" long:"min-length" default:"16" description:"The minimum length for passwords; use 0 for no minimum limit. Set this to the same as -L/--max-length to use a fixed length."`
MaxLen uint `short:"L" long:"max-length" default:"64" description:"The maximum length for passwords; use 0 for no maximum limit (this is hard-capped to 256 for performance reasons). Set this to the same as -l/--min-length for a fixed length. Must be >= -l/--min-length."`
Count uint `short:"c" long:"count" default:"1" description:"The number of passwords to generate."`
}

View File

@ -4,6 +4,7 @@ import (
"fmt"
"log"
"os"
"strings"

"github.com/jessevdk/go-flags"
"r00t2.io/pwgen/pwgenerator"
@ -15,6 +16,7 @@ func main() {

var err error
var genOpts *pwgenerator.GenOpts
var passwds []string

if _, err = flags.Parse(&a); err != nil {
switch flagsErr := err.(type) {
@ -42,8 +44,23 @@ func main() {
LengthMax: a.MaxLen,
Count: a.Count,
}
if a.DisableChars != nil && len(a.DisableChars) != 0 {
if genOpts.DisabledChars, err = pwgenerator.GetCharset(a.DisableChars); err != nil {
log.Panicln(err)
}
}
if a.ExplicitChars != nil && len(a.ExplicitChars) != 0 {
if err = genOpts.SetExplicitCharset(a.ExplicitChars, false); err != nil {
log.Panicln(err)
}
}

fmt.Printf("%#v\n", a)
fmt.Printf("%#v\n", genOpts)
if passwds, err = genOpts.Generate(); err != nil {
log.Panicln(err)
}

fmt.Println(strings.Join(passwds, "\n"))

// fmt.Printf("%#v\n", a)
// fmt.Printf("%#v\n", genOpts)
}

View File

@ -1,12 +1,37 @@
package pwgenerator

import (
"bytes"
"crypto/rand"
"math/big"
"sort"
"strings"
)

/*
GetCharset returns a CharSet from a set of characters.

chars can be one of []rune, []byte, []string, or string.
*/
func GetCharset(chars interface{}) (charset CharSet, err error) {

switch t := chars.(type) {
case []rune:
charset = CharSet(string(t))
case []byte:
charset = CharSet(string(t))
case []string:
s := strings.Join(t, "")
charset = CharSet(s)
case string:
charset = CharSet(t)
default:
err = ErrBadType
return
}

return
}

// sortDedupe sorts a slice of runes and deduplicates them.
func sortDedupe(charset *CharSet) {

@ -42,12 +67,16 @@ func sortDedupe(charset *CharSet) {
*/
func saferRandInt(max int) (randInt int, err error) {

// Avoid a panic on max being 0 per rand.Int.
if max == 0 {
max = 1
}

var max64 int64 = int64(max)
var cryptoInt *big.Int = big.NewInt(max64)
var cryptoReader *bytes.Buffer = new(bytes.Buffer)
var randInt64 int64

if cryptoInt, err = rand.Int(cryptoReader, cryptoInt); err != nil {
if cryptoInt, err = rand.Int(rand.Reader, cryptoInt); err != nil {
return
}


View File

@ -1,5 +1,42 @@
package pwgenerator

/*
Has returns true if a CharSet contains char.

char can be one of: Char, byte, rune, or a string (of length 1).
*/
func (c *CharSet) Has(char interface{}) (contains bool, err error) {

var chkChar Char

switch t := char.(type) {
case Char:
chkChar = t
case byte:
chkChar = Char(t)
case rune:
chkChar = Char(t)
case string:
if len(t) != 1 {
err = ErrBadType
return
}
chkChar = Char(t[0])
default:
err = ErrBadType
return
}

for _, i := range *c {
if chkChar == i {
contains = true
break
}
}

return
}

// Len returns the length of a CharSet (needed for sort.Interface).
func (c *CharSet) Len() (l int) {

@ -23,7 +60,7 @@ func (c *CharSet) RandChar() (char Char, err error) {

var selectIdx int

if selectIdx, err = saferRandInt(len(*c) - 1); err != nil {
if selectIdx, err = saferRandInt(len(*c)); err != nil {
return
}


View File

@ -71,14 +71,23 @@ func (o *GenOpts) generatePassword(c CharSet) (password string, err error) {
// And make the rune slice of that length.
passAlloc = make([]rune, passLen)

for _, idx := range passAlloc {
for idx, _ := range passAlloc {
var char Char

if char, err = c.RandChar(); err != nil {
return
}
for {
var isDisabled bool

passAlloc[idx] = rune(char)
if char, err = c.RandChar(); err != nil {
return
}
if isDisabled, err = o.DisabledChars.Has(char); err != nil || isDisabled {
err = nil
continue
}

passAlloc[idx] = rune(char)
break
}
}

password = string(passAlloc)