Skip to content

Instantly share code, notes, and snippets.

@betawaffle
Created February 27, 2018 14:58
Show Gist options
  • Save betawaffle/a8d1162af27ff7b48c2450eaf1260477 to your computer and use it in GitHub Desktop.
Save betawaffle/a8d1162af27ff7b48c2450eaf1260477 to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"crypto/sha1"
"encoding/hex"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
"golang.org/x/crypto/ssh/terminal"
)
func main() {
if terminal.IsTerminal(0) {
log.SetPrefix("[!] ")
log.SetFlags(log.Lmicroseconds)
} else {
log.Fatalf("stdin is not a terminal")
}
fmt.Fprintf(os.Stdin, "Password: ")
pass, err := terminal.ReadPassword(0)
fmt.Fprintln(os.Stdin)
if err != nil {
log.Fatal(err)
}
if err := checkPassword(pass); err != nil {
log.Fatal(err)
}
fmt.Printf("Nope, all good!")
}
func checkPassword(pass []byte) error {
sum := sha1.Sum(pass)
str := hex.EncodeToString(sum[:])
r, err := http.Get("https://api.pwnedpasswords.com/range/" + str[:5])
if err != nil {
return err
}
b, err := readClose(r.Body)
if err != nil {
return err
}
if r.StatusCode != 200 {
return fmt.Errorf("HTTP %d: body=%q", r.StatusCode, b)
}
if string(b[:len("\ufeff")]) == "\ufeff" {
b = b[len("\ufeff"):]
}
return checkSuffixCount(b, strings.ToUpper(str[5:]))
}
func checkSuffixCount(b []byte, suffix string) error {
const (
prefixLen = 5
suffixLen = sha1.Size*2 - prefixLen
)
if len(suffix) != suffixLen {
return errors.New("incorrect suffix length")
}
for len(b) >= suffixLen+2 {
if b[suffixLen] != ':' {
return fmt.Errorf("invalid response: missing colon in %q", b)
}
var match, count []byte
match, b = b[:suffixLen], b[suffixLen+1:]
if i := bytes.IndexByte(b, '\n'); i != -1 {
if b[i-1] == '\r' {
count, b = b[:i-1], b[i+1:]
} else {
count, b = b[:i], b[i+1:]
}
} else {
count, b = b, nil
}
if string(match) == suffix {
return fmt.Errorf("password has been pwned at least %d times", count)
}
}
return nil
}
func readClose(rc io.ReadCloser) ([]byte, error) {
b, err := ioutil.ReadAll(rc)
rc.Close()
return b, err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment