123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- package main
- import (
- "notabug.org/apiote/next-eeze/agent"
- "notabug.org/apiote/next-eeze/config"
- "notabug.org/apiote/next-eeze/fido"
- "notabug.org/apiote/next-eeze/fs"
- "notabug.org/apiote/next-eeze/operation"
- "notabug.org/apiote/next-eeze/server"
- "encoding/hex"
- "fmt"
- "log"
- "os"
- "golang.org/x/crypto/ssh/terminal"
- "git.sr.ht/~sircmpwn/getopt"
- )
- func readMasterPassword() (string, error) {
- present, err := fs.IsFidoCredentialPresent()
- if err != nil {
- fmt.Println(err)
- return "", err
- }
- if present {
- return readMasterPasswordFido()
- } else {
- return readMasterPasswordStdin()
- }
- }
- func readMasterPasswordFido() (string, error) {
- c, err := fs.ReadFidoCredential()
- if err != nil {
- return "", err
- }
- // todo memguard
- secret := fido.GetHmacSecret("next-eeze", "", c.Cdh, c.Salt, c.CredID) // todo pin
- return hex.EncodeToString(secret), nil
- }
- func readMasterPasswordStdin() (string, error) {
- fmt.Print("Master password: ")
- // todo memguard
- masterPass_b, err := terminal.ReadPassword(int(os.Stdin.Fd()))
- if err != nil {
- return "", err
- }
- // todo memguard
- masterPassword := string(masterPass_b)
- fmt.Print("\n")
- return masterPassword, nil
- }
- func main() {
- C := getopt.Bool("C", false, "Config")
- S := getopt.Bool("S", false, "Sync")
- L := getopt.Bool("L", false, "List")
- G := getopt.Bool("G", false, "Get")
- P := getopt.Bool("P", false, "Put")
- var u string
- getopt.StringVar(&u, "u", "", "filter Get by username")
- var l string
- getopt.StringVar(&l, "l", "", "filter Get by label")
- var s string
- getopt.StringVar(&s, "s", "", "filter Get by url (service/server)")
- f := getopt.Bool("f", false, "show full entry in Get, instead of just username/password")
- p := getopt.Bool("p", false, "show just password in Get")
- i := getopt.Bool("i", false, "in Config: set server, username, password (initialise)")
- r := getopt.Bool("r", false, "in Config: reëncrypt (change master password)")
- fido2 := getopt.Bool("2", false, "in Config, reëncrypt: use fido2 device")
- n := getopt.Bool("n", false, "do not ask for anything, fail if password cannot be obtained from agent")
- b := getopt.Bool("b", false, "block until password can be received from agent")
- err := getopt.Parse()
- if err != nil {
- log.Println("Error parsing opts. ", err)
- return
- }
- if *P {
- masterPassword, _ := readMasterPassword()
- agent.GiveMasterPassword(masterPassword)
- return
- }
- masterPassword, err := agent.GetMasterPassword(*b)
- if masterPassword == "" && err == nil {
- agent.StartAgent()
- }
- masterPassword, err = agent.GetMasterPassword(*b)
- if err != nil {
- log.Println("Error getting from agent", err)
- }
- if masterPassword == "" && !*C && *n {
- log.Fatalln("Password needed in non-interactive mode")
- }
- if masterPassword == "" || (*C && (*i || *r)) {
- masterPassword, _ = readMasterPassword()
- agent.GiveMasterPassword(masterPassword)
- }
- if *C {
- if *i {
- config.Init(masterPassword)
- } else if *r {
- // todo memguard
- newMasterPassword, err := config.Reëncrypt(masterPassword, *fido2)
- if err != nil {
- log.Println("Error reëncrypting. ", err)
- return
- } else {
- agent.GiveMasterPassword(newMasterPassword)
- }
- }
- } else if *S {
- err = server.Sync(masterPassword)
- } else if *G {
- var r string
- r, err = operation.Get(u, l, s, *f, *p, masterPassword)
- // todo if error:wrongPass -> kill agent
- fmt.Println(r)
- } else if *L {
- var r string
- r, err = operation.List(masterPassword)
- fmt.Println(r)
- } else {
- getopt.Usage()
- }
- if err != nil {
- log.Println("Error. ", err)
- return
- }
- }
|