summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--META6.json19
-rw-r--r--bin/orion3
-rw-r--r--cmd/orion/orion.go55
-rw-r--r--go.mod9
-rw-r--r--go.sum30
-rw-r--r--hibp/hash.go15
-rw-r--r--hibp/pwned.go40
-rw-r--r--hibp/req.go56
-rw-r--r--lib/Orion/CLI.rakumod8
10 files changed, 31 insertions, 205 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4a5e4c7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+lib/.precomp
diff --git a/META6.json b/META6.json
new file mode 100644
index 0000000..e04f841
--- /dev/null
+++ b/META6.json
@@ -0,0 +1,19 @@
+{
+    "name" : "orion",
+    "auth" : "github:andinus",
+    "version" : "0.2.0",
+    "description" : "Orion checks for compromised passwords using Have I Been Pwned API",
+    "authors" : [ "Andinus <andinus@nand.sh>" ],
+    "license" : "ISC",
+    "perl" : "6.d",
+    "provides" : {
+        "Orion::CLI" : "lib/Orion/CLI.rakumod",
+    },
+    "depends" : [
+        "WWW:ver<1.005006+>:auth<github:raku-community-modules>"
+    ],
+    "tags": [
+        "Orion", "Password Store", "pass", "Have I Been Pwned", "HIBP"
+    ],
+    "source-url" : "https://git.tilde.institute/andinus/orion"
+}
diff --git a/bin/orion b/bin/orion
new file mode 100644
index 0000000..b8f7271
--- /dev/null
+++ b/bin/orion
@@ -0,0 +1,3 @@
+#!/usr/bin/env raku
+
+use Orion::CLI;
diff --git a/cmd/orion/orion.go b/cmd/orion/orion.go
deleted file mode 100644
index e3ce011..0000000
--- a/cmd/orion/orion.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package main
-
-import (
-	"os"
-	"time"
-
-	"framagit.org/andinus/orion/hibp"
-
-	"github.com/AlecAivazis/survey/v2"
-	"github.com/AlecAivazis/survey/v2/terminal"
-	"github.com/briandowns/spinner"
-	"github.com/fatih/color"
-)
-
-func main() {
-	var pass string
-
-	prompt := &survey.Password{
-		Message: "Password:",
-		Help:    "Enter password to be checked against HIBP's Database",
-	}
-	err := survey.AskOne(prompt, &pass, survey.WithValidator(survey.Required))
-	if err == terminal.InterruptErr {
-		color.Yellow("Interrupt Received")
-		os.Exit(0)
-	} else if err != nil {
-		panic(err)
-	}
-
-	s := spinner.New(spinner.CharSets[12], 32*time.Millisecond)
-	s.Start()
-	s.Color("cyan")
-
-	// get password hash
-	hsh := hibp.GetHsh(pass)
-
-	// get list of pwned passwords
-	list, err := hibp.GetPwned(hsh)
-	if err != nil {
-		color.Yellow(err.Error())
-		os.Exit(1)
-	}
-
-	// check if pass is pwned
-	pwn, fq := hibp.ChkPwn(list, hsh)
-	s.Stop()
-
-	if pwn {
-		color.New(color.FgRed).Add(color.Bold).Println("\nPwned!")
-		color.Yellow("This password has been seen %s times before.", fq)
-		return
-	}
-
-	color.Green("\nPassword wasn't found in Have I Been Pwned's Database")
-}
diff --git a/go.mod b/go.mod
deleted file mode 100644
index c2ad747..0000000
--- a/go.mod
+++ /dev/null
@@ -1,9 +0,0 @@
-module git.tilde.institute/andinus/orion
-
-go 1.13
-
-require (
-	github.com/AlecAivazis/survey/v2 v2.0.7
-	github.com/briandowns/spinner v1.9.0
-	github.com/fatih/color v1.7.0
-)
diff --git a/go.sum b/go.sum
deleted file mode 100644
index b7157b0..0000000
--- a/go.sum
+++ /dev/null
@@ -1,30 +0,0 @@
-github.com/AlecAivazis/survey v1.8.8 h1:Y4yypp763E8cbqb5RBqZhGgkCFLRFnbRBHrxnpMMsgQ=
-github.com/AlecAivazis/survey/v2 v2.0.7 h1:+f825XHLse/hWd2tE/V5df04WFGimk34Eyg/z35w/rc=
-github.com/AlecAivazis/survey/v2 v2.0.7/go.mod h1:mlizQTaPjnR4jcpwRSaSlkbsRfYFEyKgLQvYTzxxiHA=
-github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
-github.com/briandowns/spinner v1.9.0 h1:+OMAisemaHar1hjuJ3Z2hIvNhQl9Y7GLPWUwwz2Pxo8=
-github.com/briandowns/spinner v1.9.0/go.mod h1://Zf9tMcxfRUA36V23M6YGEAv+kECGfvpnLTnb8n4XQ=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
-github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
-github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
-github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
-github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
-github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
-github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
-github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/hibp/hash.go b/hibp/hash.go
deleted file mode 100644
index 9b8d35c..0000000
--- a/hibp/hash.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package hibp
-
-import (
-	"crypto/sha1"
-	"encoding/hex"
-	"strings"
-)
-
-// GetSHA1Hash takes a string as an input & returns SHA-1 Hash
-func GetSHA1Hash(pass string) string {
-	alg := sha1.New()
-	alg.Write([]byte(pass))
-
-	return strings.ToUpper(hex.EncodeToString(alg.Sum(nil)))
-}
diff --git a/hibp/pwned.go b/hibp/pwned.go
deleted file mode 100644
index 57a1727..0000000
--- a/hibp/pwned.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package hibp
-
-import (
-	"fmt"
-	"strings"
-)
-
-// GetPwned takes SHA-1 Hash as input & returns Pwned Passwords list
-// returned by the Have I Been Pwned API
-func GetPwned(hsh string) (map[string]string, error) {
-	api := "https://api.pwnedpasswords.com/range"
-	list := make(map[string]string)
-
-	pfx := hsh[:5]
-
-	reqApi := fmt.Sprintf("%s/%s", api, pfx)
-	body, err := reqHIBP(reqApi)
-	if err != nil {
-		return list, fmt.Errorf("reqHIBP failed\n%s",
-			err.Error())
-	}
-
-	for _, v := range strings.Split(body, "\r\n") {
-		s := strings.Split(v, ":")
-		list[s[0]] = s[1]
-	}
-	return list, err
-}
-
-// ChkPwn takes list, hash as input & returns if the hash is in list,
-// the frequency
-func ChkPwn(list map[string]string, hsh string) (bool, string) {
-	sfx := hsh[5:]
-	for k, fq := range list {
-		if sfx == k {
-			return true, fq
-		}
-	}
-	return false, ""
-}
diff --git a/hibp/req.go b/hibp/req.go
deleted file mode 100644
index 8081d3c..0000000
--- a/hibp/req.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package hibp
-
-import (
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"time"
-)
-
-func reqHIBP(reqApi string) (body string, err error) {
-	c := http.Client{
-		// TODO: timeout should be configurable by the user
-		Timeout: time.Second * 64,
-	}
-
-	req, err := http.NewRequest(http.MethodGet, reqApi, nil)
-	if err != nil {
-		err = fmt.Errorf("hibp/req.go: Failed to create request\n%s",
-			err.Error())
-		return
-	}
-
-	// User-Agent should be passed with every request to
-	// make work easier for the server handler. Include contact
-	// information along with the project name so they could reach
-	// you if required.
-	req.Header.Set("User-Agent",
-		"Andinus / Orion - https://andinus.nand.sh/orion")
-
-	res, err := c.Do(req)
-	if err != nil {
-		err = fmt.Errorf("hibp/req.go: Failed to get response\n%s",
-			err.Error())
-		return
-	}
-	defer res.Body.Close()
-
-	if res.StatusCode != 200 {
-		fmt.Errorf("hibp/req.go: Unexpected response status code received: %d %s",
-			res.StatusCode,
-			http.StatusText(res.StatusCode))
-		return
-	}
-
-	// This will read everything to memory and is okay to use here
-	// because the response is expected to be small.
-	out, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		fmt.Errorf("hibp/req.go: Failed to read res.Body\n%s",
-			err.Error())
-		return
-	}
-
-	body = string(out)
-	return
-}
diff --git a/lib/Orion/CLI.rakumod b/lib/Orion/CLI.rakumod
new file mode 100644
index 0000000..be7085a
--- /dev/null
+++ b/lib/Orion/CLI.rakumod
@@ -0,0 +1,8 @@
+proto MAIN(|) is export { unless so @*ARGS { say $*USAGE; exit }; {*} }
+
+multi sub MAIN(
+) { }
+
+multi sub MAIN(
+    Bool :$version #= print version
+) { say "Orion v" ~ $?DISTRIBUTION.meta<version>; }