some funcs stubbed out, Dbus methods in consts.

This commit is contained in:
brent s. 2021-12-15 03:48:40 -05:00
parent 6591aec7a8
commit ebe91c867c
Signed by: bts
GPG Key ID: 8C004C2F93481F6B
9 changed files with 409 additions and 8 deletions

3
.ref/URLs Normal file
View File

@ -0,0 +1,3 @@
https://api.kde.org/frameworks/kwallet/html/index.html

Dbus methods etc.: https://invent.kde.org/frameworks/kwallet/-/blob/master/src/api/KWallet/org.kde.KWallet.xml

3
TODO Normal file
View File

@ -0,0 +1,3 @@
- XML import/export?
-- compat with kwalletmanager
--- Will require conversion to different struct model.

165
consts.go Normal file
View File

@ -0,0 +1,165 @@
package gokwallet

// KWalletD Dbus interfaces.
const (
// DbusService is the Dbus service bus identifier.
DbusService string = "org.kde.kwalletd5"
// DbusServiceBase is the base identifier used by interfaces.
DbusServiceBase string = "org.kde"
)

// gokwallet defaults.
const (
// DefaultWalletName is the name of the default Wallet to use.
DefaultWalletName string = "kdewallet"
// DefaultAppID is the default name for the application (see WalletManager.AppID).
DefaultAppID string = "GoKwallet"
)

// WalletManager interface.
const (
/*
DbusInterfaceWM is the Dbus interface for working with a WalletManager.
*/
DbusInterfaceWM string = DbusServiceBase + ".KWallet"

// Methods

// DbusWMChangePassword changes the password for a Wallet.
DbusWMChangePassword string = DbusInterfaceWM + ".changePassword"

// DbusWMClose closes an App (WalletManager) or Wallet.
DbusWMClose string = DbusInterfaceWM + ".close"

// DbusWMCloseAllWallets closes all WalletManager.Wallets.
DbusWMCloseAllWallets string = DbusInterfaceWM + ".closeAllWallets"

// DbusWMCreateFolder creates a Folder.
DbusWMCreateFolder string = DbusInterfaceWM + ".createFolder"

// DbusWMDeleteWallet deletes/removes a Wallet.
DbusWMDeleteWallet string = DbusInterfaceWM + ".deleteWallet"

// DbusWMDisconnectApp disconnects a WalletManager (or other App).
DbusWMDisconnectApp string = DbusInterfaceWM + ".disconnectApplication"

// DbusWMEntriesList returns a *map* of the WalletItem objects in a Folder (with their entry name as the map key).
DbusWMEntriesList string = DbusInterfaceWM + ".entriesList"

// DbusWMEntryList returns a *slice* of WalletItem names in a Folder.
DbusWMEntryList string = DbusInterfaceWM + ".entryList"

// DbusWMEntryType returns the type of a WalletItem.
DbusWMEntryType string = DbusInterfaceWM + ".entryType"

// DbusWMFolderNotExist indicates if a Folder exists within a Wallet or not.
DbusWMFolderNotExist string = DbusInterfaceWM + ".folderDoesNotExist"

// DbusWMFolderList lists the Folder objects (as Folder.Name) in a Wallet.
DbusWMFolderList string = DbusInterfaceWM + ".folderList"

// DbusWMHasEntry indicates if a Folder has a WalletItem or not.
DbusWMHasEntry string = DbusInterfaceWM + ".hasEntry"

// DbusWMHasFolder indicates if a Wallet has a Folder or not.
DbusWMHasFolder string = DbusInterfaceWM + ".hasFolder"

/*
DbusWMIsEnabled indicates if KWallet is enabled.
TODO: Is this accurate?
*/
DbusWMIsEnabled string = DbusInterfaceWM + ".isEnabled"

// DbusWMIsOpen indicates if a Wallet is open (unlocked).
DbusWMIsOpen string = DbusInterfaceWM + ".isOpen"

// DbusWMKeyNotExist indicates if a Folder has a WalletItem or not.
DbusWMKeyNotExist string = DbusInterfaceWM + ".keyDoesNotExist"

// DbusWMLocalWallet gives the name of the local (default?) Wallet.
DbusWMLocalWallet string = DbusInterfaceWM + ".localWallet"

// DbusWMMapList gives a list of Map names in a Folder.
DbusWMMapList string = DbusInterfaceWM + ".mapList"

/*
DbusWMNetWallet indicates if a Wallet is a Network Wallet or not.
TODO: is/was this ever used?
*/
DbusWMNetWallet string = DbusInterfaceWM + ".networkWallet"

// DbusWMOpen opens (unlocks) a Wallet.
DbusWMOpen string = DbusInterfaceWM + ".open"

// DbusWMOpenAsync opens (unlocks) a Wallet asynchronously.
DbusWMOpenAsync string = DbusInterfaceWM + ".openAsync"

// DbusWMOpenPath opens (unlocks) a Wallet by its filepath.
DbusWMOpenPath string = DbusInterfaceWM + ".openPath"

// DbusWMOpenPathAsync opens (unlocks) a Wallet by its filepath asynchronously.
DbusWMOpenPathAsync string = DbusInterfaceWM + ".openPath"

// DbusWMPamOpen opens (unlocks) a Wallet via PAM.
DbusWMPamOpen string = DbusInterfaceWM + ".pamOpen"

/*
DbusWMPasswordList returns a map of Password objects in a Folder.
Password.Name is the map key.
*/
DbusWMPasswordList string = DbusInterfaceWM + ".passwordList"

// DbusWMReadEntry fetches a WalletItem by its name from a Folder (as a byteslice).
DbusWMReadEntry string = DbusInterfaceWM + ".readEntry"

// DbusWMReadEntryList returns a map of WalletItem objects in a Folder.
DbusWMReadEntryList string = DbusInterfaceWM + ".readEntryList"

// DbusWMReadMap returns a Map from a Folder (as a byteslice).
DbusWMReadMap string = DbusInterfaceWM + ".readMap"

// DbusWMReadMapList returns a map of Map objects in a Folder.
DbusWMReadMapList string = DbusInterfaceWM + ".readMapList"

// DbusWMReadPassword returns a Password from a Folder (as a byteslice).
DbusWMReadPassword string = DbusInterfaceWM + ".readPassword"

// DbusWMReadPasswordList returns a map of Password objects in a Folder.
DbusWMReadPasswordList string = DbusInterfaceWM + ".readPasswordList"

// DbusWMReconfigure is [FUNCTION UNKNOWN/UNDOCUMENTED; TODO? NOT IMPLEMENTED.]
// DbusWMReconfigure string = DbusInterfaceWM + ".reconfigure"

// DbusWMRemoveEntry removes a WalletItem from a Folder.
DbusWMRemoveEntry string = DbusInterfaceWM + ".removeEntry"

// DbusWMRemoveFolder removes a Folder from a Wallet.
DbusWMRemoveFolder string = DbusInterfaceWM + ".removeFolder"

// DbusWMRenameEntry renames ("moves") a WalletItem.
DbusWMRenameEntry string = DbusInterfaceWM + ".renameEntry"

// DbusWMSync is [FUNCTION UNKNOWN/UNDOCUMENTED; TODO? RELATED TO ASYNC? NOT IMPLEMENTED.]
// DbusWMSync string = DbusInterfaceWM + ".sync"

// DbusWMUsers returns a slice of users.
DbusWMUsers string = DbusInterfaceWM + ".users"

// DbusWMWallets returns an array of Wallet names.
DbusWMWallets string = DbusInterfaceWM + ".wallets"

// DbusWMWriteEntry writes (creates) a WalletItem to/in a Folder.
DbusWMWriteEntry string = DbusInterfaceWM + ".writeEntry"

// DbusWMWriteMap writes (creates) a Map (via a byteslice) to/in a Folder.
DbusWMWriteMap string = DbusInterfaceWM + ".writeMap"

// DbusWMWritePassword writes (creates) a Password to/in a Folder.
DbusWMWritePassword string = DbusInterfaceWM + ".writePassword"
)

// Dbus paths.
const (
// DbusPath is the path for DbusService.
DbusPath string = "/modules/kwalletd5"
)

45
doc.go
View File

@ -3,15 +3,18 @@
/*
Package gokwallet serves as a Golang interface to KDE's KWallet (https://utils.kde.org/projects/kwalletmanager/).

Note that to use this library, the running machine must have both Dbus and kwalletd running.

Note that this library interfaces with kwalletd. KWallet is in the process of moving to libsecret/SecretService
(see https://bugs.kde.org/show_bug.cgi?id=313216 and https://invent.kde.org/frameworks/kwallet/-/merge_requests/11).
(see https://bugs.kde.org/show_bug.cgi?id=313216 and https://invent.kde.org/frameworks/kwallet/-/merge_requests/11),
thus replacing kwalletd.
While there is a pull request in place, it has not yet been merged in (and it may be a while before downstream
distributions incorporate that version). However, when that time comes I highly recommend using my `gosecret`
library to interface with that (module r00t2.io/gosecret; see https://pkg.go.dev/r00t2.io/gosecret).

KWallet has the following structure (modified slightly to reflect this library):

- A main Dbus service interface ("org.kde.kwalletd5") allows one to retrieve and operate on/with Wallet items.
- A main Dbus service interface ("org.kde.kwalletd5"), WalletManager, allows one to retrieve and operate on/with Wallet items.

- One or more Wallet items allow one to retrieve and operate on/with Folder items.

@ -23,25 +26,51 @@ Thus, the hierarchy (as exposed by this library) looks like this:
├─ Wallet "A"
│ ├─ Folder "A_1"
│ │ ├─ Passwords
│ │ │ ├─ Password "A_1_a"
│ │ │ └─ Password "A_1_b"
│ │ ├─ Maps
│ │ │ ├─ Map "A_1_a"
│ │ │ └─ Map "A_1_b"
│ │ ├─ BinaryData
│ │ │ ├─ Blob "A_1_a"
│ │ │ └─ Blob "A_1_b"
│ │ └─ Unknown
│ │ ├─ UnknownItem "A_1_a"
│ │ └─ UnknownItem "A_1_b"
│ └─ Folder "A_2"
│ ├─ Passwords
│ │ ├─ Password "A_2_a"
│ │ └─ Password "A_2_b"
│ ├─ Maps
│ │ ├─ Map "A_2_a"
│ │ └─ Map "A_2_b"
│ ├─ BinaryData
│ │ ├─ Blob "A_2_a"
│ │ └─ Blob "A_2_b"
│ └─ Unknown
│ ├─ UnknownItem "A_2_a"
│ └─ UnknownItem "A_2_b"
└─ Wallet "B"
├─ Folder "B_1"
│ ├─ Passwords
│ ├─ Maps
│ ├─ BinaryData
│ └─ Unknown
└─ Folder "B_2"
└─ Folder "B_1"
├─ Passwords
│ ├─ Password "B_1_a"
│ └─ Password "B_1_b"
├─ Maps
│ ├─ Map "B_1_a"
│ └─ Map "B_1_b"
├─ BinaryData
│ ├─ Blob "B_1_a"
│ └─ Blob "B_1_b"
└─ Unknown
├─ UnknownItem "B_1_a"
└─ UnknownItem "B_1_b"

This is an approximation, but should show a relatively accurate representation of the model.
Note that most systems are likely to only have a single wallet, "kdewallet".

Usage

Full documentation can be found via inline documentation.
Additionally, use either https://pkg.go.dev/r00t2.io/gokwallet or https://pkg.go.dev/golang.org/x/tools/cmd/godoc (or `go doc`) in the source root.
*/
package gokwallet

2
go.mod
View File

@ -1,3 +1,5 @@
module r00t2.io/gokwallet

go 1.17

require github.com/godbus/dbus/v5 v5.0.6

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro=
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=

133
types.go Normal file
View File

@ -0,0 +1,133 @@
package gokwallet

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

/*
MultiError is a type of error.Error that can contain multiple error.Errors. Confused? Don't worry about it.
*/
type MultiError struct {
// Errors is a slice of errors to combine/concatenate when .Error() is called.
Errors []error `json:"errors"`
// ErrorSep is a string to use to separate errors for .Error(). The default is "\n".
ErrorSep string `json:"separator"`
}

// ConnPathCheckResult contains the result of validConnPath.
type ConnPathCheckResult struct {
// ConnOK is true if the dbus.Conn is valid.
ConnOK bool `json:"conn"`
// PathOK is true if the Dbus path given is a valid type and value.
PathOK bool `json:"path"`
}

// DbusObject is a base struct type to be anonymized by other types.
type DbusObject struct {
// Conn is an active connection to the Dbus.
Conn *dbus.Conn `json:"-"`
// Dbus is the Dbus bus object.
Dbus dbus.BusObject `json:"-"`
}

/*
WalletManager is a general KWallet interface, sort of a handler for Dbus.
It's used for fetching Wallet objects.
*/
type WalletManager struct {
*DbusObject
/*
AppID is the application ID.
The default is DefaultAppID.
*/
AppID string `json:"app_id"`
/*
Wallets is the collection of Wallets accessible in/to this WalletManager.
Wallet.Name is the map key.
*/
Wallets map[string]*Wallet `json:"wallets"`
}

// Wallet contains one or more (or none) Folder objects.
type Wallet struct {
*DbusObject
// Name is the name of this Wallet.
Name string `json:"name"`
/*
Folders contains all Folder objects in this Wallet.
Folder.Name is the map key.
*/
Folders map[string]*Folder `json:"folders"`
}

// Folder contains secret object collections of Password, Map, Blob, and UnknownItem objects.
type Folder struct {
*DbusObject
// Name is the name of this Folder.
Name string `json:"name"`
/*
Passwords contains a map of all Password objects in this Folder.
Password.Name is the map key.
*/
Passwords map[string]*Password `json:"passwords"`
/*
Maps contains a map of all Map objects in this Folder.
Map.Name is the map key.
*/
Maps map[string]*Map `json:"maps"`
/*
BinaryData contains a map if all Blob objects in this Folder.
Blob.Name is the map key.
*/
BinaryData map[string]*Blob `json:"binary_data"`
/*
Unknown contains a map of all UnknownItem objects in this Folder.
Unknown.Name is the map key.
*/
Unknown map[string]*UnknownItem `json:"unknown"`
}

// Password is a straightforward single-value secret of text.
type Password struct {
*DbusObject
// Name is the name of this Password.
Name string `json:"name"`
// Value is this Password's value.
Value string `json:"value"`
}

// Map is a dictionary or key/value secret.
type Map struct {
*DbusObject
// Name is the name of this Map.
Name string `json:"name"`
// Value is this Map's value.
Value map[string]string `json:"value"`
}

// Blob (binary large object, typographically BLOB) is secret binary data.
type Blob struct {
*DbusObject
// Name is the name of this Blob.
Name string `json:"name"`
// Value is this Blob's value.
Value []byte `json:"value"`
}

/*
UnknownItem is a secret item of unknown classification, so there isn't exactly a good way of determining a type for UnknownItem.Value.
As such, its dbus.ObjectPath is used.
TODO: There may be a method to fetch the raw bytes of the object (such as one would use with Blob) in the future.
*/
type UnknownItem struct {
*DbusObject
// Name is the name of this UnknownItem.
Name string `json:"name"`
// Value is the Dbus path of this UnknownItem.
Value dbus.ObjectPath `json:"value"`
}

// WalletItem is an interface to manage wallet objects: Password, Map, Blob, or UnknownItem.
type WalletItem interface {
isWalletItem() (isWalletItem bool)
}

14
wallet_funcs.go Normal file
View File

@ -0,0 +1,14 @@
package gokwallet

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

func NewWallet(wm *WalletManager, path dbus.ObjectPath) (wallet *Wallet, err error) {

var open bool

_ = open

return
}

50
walletmanager_funcs.go Normal file
View File

@ -0,0 +1,50 @@
package gokwallet

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

/*
NewWalletManager returns a WalletManager.
If appId is empty/nil, DefaultAppID will be used as the app ID.
If appId is specified, only the first string is used.
*/
func NewWalletManager(appID ...string) (wm *WalletManager, err error) {

var realAppID string

if appID != nil && len(appID) > 0 {
realAppID = appID[0]
} else {
realAppID = DefaultAppID
}

wm = &WalletManager{
DbusObject: &DbusObject{
Conn: nil,
Dbus: nil,
},
AppID: realAppID,
Wallets: make(map[string]*Wallet),
}

if wm.DbusObject.Conn, err = dbus.SessionBus(); err != nil {
return
}
wm.DbusObject.Dbus = wm.DbusObject.Conn.Object(DbusService, dbus.ObjectPath(DbusPath))

return
}

/*
Update fetches/updates all Wallet objects in a WalletManager.
*/
func (wm *WalletManager) Update() (err error) {

var wallets []*Wallet

// TODO.
_ = wallets

return
}