next-eeze.git

commit eb7704f608bfd9e73e2b8ed351d1d5ad9f0ceab2

Author: Adam <git@apiote.xyz>

add option to block when keyring is not open

 agent/client.go | 43 ++++++++++++++++++++++++++++++++++++++-----
 eeze.go | 33 ++++++++++++++++++++++++---------
 go.mod | 9 ++++++---
 go.sum | 23 +++++++++++++++++++++++
 server/sync.go | 8 +++-----


diff --git a/agent/client.go b/agent/client.go
index c315523de3ddbc91ee3020a94340a3b3d04115fa..fb320bb7ba670a7552c3faf3149abe40cb27b5e9 100644
--- a/agent/client.go
+++ b/agent/client.go
@@ -4,14 +4,21 @@ import (
 	"log"
 	"net"
 	"os"
+	"os/exec"
 	"os/user"
 
 	"git.sr.ht/~sircmpwn/go-bare"
 )
 
-func GetMasterPassword() (string, error) {
+func GetMasterPassword(block bool) (string, error) {
 	// todo memguard
 	var masterPassword = ""
+	var command byte
+	if block {
+		command = 2
+	} else {
+		command = 1
+	}
 	user, err := user.Current()
 	if err != nil {
 		log.Println("Error getting user ", err)
@@ -26,7 +33,7 @@ 			return "", err
 		}
 		defer conn.Close()
 
-		_, err = conn.Write([]byte{1})
+		_, err = conn.Write([]byte{command})
 		if err != nil {
 			log.Println("Warning, cannot write to agent", err)
 			return "", err
@@ -42,10 +49,36 @@ 	return masterPassword, nil
 }
 
 // todo memguard
-func GiveMasterPassword(masterPassword string) {
-	// todo implement GiveMasterPassword
+func GiveMasterPassword(masterPassword string) error {
+	user, err := user.Current()
+	if err != nil {
+		log.Println("Error getting user ", err)
+		return err
+	}
+	fileInfo, err := os.Stat("/tmp/eeze-agent-" + user.Username)
+	if err == nil && fileInfo.Mode()&os.ModeSocket != 0 {
+		conn, err := net.Dial("unix", "/tmp/eeze-agent-"+user.Username)
+		if err != nil {
+			log.Println("Warning, cannot connect to agent", err)
+			return err
+		}
+		defer conn.Close()
+
+		w := bare.NewWriter(conn)
+		err = w.WriteU8(0)
+		if err != nil {
+			log.Println("Warning, cannot write cmd to agent", err)
+			return err
+		}
+		err = w.WriteString(masterPassword)
+		if err != nil {
+			log.Println("Warning, cannot write password to agent", err)
+			return err
+		}
+	}
+	return nil
 }
 
 func StartAgent() {
-	// todo implement StartAgent
+	exec.Command("eeze-agent").Run()
 }




diff --git a/eeze.go b/eeze.go
index 1f01072f741290b8344fc1ef75fc59c1715f77e6..78e278753bed0d1874414fbaa65e83945241aad0 100644
--- a/eeze.go
+++ b/eeze.go
@@ -15,11 +15,23 @@
 	"git.sr.ht/~sircmpwn/getopt"
 )
 
+func rememberMasterPassword() string {
+	fmt.Print("Master password: ")
+	// todo memguard
+	masterPass_b, _ := terminal.ReadPassword(int(os.Stdin.Fd()))
+	// todo memguard
+	masterPassword := string(masterPass_b)
+	fmt.Print("\n")
+	agent.GiveMasterPassword(masterPassword)
+	return masterPassword
+}
+
 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")
@@ -32,6 +44,7 @@ 	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)")
 	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 {
@@ -39,10 +52,18 @@ 		log.Println("Error parsing opts. ", err)
 		return
 	}
 
-	masterPassword, err := agent.GetMasterPassword()
+	if *P {
+		_ = rememberMasterPassword()
+		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)
-		agent.StartAgent()
 	}
 
 	if masterPassword == "" && !*C && *n {
@@ -50,13 +71,7 @@ 		log.Fatalln("Password needed in non-interactive mode")
 	}
 
 	if masterPassword == "" || (*C && (*i || *r)) {
-		fmt.Print("Master password: ")
-		// todo memguard
-		masterPass_b, _ := terminal.ReadPassword(int(os.Stdin.Fd()))
-		// todo memguard
-		masterPassword = string(masterPass_b)
-		fmt.Print("\n")
-		agent.GiveMasterPassword(masterPassword)
+		masterPassword = rememberMasterPassword()
 	}
 
 	if *C {




diff --git a/go.mod b/go.mod
index e9cdc6c6e3d531e59a7c52e8c71baecefc5ca105..58a3ef030559e3272405877ca1a2d9b604283ce3 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,10 @@
 go 1.15
 
 require (
-	git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3
-	git.sr.ht/~sircmpwn/go-bare v0.0.0-20200812160916-d2c72e1a5018
-	golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
+	git.sr.ht/~sircmpwn/getopt v1.0.0
+	git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9
+	github.com/keys-pub/go-libfido2 v1.5.2 // indirect
+	golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
+	golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac // indirect
+	golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
 )




diff --git a/go.sum b/go.sum
index 52571e1349b657cc9f400629247b4910abb434f7..b8e8cc21a481a3982c6142cf7cd5e40f8321b72d 100644
--- a/go.sum
+++ b/go.sum
@@ -1,19 +1,42 @@
 git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3 h1:4wDp4BKF7NQqoh73VXpZsB/t1OEhDpz/zEpmdQfbjDk=
 git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw=
+git.sr.ht/~sircmpwn/getopt v1.0.0 h1:/pRHjO6/OCbBF4puqD98n6xtPEgE//oq5U8NXjP7ROc=
+git.sr.ht/~sircmpwn/getopt v1.0.0/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw=
 git.sr.ht/~sircmpwn/go-bare v0.0.0-20200812160916-d2c72e1a5018 h1:89QMorzx6ML69PKPoayL3HuSfb7WqAlxD1dZ7DyzD0k=
 git.sr.ht/~sircmpwn/go-bare v0.0.0-20200812160916-d2c72e1a5018/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA=
+git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9 h1:Ahny8Ud1LjVMMAlt8utUFKhhxJtwBAualvsbc/Sk7cE=
+git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/keys-pub/go-libfido2 v1.5.2 h1:YJVK9iMOMlfRZrEzZtnJBRNO+jYB+/sfNtO4ruV7BXI=
+github.com/keys-pub/go-libfido2 v1.5.2/go.mod h1:P0V19qHwJNY0htZwZDe9Ilvs/nokGhdFX7faKFyZ6+U=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
 golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac h1:oN6lz7iLW/YC7un8pq+9bOLyXrprv2+DKfkJY+2LJJw=
+golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=




diff --git a/server/sync.go b/server/sync.go
index e16920c19d57361a784d96e5db517874bf0495e0..87264cfd89f20f7f7db19157ffdf154cc3814d4d 100644
--- a/server/sync.go
+++ b/server/sync.go
@@ -22,8 +22,6 @@
 // todo memguard credentials
 func open(credentials fs.Credentials) (string, error) {
 	// todo memguard
-	authorization := base64.StdEncoding.EncodeToString([]byte(credentials.Username + ":" + credentials.Password))
-
 	req, err := http.NewRequest("POST",
 		credentials.Server+"/index.php/apps/passwords/api/1.0/session/open",
 		bytes.NewBuffer([]byte("{}")))
@@ -34,9 +32,9 @@ 		return "", err
 	}
 
 	req.Header.Set("Accept", "application/json")
-	req.Header.Set("authorization", "Basic "+authorization)
-
-	client := &http.Client{Timeout: time.Second * 10}
+	req.SetBasicAuth(credentials.Username, credentials.Password)
+	
+	client := &http.Client{Timeout: time.Second * 30}
 
 	resp, err := client.Do(req)
 	if err != nil {