Skip to content
This repository has been archived by the owner on May 27, 2019. It is now read-only.

Support for OTP #73

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"


[[constraint]]
branch = "master"
name = "github.com/gokyle/twofactor"

[[constraint]]
branch = "master"
name = "github.com/mattn/go-zglob"
35 changes: 34 additions & 1 deletion browserpass.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,24 @@ import (
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"io"
"net/url"
"os/exec"
"path/filepath"
"regexp"
"strings"

"github.com/dannyvankooten/browserpass/pass"
"github.com/gokyle/twofactor"
)

// Login represents a single pass login.
type Login struct {
Username string `json:"u"`
Password string `json:"p"`
OTP string `json:"digits"`
otpLabel string `json:"label"`
}

var endianness = binary.LittleEndian
Expand Down Expand Up @@ -126,14 +131,41 @@ func readLoginGPG(r io.Reader) (*Login, error) {
if err != nil {
return nil, err
}
rc.Close()

defer rc.Close()

if err := cmd.Wait(); err != nil {
return nil, errors.New(err.Error() + "\n" + errbuf.String())
}
return login, nil
}

func parseTotp(str string, l *Login) error {
re := regexp.MustCompile("^otpauth.*$")
ourl := re.FindString(str)

if ourl != "" {
u, err := url.Parse(ourl)

if u.Scheme != "otpauth" {
return nil
}

v := u.Query()
v.Set("secret", strings.ToUpper(v.Get("secret")))
ourl = fmt.Sprintf("%s://%s/%s?%s", u.Scheme, u.Host, u.Path[1:], v.Encode())

o, label, err := twofactor.FromURL(ourl)
if err != nil {
return err
}
l.OTP = o.OTP()
l.otpLabel = label
}

return nil
}

// parseLogin parses a login and a password from a decrypted password file.
func parseLogin(r io.Reader) (*Login, error) {
login := new(Login)
Expand All @@ -148,6 +180,7 @@ func parseLogin(r io.Reader) (*Login, error) {
re := regexp.MustCompile("(?i)^(login|username|user):")
for scanner.Scan() {
line := scanner.Text()
parseTotp(line, login)
replaced := re.ReplaceAllString(line, "")
if len(replaced) != len(line) {
login.Username = strings.TrimSpace(replaced)
Expand Down
26 changes: 26 additions & 0 deletions browserpass_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package browserpass
import (
"strings"
"testing"

"github.com/gokyle/twofactor"
)

func TestParseLogin(t *testing.T) {
Expand All @@ -21,6 +23,30 @@ func TestParseLogin(t *testing.T) {
}
}

func TestOtp(t *testing.T) {
r := strings.NewReader("password\n\nfoo\nlogin: bar\notpauth://totp/totp-secret?secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ&issuer=test")

login, err := parseLogin(r)
if err != nil {
t.Fatal(err)
}

if login.otpLabel != "totp-secret" {
t.Errorf("otpLabel is '%s', expected '%s'", login.otpLabel, "totp-secret")
}

o, err := twofactor.NewGoogleTOTP("GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ")
if err != nil {
t.Error(err)
}

otp := o.OTP()

if login.OTP != otp {
t.Errorf("OTP is %s, expected %s", login.OTP, otp)
}
}

func TestGuessUsername(t *testing.T) {
tests := map[string]string{
"foo": "",
Expand Down
4 changes: 4 additions & 0 deletions chrome/inject.browserify.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@
update(field(PASSWORD_FIELDS), login.p);
update(field(USERNAME_FIELDS), login.u);

if (login.digits != "") {
alert(login.digits);
}

var password_inputs = queryAllVisible(form(), PASSWORD_FIELDS);
if (autoSubmit == "false" || password_inputs.length > 1) {
password_inputs[1].select();
Expand Down
6 changes: 5 additions & 1 deletion makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ firefox:
.PHONY: js
js: $(JS_OUTPUT)

chrome/script.js: chrome/script.browserify.js
chrome/script.js: chrome/script.browserify.js
browserify chrome/script.browserify.js -o chrome/script.js

chrome/inject.js: chrome/inject.browserify.js
Expand All @@ -49,6 +49,10 @@ browserpass-openbsd64: cmd/browserpass/ pass/ browserpass.go
browserpass-freebsd64: cmd/browserpass/ pass/ browserpass.go
env GOOS=freebsd GOARCH=amd64 go build -o $@ ./cmd/browserpass

clean:
rm -f browserpass-*
rm -rf release

.PHONY: static-files chrome firefox
release: static-files chrome firefox browserpass-linux64 browserpass-darwinx64 browserpass-openbsd64 browserpass-freebsd64
mkdir -p release
Expand Down
7 changes: 7 additions & 0 deletions vendor/github.com/gokyle/twofactor/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions vendor/github.com/gokyle/twofactor/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions vendor/github.com/gokyle/twofactor/doc.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 101 additions & 0 deletions vendor/github.com/gokyle/twofactor/hotp.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading