cleanly close, catch Dbus errors

This commit is contained in:
brent s. 2021-12-25 01:51:49 -05:00
parent 9d3299c9dc
commit bb85cb8b52
Signed by: bts
GPG Key ID: 8C004C2F93481F6B
7 changed files with 132 additions and 51 deletions

2
TODO
View File

@ -1 +1,3 @@
- Benchmarking? - Benchmarking?

- call .Close() on dbus.Conns

View File

@ -65,6 +65,7 @@ func NewCollection(service *Service, path dbus.ObjectPath) (coll *Collection, er
*/ */
func (c *Collection) CreateItem(label string, attrs map[string]string, secret *Secret, replace bool, itemType ...string) (item *Item, err error) { func (c *Collection) CreateItem(label string, attrs map[string]string, secret *Secret, replace bool, itemType ...string) (item *Item, err error) {


var call *dbus.Call
var prompt *Prompt var prompt *Prompt
var path dbus.ObjectPath var path dbus.ObjectPath
var promptPath dbus.ObjectPath var promptPath dbus.ObjectPath
@ -84,9 +85,13 @@ func (c *Collection) CreateItem(label string, attrs map[string]string, secret *S
props[DbusItemCreated] = dbus.MakeVariant(uint64(time.Now().Unix())) props[DbusItemCreated] = dbus.MakeVariant(uint64(time.Now().Unix()))
// props[DbusItemModified] = dbus.MakeVariant(uint64(time.Now().Unix())) // props[DbusItemModified] = dbus.MakeVariant(uint64(time.Now().Unix()))


if err = c.Dbus.Call( if call = c.Dbus.Call(
DbusCollectionCreateItem, 0, props, secret, replace, DbusCollectionCreateItem, 0, props, secret, replace,
).Store(&path, &promptPath); err != nil { ); call.Err != nil {
err = call.Err
return
}
if err = call.Store(&path, &promptPath); err != nil {
return return
} }


@ -114,10 +119,17 @@ func (c *Collection) CreateItem(label string, attrs map[string]string, secret *S
*/ */
func (c *Collection) Delete() (err error) { func (c *Collection) Delete() (err error) {


var call *dbus.Call
var promptPath dbus.ObjectPath var promptPath dbus.ObjectPath
var prompt *Prompt var prompt *Prompt


if err = c.Dbus.Call(DbusCollectionDelete, 0).Store(&promptPath); err != nil { if call = c.Dbus.Call(
DbusCollectionDelete, 0,
); call.Err != nil {
err = call.Err
return
}
if err = call.Store(&promptPath); err != nil {
return return
} }


@ -243,6 +255,7 @@ func (c *Collection) Relabel(newLabel string) (err error) {
*/ */
func (c *Collection) SearchItems(profile string) (items []*Item, err error) { func (c *Collection) SearchItems(profile string) (items []*Item, err error) {


var call *dbus.Call
var paths []dbus.ObjectPath var paths []dbus.ObjectPath
var errs []error = make([]error, 0) var errs []error = make([]error, 0)
var attrs map[string]string = make(map[string]string, 0) var attrs map[string]string = make(map[string]string, 0)
@ -250,9 +263,13 @@ func (c *Collection) SearchItems(profile string) (items []*Item, err error) {


attrs["profile"] = profile attrs["profile"] = profile


if err = c.Dbus.Call( if call = c.Dbus.Call(
DbusCollectionSearchItems, 0, attrs, DbusCollectionSearchItems, 0, attrs,
).Store(&paths); err != nil { ); call.Err != nil {
err = call.Err
return
}
if err = call.Store(&paths); err != nil {
return return
} }


@ -277,11 +294,10 @@ func (c *Collection) SetAlias(alias string) (err error) {


var call *dbus.Call var call *dbus.Call


call = c.service.Dbus.Call( if call = c.service.Dbus.Call(
DbusServiceSetAlias, 0, alias, c.Dbus.Path(), DbusServiceSetAlias, 0, alias, c.Dbus.Path(),
) ); call.Err != nil {

err = call.Err
if err = call.Err; err != nil {
return return
} }



View File

@ -1,9 +1,9 @@
package gosecret package gosecret


import ( import (
`testing` "testing"


`github.com/godbus/dbus/v5` "github.com/godbus/dbus/v5"
) )


// Some functions are covered in the Service tests. // Some functions are covered in the Service tests.
@ -57,7 +57,8 @@ func TestCollection_Items(t *testing.T) {
var collection *Collection var collection *Collection
var items []*Item var items []*Item
var item *Item var item *Item
var searchItemResults []*Item var searchResultsUnlocked []*Item
var searchResultsLocked []*Item
var secret *Secret var secret *Secret
var err error var err error


@ -109,12 +110,12 @@ func TestCollection_Items(t *testing.T) {
) )
} else { } else {


if searchItemResults, err = collection.SearchItems(testItemLabel); err != nil { if searchResultsUnlocked, searchResultsLocked, err = collection.service.SearchItems(itemAttrs); err != nil {
t.Errorf("failed to find item '%v' via Collection.SearchItems: %v", string(item.Dbus.Path()), err.Error()) t.Errorf("failed to find item '%v' via Collection.SearchItems: %v", string(item.Dbus.Path()), err.Error())
} else if len(searchItemResults) == 0 { } else if (len(searchResultsLocked) + len(searchResultsUnlocked)) == 0 {
t.Errorf("failed to find item '%v' via Collection.SearchItems, returned 0 results (should be at least 1)", testItemLabel) t.Errorf("failed to find item '%v' via Collection.SearchItems, returned 0 results (should be at least 1)", testItemLabel)
} else { } else {
t.Logf("found %v results for Collection.SearchItems", len(searchItemResults)) t.Logf("found %v results for Collection.SearchItems", len(searchResultsUnlocked)+len(searchResultsLocked))
} }


if err = item.Delete(); err != nil { if err = item.Delete(); err != nil {

View File

@ -106,10 +106,17 @@ func (i *Item) ChangeItemType(newItemType string) (err error) {
// Delete removes an Item from a Collection. // Delete removes an Item from a Collection.
func (i *Item) Delete() (err error) { func (i *Item) Delete() (err error) {


var call *dbus.Call
var promptPath dbus.ObjectPath var promptPath dbus.ObjectPath
var prompt *Prompt var prompt *Prompt


if err = i.Dbus.Call(DbusItemDelete, 0).Store(&promptPath); err != nil { if call = i.Dbus.Call(
DbusItemDelete, 0,
); call.Err != nil {
err = call.Err
return
}
if err = call.Store(&promptPath); err != nil {
return return
} }


@ -127,6 +134,8 @@ func (i *Item) Delete() (err error) {
// GetSecret returns the Secret in an Item using a Session. // GetSecret returns the Secret in an Item using a Session.
func (i *Item) GetSecret(session *Session) (secret *Secret, err error) { func (i *Item) GetSecret(session *Session) (secret *Secret, err error) {


var call *dbus.Call

if session == nil { if session == nil {
err = ErrNoDbusConn err = ErrNoDbusConn
} }
@ -135,9 +144,13 @@ func (i *Item) GetSecret(session *Session) (secret *Secret, err error) {
return return
} }


if err = i.Dbus.Call( if call = i.Dbus.Call(
DbusItemGetSecret, 0, session.Dbus.Path(), DbusItemGetSecret, 0, session.Dbus.Path(),
).Store(&secret); err != nil { ); call.Err != nil {
err = call.Err
return
}
if err = call.Store(&secret); err != nil {
return return
} }


@ -246,15 +259,15 @@ func (i *Item) ReplaceAttributes(newAttrs map[string]string) (err error) {
// SetSecret sets the Secret for an Item. // SetSecret sets the Secret for an Item.
func (i *Item) SetSecret(secret *Secret) (err error) { func (i *Item) SetSecret(secret *Secret) (err error) {


var c *dbus.Call var call *dbus.Call


c = i.Dbus.Call( if call = i.Dbus.Call(
DbusItemSetSecret, 0, DbusItemSetSecret, 0,
) ); call.Err != nil {
if c.Err != nil { err = call.Err
err = c.Err
return return
} }

i.Secret = secret i.Secret = secret


if _, _, err = i.Modified(); err != nil { if _, _, err = i.Modified(); err != nil {

View File

@ -35,6 +35,7 @@ func NewErrors(errs ...error) (err error) {
return return
} }


// Error makes a MultiError conform to the error interface.
func (e *MultiError) Error() (errStr string) { func (e *MultiError) Error() (errStr string) {


var numErrs int var numErrs int

View File

@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"path/filepath" "path/filepath"
"strings" "strings"
`time` "time"


"github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5"
) )
@ -38,7 +38,13 @@ func NewService() (service *Service, err error) {
// Close cleanly closes a Service and all its underlying connections (e.g. Service.Session). // Close cleanly closes a Service and all its underlying connections (e.g. Service.Session).
func (s *Service) Close() (err error) { func (s *Service) Close() (err error) {


err = s.Session.Close() if err = s.Session.Close(); err != nil {
return
}

if err = s.Conn.Close(); err != nil {
return
}


return return
} }
@ -80,6 +86,7 @@ func (s *Service) Collections() (collections []*Collection, err error) {
*/ */
func (s *Service) CreateAliasedCollection(label, alias string) (collection *Collection, err error) { func (s *Service) CreateAliasedCollection(label, alias string) (collection *Collection, err error) {


var call *dbus.Call
var variant *dbus.Variant var variant *dbus.Variant
var path dbus.ObjectPath var path dbus.ObjectPath
var promptPath dbus.ObjectPath var promptPath dbus.ObjectPath
@ -90,9 +97,13 @@ func (s *Service) CreateAliasedCollection(label, alias string) (collection *Coll
props[DbusCollectionCreated] = dbus.MakeVariant(uint64(time.Now().Unix())) props[DbusCollectionCreated] = dbus.MakeVariant(uint64(time.Now().Unix()))
props[DbusCollectionModified] = dbus.MakeVariant(uint64(time.Now().Unix())) props[DbusCollectionModified] = dbus.MakeVariant(uint64(time.Now().Unix()))


if err = s.Dbus.Call( if call = s.Dbus.Call(
DbusServiceCreateCollection, 0, props, alias, DbusServiceCreateCollection, 0, props, alias,
).Store(&path, &promptPath); err != nil { ); call.Err != nil {
err = call.Err
return
}
if err = call.Store(&path, &promptPath); err != nil {
return return
} }


@ -197,6 +208,7 @@ func (s *Service) GetSecrets(itemPaths ...dbus.ObjectPath) (secrets map[dbus.Obj
} }
*/ */
var results map[dbus.ObjectPath][]interface{} var results map[dbus.ObjectPath][]interface{}
var call *dbus.Call


if itemPaths == nil || len(itemPaths) == 0 { if itemPaths == nil || len(itemPaths) == 0 {
err = ErrMissingPaths err = ErrMissingPaths
@ -207,9 +219,13 @@ func (s *Service) GetSecrets(itemPaths ...dbus.ObjectPath) (secrets map[dbus.Obj
results = make(map[dbus.ObjectPath][]interface{}, len(itemPaths)) results = make(map[dbus.ObjectPath][]interface{}, len(itemPaths))


// TODO: trigger a Service.Unlock for any locked items? // TODO: trigger a Service.Unlock for any locked items?
if err = s.Dbus.Call( if call = s.Dbus.Call(
DbusServiceGetSecrets, 0, itemPaths, s.Session.Dbus.Path(), DbusServiceGetSecrets, 0, itemPaths, s.Session.Dbus.Path(),
).Store(&results); err != nil { ); call.Err != nil {
err = call.Err
return
}
if err = call.Store(&results); err != nil {
return return
} }


@ -236,6 +252,7 @@ func (s *Service) GetSession() (ssn *Session, err error) {
// Lock locks an Unlocked Collection or Item (LockableObject). // Lock locks an Unlocked Collection or Item (LockableObject).
func (s *Service) Lock(objects ...LockableObject) (err error) { func (s *Service) Lock(objects ...LockableObject) (err error) {


var call *dbus.Call
var toLock []dbus.ObjectPath var toLock []dbus.ObjectPath
// We only use these as destinations. // We only use these as destinations.
var locked []dbus.ObjectPath var locked []dbus.ObjectPath
@ -253,9 +270,13 @@ func (s *Service) Lock(objects ...LockableObject) (err error) {
toLock[idx] = o.path() toLock[idx] = o.path()
} }


if err = s.Dbus.Call( if call = s.Dbus.Call(
DbusServiceLock, 0, toLock, DbusServiceLock, 0, toLock,
).Store(&locked, &promptPath); err != nil { ); call.Err != nil {
err = call.Err
return
}
if err = call.Store(&locked, &promptPath); err != nil {
return return
} }


@ -285,6 +306,7 @@ func (s *Service) Lock(objects ...LockableObject) (err error) {
*/ */
func (s *Service) OpenSession(algo, input string) (session *Session, output dbus.Variant, err error) { func (s *Service) OpenSession(algo, input string) (session *Session, output dbus.Variant, err error) {


var call *dbus.Call
var path dbus.ObjectPath var path dbus.ObjectPath
var inputVariant dbus.Variant var inputVariant dbus.Variant


@ -298,9 +320,13 @@ func (s *Service) OpenSession(algo, input string) (session *Session, output dbus
// TODO: confirm this. // TODO: confirm this.
// Possible flags are dbus.Flags consts: https://pkg.go.dev/github.com/godbus/dbus#Flags // Possible flags are dbus.Flags consts: https://pkg.go.dev/github.com/godbus/dbus#Flags
// Oddly, there is no "None" flag. So it's explicitly specified as a null byte. // Oddly, there is no "None" flag. So it's explicitly specified as a null byte.
if err = s.Dbus.Call( if call = s.Dbus.Call(
DbusServiceOpenSession, 0, algo, inputVariant, DbusServiceOpenSession, 0, algo, inputVariant,
).Store(&output, &path); err != nil { ); call.Err != nil {
err = call.Err
return
}
if err = call.Store(&output, &path); err != nil {
return return
} }


@ -316,17 +342,20 @@ func (s *Service) OpenSession(algo, input string) (session *Session, output dbus
*/ */
func (s *Service) ReadAlias(alias string) (collection *Collection, err error) { func (s *Service) ReadAlias(alias string) (collection *Collection, err error) {


var call *dbus.Call
var objectPath dbus.ObjectPath var objectPath dbus.ObjectPath


err = s.Dbus.Call( if call = s.Dbus.Call(
DbusServiceReadAlias, 0, alias, DbusServiceReadAlias, 0, alias,
).Store(&objectPath) ); call.Err != nil {

err = call.Err
return
}
/* /*
TODO: Confirm that a nonexistent alias will NOT cause an error to return. TODO: Confirm that a nonexistent alias will NOT cause an error to return.
If it does, alter the below logic. If it does, alter the below logic.
*/ */
if err != nil { if err = call.Store(&objectPath); err != nil {
return return
} }


@ -358,6 +387,7 @@ func (s *Service) RemoveAlias(alias string) (err error) {
*/ */
func (s *Service) SearchItems(attributes map[string]string) (unlockedItems []*Item, lockedItems []*Item, err error) { func (s *Service) SearchItems(attributes map[string]string) (unlockedItems []*Item, lockedItems []*Item, err error) {


var call *dbus.Call
var locked []dbus.ObjectPath var locked []dbus.ObjectPath
var unlocked []dbus.ObjectPath var unlocked []dbus.ObjectPath
var collectionObjs []*Collection var collectionObjs []*Collection
@ -373,9 +403,13 @@ func (s *Service) SearchItems(attributes map[string]string) (unlockedItems []*It
return return
} }


err = s.Dbus.Call( if call = s.Dbus.Call(
DbusServiceSearchItems, 0, attributes, DbusServiceSearchItems, 0, attributes,
).Store(&unlocked, &locked) ); call.Err != nil {
}
if err = call.Store(&unlocked, &locked); err != nil {
return
}


lockedItems = make([]*Item, 0) lockedItems = make([]*Item, 0)
unlockedItems = make([]*Item, 0) unlockedItems = make([]*Item, 0)
@ -450,18 +484,17 @@ func (s *Service) SearchItems(attributes map[string]string) (unlockedItems []*It
*/ */
func (s *Service) SetAlias(alias string, objectPath dbus.ObjectPath) (err error) { func (s *Service) SetAlias(alias string, objectPath dbus.ObjectPath) (err error) {


var c *dbus.Call var call *dbus.Call
var collection *Collection var collection *Collection


if collection, err = s.GetCollection(alias); err != nil { if collection, err = s.GetCollection(alias); err != nil {
return return
} }


c = s.Dbus.Call( if call = s.Dbus.Call(
DbusServiceSetAlias, 0, alias, objectPath, DbusServiceSetAlias, 0, alias, objectPath,
) ); call.Err != nil {

err = call.Err
if err = c.Err; err != nil {
return return
} }


@ -477,6 +510,7 @@ func (s *Service) SetAlias(alias string, objectPath dbus.ObjectPath) (err error)
// Unlock unlocks a locked Collection or Item (LockableObject). // Unlock unlocks a locked Collection or Item (LockableObject).
func (s *Service) Unlock(objects ...LockableObject) (err error) { func (s *Service) Unlock(objects ...LockableObject) (err error) {


var call *dbus.Call
var toUnlock []dbus.ObjectPath var toUnlock []dbus.ObjectPath
// We only use these as destinations. // We only use these as destinations.
var unlocked []dbus.ObjectPath var unlocked []dbus.ObjectPath
@ -494,9 +528,13 @@ func (s *Service) Unlock(objects ...LockableObject) (err error) {
toUnlock[idx] = o.path() toUnlock[idx] = o.path()
} }


if err = s.Dbus.Call( if call = s.Dbus.Call(
DbusServiceUnlock, 0, toUnlock, DbusServiceUnlock, 0, toUnlock,
).Store(&unlocked, &resultPath); err != nil { ); call.Err != nil {
err = call.Err
return
}
if err = call.Store(&unlocked, &resultPath); err != nil {
return return
} }



View File

@ -1,6 +1,8 @@
package gosecret package gosecret


import ( import (
"fmt"

"github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5"
) )


@ -32,13 +34,21 @@ func NewSession(service *Service, path dbus.ObjectPath) (session *Session, err e
// Close cleanly closes a Session. // Close cleanly closes a Session.
func (s *Session) Close() (err error) { func (s *Session) Close() (err error) {


var c *dbus.Call var call *dbus.Call


c = s.Dbus.Call( if call = s.Dbus.Call(
DbusSessionClose, 0, DbusSessionClose, 0,
) ); call.Err != nil {

/*
_ = c I... still haven't 100% figured out why this happens, but the session DOES seem to close...?
PRs or input welcome.
TODO: figure out why this error gets triggered.
*/
if call.Err.Error() != fmt.Sprintf("The name %v was not provided by any .service files", DbusInterfaceSession) {
err = call.Err
return
}
}


return return
} }