diff --git a/cmd/passgo-gui/impl_darwin.go b/cmd/passgo-gui/impl_darwin.go index 4c8b6db..0e8d764 100644 --- a/cmd/passgo-gui/impl_darwin.go +++ b/cmd/passgo-gui/impl_darwin.go @@ -1,4 +1,4 @@ -//+build !android !linux +//+build darwin package main diff --git a/cmd/passgo-gui/impl_non_darwin.go b/cmd/passgo-gui/impl_non_darwin.go new file mode 100644 index 0000000..51527e7 --- /dev/null +++ b/cmd/passgo-gui/impl_non_darwin.go @@ -0,0 +1,38 @@ +//+build !darwin + +package main + +import ( + "os" + "os/user" + "path" + + "golang.org/x/image/font/gofont/goregular" + "golang.org/x/image/font/sfnt" +) + +var ( + regular *sfnt.Font + confDir string +) + +func init() { + regular, err = sfnt.Parse(goregular.TTF) + if err != nil { + log(Fatal, "Cannot parse default font: ", err) + } + usr, err := user.Current() + if err != nil { + log(Fatal, "Cannot get current user: ", err) + } + confDir = path.Join(usr.HomeDir, ".config/passgo") + if _, err := os.Stat(confDir); os.IsNotExist(err) { + err = os.MkdirAll(confDir, 0700) + if err != nil { + log(Info, "Cannot create configuration directory ", confDir) + log(Fatal, err) + } else { + log(Info, "Configuration directory created") + } + } +} diff --git a/cmd/passgo-gui/main.go b/cmd/passgo-gui/main.go index c236dff..7d65996 100644 --- a/cmd/passgo-gui/main.go +++ b/cmd/passgo-gui/main.go @@ -65,6 +65,7 @@ func main() { reload = make(chan struct{}) updated = make(chan struct{}) + passch = make(chan []byte) go Updater() log(Info, "Staring event loop") @@ -80,6 +81,7 @@ var ( store passgo.Store reload chan struct{} updated chan struct{} + passch chan []byte black = color.RGBA{A: 0xff, R: 0, G: 0, B: 0} white = color.RGBA{A: 0xff, R: 0xff, G: 0xff, B: 0xff} gray = color.RGBA{A: 0xff, R: 0xf0, G: 0xf0, B: 0xf0} @@ -334,6 +336,16 @@ func eventLoop() { Background: gray, } + promptLabel := &text.Label{Face: face, Text: "passphrase"} + promptEd := &text.Editor{Face: face, SingleLine: true} + okBtn := &Button{ + Face: face, + Label: "ok", + Alignment: text.End, + Color: black, + Background: gray, + } + anim := &time.Ticker{} animating := false animOn := func() { @@ -346,8 +358,14 @@ func eventLoop() { animating = false } - var listPage, confPage, page func() - _ = confPage + var listPage, confPage, promptPage, page func() + + prompt := func() []byte { + page = promptPage + promptEd.SetText("") + w.Invalidate() + return <-passch + } listPage = func() { cs = flex.Flexible(1.0) @@ -373,8 +391,8 @@ func eventLoop() { log(Info, "Clicked ", btn.Label) // don't block UI thread on decryption attempt go func(name string) { - //p,err := store.Decrypt(name, prompt) - p, err := store.Decrypt(name) + p,err := store.Decrypt(name, prompt) + //p, err := store.Decrypt(name) if err == nil { passgo.Clip(p) copiedWhen = time.Now() @@ -459,6 +477,32 @@ func eventLoop() { } } + promptPage = func() { + cs = flex.Rigid() + c2 := flex.End(promptLabel.Layout(ops, cs)) + cs = flex.Rigid() + c3 := flex.End(promptEd.Layout(c, q, ops, cs)) + cs = flex.Rigid() + al := &layout.Align{Alignment: layout.E} + cs = al.Begin(ops, cs) + c4 := flex.End(al.End(okBtn.Layout(c, q, ops, cs))) + flex.Layout(c1, c2, c3, c4) + if okBtn.Clicked() { + log(Info, "Ok") + go func() { // do not block UI thread + passch <-[]byte(promptEd.Text()) + }() + page = listPage + } + if backBtn.Clicked() { + log(Info, "Back") + go func() { + passch <- nil // cancel prompt + }() + page = listPage + } + } + page = listPage for { diff --git a/impl_darwin.go b/impl_darwin.go index 0570cba..ec30741 100644 --- a/impl_darwin.go +++ b/impl_darwin.go @@ -1,4 +1,4 @@ -//+build !android !linux +//+build darwin package passgo diff --git a/impl_non_darwin.go b/impl_non_darwin.go new file mode 100644 index 0000000..f1a7e8a --- /dev/null +++ b/impl_non_darwin.go @@ -0,0 +1,12 @@ +//+build !darwin + +package passgo + +import ( + "log" +) + +//Clip copies a string to the clipboard +func Clip(x string) { + log(Info,"Clipboard not implemented for this platform") +} diff --git a/main.go b/main.go index 7afaba4..9a618e2 100644 --- a/main.go +++ b/main.go @@ -122,15 +122,18 @@ func AskPass(prompts ...func() []byte) openpgp.PromptFunction { } } - var err error var passphrase []byte - dec := func(p *packet.PrivateKey) { + dec := func(p *packet.PrivateKey) error { for i := 0; i < 3; i++ { - if err = p.Decrypt(passphrase); err == nil { - break + if err := p.Decrypt(passphrase); err == nil { + return err } passphrase = prompt() + if passphrase == nil { + return fmt.Errorf("Passphrase entry aborted") + } } + return fmt.Errorf("Passphrase entry failed") } var ret openpgp.PromptFunction @@ -138,16 +141,20 @@ func AskPass(prompts ...func() []byte) openpgp.PromptFunction { if !symmetric { for _, k := range keys { if p := k.PrivateKey; p != nil && p.Encrypted { - dec(p) + if err := dec(p); err != nil { + return nil, err + } } for _, s := range k.Entity.Subkeys { if p := s.PrivateKey; p != nil && p.Encrypted { - dec(p) + if err := dec(p); err != nil { + return nil, err + } } } } } - return passphrase, err + return passphrase, nil } return ret }