mirror of
https://github.com/wneessen/apg-go.git
synced 2024-11-10 00:02:54 +01:00
v0.1.0: Initial check-in
This commit is contained in:
parent
ebdad33364
commit
5d743f70ae
8 changed files with 209 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,6 +4,7 @@
|
||||||
*.dll
|
*.dll
|
||||||
*.so
|
*.so
|
||||||
*.dylib
|
*.dylib
|
||||||
|
apg
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
# Test binary, built with `go test -c`
|
||||||
*.test
|
*.test
|
||||||
|
|
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
9
.idea/apg.go.iml
Normal file
9
.idea/apg.go.iml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
12
.idea/inspectionProfiles/Project_Default.xml
Normal file
12
.idea/inspectionProfiles/Project_Default.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="GrazieInspection" enabled="false" level="TYPO" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="LanguageDetectionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||||
|
<option name="processCode" value="true" />
|
||||||
|
<option name="processLiterals" value="true" />
|
||||||
|
<option name="processComments" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/apg.go.iml" filepath="$PROJECT_DIR$/.idea/apg.go.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
30
README.md
30
README.md
|
@ -1,2 +1,30 @@
|
||||||
# apg.go
|
# apg.go
|
||||||
Advanced Password Generator Clone
|
_apg.pl_ is a simple APG-like password generator script written in Go. It tries to replicate the functionality of the "[Automated Password Generator](https://web.archive.org/web/20130313042424/http://www.adel.nursat.kz:80/apg)", which hasn't been maintained since 2003. Since more and more Unix distributions are abondoning the tool, I was looking for an alternative. FreeBSD for example recommends "security/makepasswd", which is also written in Perl but requires much more dependency packages and doesn't offer the feature-set/flexibility of APG. Therefore I decided to write my own implementation. As I never used the "pronouncable password" functionality, I left this out in my version.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
Simply add the execute-flag to the script and run it
|
||||||
|
```sh
|
||||||
|
$ chmod +x apg
|
||||||
|
$ ./apg
|
||||||
|
```
|
||||||
|
|
||||||
|
## Systemwide installation
|
||||||
|
To be a proper APG replacement, i suggest to install it into a directory in your PATH and symlink it to "apg":
|
||||||
|
```sh
|
||||||
|
$ sudo cp apg /usr/local/bin/apg
|
||||||
|
```
|
||||||
|
|
||||||
|
## CLI options
|
||||||
|
_apg.go_ replicates some of the parameters of the original APG. Some parameters are different though:
|
||||||
|
|
||||||
|
- ```-m, --minpasslen <length>```: The minimum length of the password to be generated
|
||||||
|
- ```-x, --maxpasslen <length>```: The maximum length of the password to be generated
|
||||||
|
- ```-n, --numofpass <number of passwords>```: The amount of passwords to be generated
|
||||||
|
- ```-E, --exclude <list of characters>```: Do not use the specified characters in generated passwords
|
||||||
|
- ```-U, --uppercase```: Use uppercase characters in passwords
|
||||||
|
- ```-N, --numbers```: Use numeric characters in passwords
|
||||||
|
- ```-S, --special```: Use special characters in passwords
|
||||||
|
- ```-H, --human```: Avoid ambiguous characters in passwords (i. e.: 1, l, I, o, O, 0)
|
||||||
|
- ```-c, --complex```: Generate complex passwords (implies -U -N -S and disables -H)
|
||||||
|
- ```-h, --help```: Show a CLI help text
|
||||||
|
- ```-v, --version```: Show the version number
|
136
apg.go
Normal file
136
apg.go
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"math/big"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
const DefaultPwLenght int = 20
|
||||||
|
const VersionString string = "0.1.0"
|
||||||
|
const PwLowerCharsHuman string = "abcdefghjkmnpqrstuvwxyz"
|
||||||
|
const PwUpperCharsHuman string = "ABCDEFGHJKMNPQRSTUVWXYZ"
|
||||||
|
const PwLowerChars string = "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
const PwUpperChars string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
const PwSpecialCharsHuman string = "\"#/\\$%&+-*"
|
||||||
|
const PwSpecialChars string = "\"#/!\\$%&+-*.,?=()[]{}:;~^|"
|
||||||
|
const PwNumbersHuman string = "23456789"
|
||||||
|
const PwNumbers string = "1234567890"
|
||||||
|
|
||||||
|
type cliOpts struct {
|
||||||
|
minPassLen int
|
||||||
|
maxPassLen int
|
||||||
|
numOfPass int
|
||||||
|
useComplex bool
|
||||||
|
useLowerCase bool
|
||||||
|
useUpperCase bool
|
||||||
|
useNumber bool
|
||||||
|
useSpecial bool
|
||||||
|
humanReadable bool
|
||||||
|
excludeChars string
|
||||||
|
showHelp bool
|
||||||
|
showVersion bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var config cliOpts
|
||||||
|
|
||||||
|
// Read flags
|
||||||
|
func init() {
|
||||||
|
// Bool flags
|
||||||
|
flag.BoolVar(&config.useLowerCase, "L", true, "Use lower case characters in passwords")
|
||||||
|
flag.BoolVar(&config.useUpperCase, "U", false, "Use upper case characters in passwords")
|
||||||
|
flag.BoolVar(&config.useNumber, "N", false, "Use numbers in passwords")
|
||||||
|
flag.BoolVar(&config.useSpecial, "S", false, "Use special characters in passwords")
|
||||||
|
flag.BoolVar(&config.useComplex, "C", true, "Generate complex passwords (implies -L -U -N -S, disables -H)")
|
||||||
|
flag.BoolVar(&config.humanReadable, "H", false, "Generate human-readable passwords")
|
||||||
|
flag.BoolVar(&config.showVersion, "v", false, "Show version")
|
||||||
|
|
||||||
|
// Int flags
|
||||||
|
flag.IntVar(&config.minPassLen, "m", 10, "Minimum password length")
|
||||||
|
flag.IntVar(&config.maxPassLen, "x", DefaultPwLenght, "Maxiumum password length")
|
||||||
|
flag.IntVar(&config.numOfPass, "n", 1, "Number of passwords to generate")
|
||||||
|
|
||||||
|
// TODO: Exclude chars are missing, yet
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
if config.showVersion {
|
||||||
|
_, _ = os.Stderr.WriteString("Advanced Password Generator v" + VersionString + "\n")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
pwLength := config.minPassLen
|
||||||
|
if pwLength < config.minPassLen {
|
||||||
|
pwLength = config.minPassLen
|
||||||
|
}
|
||||||
|
if pwLength > config.maxPassLen {
|
||||||
|
pwLength = config.maxPassLen
|
||||||
|
}
|
||||||
|
if config.useComplex {
|
||||||
|
config.useUpperCase = true
|
||||||
|
config.useLowerCase = true
|
||||||
|
config.useSpecial = true
|
||||||
|
config.useNumber = true
|
||||||
|
config.humanReadable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
pwUpperChars := PwUpperChars
|
||||||
|
pwLowerChars := PwLowerChars
|
||||||
|
pwNumbers := PwNumbers
|
||||||
|
pwSpecialChars := PwSpecialChars
|
||||||
|
if config.humanReadable {
|
||||||
|
pwUpperChars = PwUpperCharsHuman
|
||||||
|
pwLowerChars = PwLowerCharsHuman
|
||||||
|
pwNumbers = PwNumbersHuman
|
||||||
|
pwSpecialChars = PwSpecialCharsHuman
|
||||||
|
}
|
||||||
|
|
||||||
|
var charRange string
|
||||||
|
if config.useLowerCase {
|
||||||
|
charRange = charRange + pwLowerChars
|
||||||
|
}
|
||||||
|
if config.useUpperCase {
|
||||||
|
charRange = charRange + pwUpperChars
|
||||||
|
}
|
||||||
|
if config.useNumber {
|
||||||
|
charRange = charRange + pwNumbers
|
||||||
|
}
|
||||||
|
if config.useSpecial {
|
||||||
|
charRange = charRange + pwSpecialChars
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
for i := 1; i <= config.numOfPass; i++ {
|
||||||
|
fmt.Println(i)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
pwString := getRandChar(&charRange, pwLength)
|
||||||
|
fmt.Println(pwString)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRandChar(charRange *string, pwLength int) string {
|
||||||
|
availCharsLength := len(*charRange)
|
||||||
|
charSlice := []byte(*charRange)
|
||||||
|
returnString := []byte{}
|
||||||
|
for i := 0; i < pwLength; i++ {
|
||||||
|
randNum := getRandNum(availCharsLength)
|
||||||
|
returnString = append(returnString, charSlice[randNum])
|
||||||
|
}
|
||||||
|
return string(returnString)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRandNum(maxNum int) int {
|
||||||
|
maxNumBigInt := big.NewInt(int64(maxNum))
|
||||||
|
randNum64, err := rand.Int(rand.Reader, maxNumBigInt)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("An error occured generating random number: %v", err)
|
||||||
|
}
|
||||||
|
randNum := int(randNum64.Int64())
|
||||||
|
return randNum
|
||||||
|
}
|
Loading…
Reference in a new issue