Compare commits
16 Commits
v1.3.0
...
fe11983dab
| Author | SHA1 | Date | |
|---|---|---|---|
| fe11983dab | |||
| 1e93add7bd | |||
| c328726ed0 | |||
| 7e826b75d7 | |||
| 72f4797428 | |||
| aad2144e7c | |||
| a1c8d6e531 | |||
| 0d5d7503ec | |||
| ee1a0fedcc | |||
| 3fc3f35bb5 | |||
| 9a98788476 | |||
| 43b8d3b618 | |||
| 6d1e700d8b | |||
| 1b2fcd72b9 | |||
| 6c20c7bb8b | |||
| f5289baecd |
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -14,8 +15,9 @@ import (
|
|||||||
var allowedCharacters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890`~!@#$%^&*()_+[]\\{}|;':,./<>?")
|
var allowedCharacters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890`~!@#$%^&*()_+[]\\{}|;':,./<>?")
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "1.3.0"
|
Version = "1.3.4"
|
||||||
symbols = "`~!@#$%^&*()_+[]\\{}|;':,./<>?"
|
symbols = "`~!@#$%^&*()_+[]\\{}|;':,./<>?"
|
||||||
|
chunkSize = 16 // The size of each chunk of the password to be generated by the worker goroutines
|
||||||
)
|
)
|
||||||
|
|
||||||
func matchArguments(args []string) string {
|
func matchArguments(args []string) string {
|
||||||
@@ -26,11 +28,10 @@ func matchArguments(args []string) string {
|
|||||||
|
|
||||||
// First argument is special, must be an integer, -v, or -h
|
// First argument is special, must be an integer, -v, or -h
|
||||||
var size = 0 // Password length
|
var size = 0 // Password length
|
||||||
err := error(nil)
|
switch args[0] {
|
||||||
if size, err = strconv.Atoi(args[0]); err == nil { // If first argument is an integer
|
case "-v":
|
||||||
} else if args[0] == "-v" {
|
|
||||||
return "GoPass version " + Version
|
return "GoPass version " + Version
|
||||||
} else if args[0] == "-h" {
|
case "-h":
|
||||||
return "GoPass - A simple password generator written in Go\n" +
|
return "GoPass - A simple password generator written in Go\n" +
|
||||||
"Usage: gopass [length] [disallowed characters] [optional remove symbols -s]\n" +
|
"Usage: gopass [length] [disallowed characters] [optional remove symbols -s]\n" +
|
||||||
" Example: gopass 16\n" +
|
" Example: gopass 16\n" +
|
||||||
@@ -38,16 +39,23 @@ func matchArguments(args []string) string {
|
|||||||
" Example: gopass 16 -s\n" +
|
" Example: gopass 16 -s\n" +
|
||||||
"\nFor help (this output): gopass -h\n" +
|
"\nFor help (this output): gopass -h\n" +
|
||||||
"For version: gopass -v\n"
|
"For version: gopass -v\n"
|
||||||
|
default:
|
||||||
|
err := error(nil)
|
||||||
|
size, err = strconv.Atoi(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return "Invalid first argument (\"" + args[0] + "\") supplied! (Type gopass -h for help)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 1; i < len(args); i++ {
|
for i := 1; i < len(args); i++ {
|
||||||
v := args[i]
|
v := args[i]
|
||||||
if v == "-s" {
|
switch {
|
||||||
|
case v == "-s":
|
||||||
removeDisallowed([]rune(symbols))
|
removeDisallowed([]rune(symbols))
|
||||||
} else if strings.HasPrefix(v, "-r=") { // If argument starts with -r=
|
case strings.HasPrefix(v, "-r="):
|
||||||
// Remove all characters after the = until next whitespace
|
// Remove all characters after the = until next whitespace
|
||||||
removeDisallowed([]rune(v[2:]))
|
removeDisallowed([]rune(v[2:]))
|
||||||
} else {
|
default:
|
||||||
return "Invalid argument (\"" + v + "\") supplied! (Type gopass -h for help)"
|
return "Invalid argument (\"" + v + "\") supplied! (Type gopass -h for help)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,28 +69,57 @@ func matchArguments(args []string) string {
|
|||||||
|
|
||||||
// Remove all disallowed characters from the allowedCharacters slice
|
// Remove all disallowed characters from the allowedCharacters slice
|
||||||
func removeDisallowed(disallowed []rune) {
|
func removeDisallowed(disallowed []rune) {
|
||||||
|
disallowedMap := make(map[rune]bool, len(disallowed))
|
||||||
for _, r := range disallowed {
|
for _, r := range disallowed {
|
||||||
for i, v := range allowedCharacters {
|
disallowedMap[r] = true
|
||||||
if v == r {
|
}
|
||||||
allowedCharacters = append(allowedCharacters[:i], allowedCharacters[i+1:]...)
|
|
||||||
}
|
i := 0
|
||||||
|
for _, v := range allowedCharacters {
|
||||||
|
if !disallowedMap[v] {
|
||||||
|
allowedCharacters[i] = v
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
allowedCharacters = allowedCharacters[:i]
|
||||||
}
|
}
|
||||||
|
|
||||||
func generatePassword(size int) string {
|
func generatePassword(size int) string {
|
||||||
// Make empty array of runes with size of size
|
// Make empty array of runes with size of size
|
||||||
pass := make([]rune, size)
|
pass := make([]rune, size)
|
||||||
|
|
||||||
// Assign every slot of pass to a random allowedCharacter
|
// Create a channel to receive chunks of the password
|
||||||
for i := range pass {
|
passChan := make(chan []rune)
|
||||||
// Generate a random int greater than 0 and not to exceed the length of allowedCharacters
|
|
||||||
index, err := rand.Int(rand.Reader, big.NewInt(int64(len(allowedCharacters))))
|
// Determine the number of worker goroutines to use
|
||||||
if err != nil {
|
numWorkers := runtime.NumCPU()
|
||||||
println("Error securely generating random character!")
|
|
||||||
return ""
|
// Launch the worker goroutines
|
||||||
}
|
for i := 0; i < numWorkers; i++ {
|
||||||
pass[i] = allowedCharacters[index.Int64()]
|
go func() {
|
||||||
|
allowedLen := len(allowedCharacters)
|
||||||
|
for {
|
||||||
|
// Generate a chunk of the password
|
||||||
|
chunk := make([]rune, chunkSize)
|
||||||
|
for i := range chunk {
|
||||||
|
index, err := rand.Int(rand.Reader, big.NewInt(int64(allowedLen)))
|
||||||
|
if err != nil {
|
||||||
|
println("Error securely generating random character chunk!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
chunk[i] = allowedCharacters[index.Int64()]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the chunk of the password to the main goroutine
|
||||||
|
passChan <- chunk
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect the chunks of the password from the channel
|
||||||
|
for i := 0; i < size; i += chunkSize {
|
||||||
|
chunk := <-passChan
|
||||||
|
copy(pass[i:], chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(pass)
|
return string(pass)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# The current version number of the program
|
# The current version number of the program
|
||||||
VERSION := 1.3.0
|
VERSION := 1.3.4
|
||||||
|
|
||||||
# List of OS and architecture combinations to build
|
# List of OS and architecture combinations to build
|
||||||
BUILD_OS_ARCH := \
|
BUILD_OS_ARCH := \
|
||||||
|
|||||||
Reference in New Issue
Block a user