diff --git a/emails.go b/emails.go index e355922..b85a66e 100644 --- a/emails.go +++ b/emails.go @@ -2,8 +2,6 @@ package scsusers import ( "bytes" - "crypto/rand" - "encoding/base32" "fmt" "log" "net/smtp" @@ -16,7 +14,7 @@ func RecoverByEmail(email string) { if !ok { return } - recoverycode := randBytes(16) + recoverycode := generatePassword(16) u.Delete("recoverykey") u.Delete("recoverytime") @@ -26,15 +24,6 @@ func RecoverByEmail(email string) { SendRecoveryEmail(email, email, string(recoverycode)) } -func randBytes(n int) []byte { - randomBytes := make([]byte, 32) - _, err := rand.Read(randomBytes) - if err != nil { - panic(err) - } - return []byte(base32.StdEncoding.EncodeToString(randomBytes)[:n]) -} - func SendRegistrationEmail(recipient, username, password string) bool { data := struct { SiteName string diff --git a/main.go b/main.go index fe3d0a8..0c118c6 100644 --- a/main.go +++ b/main.go @@ -84,7 +84,7 @@ func Register(username, email, ip string) bool { } username = strings.ToLower(username) - pass := randBytes(16) + pass := generatePassword(16) crypt, err := bcrypt.GenerateFromPassword(pass, 10) if err != nil { log.Printf("scsusers.Register: Bcrypt GenerateFromPassword failed? Pass is %s and error is %s\n", pass, err.Error()) diff --git a/password.go b/password.go new file mode 100644 index 0000000..9850bdc --- /dev/null +++ b/password.go @@ -0,0 +1,81 @@ +package scsusers + +import ( + "crypto/rand" + "encoding/base32" + "unicode" +) + +func flipCoin() bool { + x := make([]byte, 1) + _, err := rand.Read(x) + if err != nil { + return true + } + if uint8(x[0]) % 2==0 { + return true + } + return false + +} +func scrambleCase(in []byte) []byte { + var out []byte + for _, x := range string(in) { + if unicode.IsUpper(x) { + + if flipCoin() { + out = append(out, byte(x)) + } else { + out = append(out, byte(unicode.ToLower(x))) + + } + } + } + return out +} + +func randBytes(n int) []byte { + randomBytes := make([]byte, 32) + _, err := rand.Read(randomBytes) + if err != nil { + panic(err) + } + return []byte(base32.StdEncoding.EncodeToString(randomBytes)[:n]) +} + +func generatePassword(n int) []byte { + for { + p := scrambleCase(randBytes(16)) + if hasDigit(p) && hasUppercase(p) && hasLowercase(p) { + return p + } + } + +} + +func hasDigit(in []byte) bool { + for _,x := range string(in) { + if unicode.IsDigit(x) { + return true + } + } + return false +} + +func hasUppercase(in []byte) bool { + for _,x:= range string(in) { + if unicode.IsUpper(x) { + return true + } + } + return false +} + +func hasLowercase(in []byte) bool { + for _,x := range string(in) { + if unicode.IsLower(x) { + return true + } + } + return false +}