mirror of
https://github.com/kemko/xc.git
synced 2026-01-01 15:55:43 +03:00
102 lines
2.3 KiB
Go
102 lines
2.3 KiB
Go
package passmgr
|
|
|
|
import (
|
|
"fmt"
|
|
"plugin"
|
|
|
|
"github.com/viert/xc/log"
|
|
"github.com/viert/xc/term"
|
|
)
|
|
|
|
const (
|
|
initFuncName = "Init"
|
|
acquireFuncName = "GetPass"
|
|
)
|
|
|
|
var (
|
|
p *plugin.Plugin
|
|
initialFilename string
|
|
initialOptions map[string]string
|
|
initialized bool
|
|
pluginInit func(map[string]string, func(string, ...interface{})) error
|
|
pluginAcquire func(string) string
|
|
)
|
|
|
|
// Load loads a password manager library
|
|
func Load(filename string, options map[string]string) error {
|
|
var err error
|
|
|
|
initialFilename = filename
|
|
initialOptions = options
|
|
|
|
p, err = plugin.Open(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
init, err := p.Lookup(initFuncName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
pluginInit, initialized = init.(func(map[string]string, func(string, ...interface{})) error)
|
|
if !initialized {
|
|
return fmt.Errorf("invalid plugin `%s() error` function signature", initFuncName)
|
|
}
|
|
|
|
acq, err := p.Lookup(acquireFuncName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
pluginAcquire, initialized = acq.(func(string) string)
|
|
if !initialized {
|
|
return fmt.Errorf("invalid plugin `%s(string) string` function signature", acquireFuncName)
|
|
}
|
|
|
|
err = pluginInit(options, log.Debugf)
|
|
initialized = err == nil
|
|
|
|
return err
|
|
}
|
|
|
|
// GetPass returns password for a given host from password manager
|
|
func GetPass(hostname string) string {
|
|
if !initialized {
|
|
return ""
|
|
}
|
|
return pluginAcquire(hostname)
|
|
}
|
|
|
|
// Ready returns a bool value indicating if the passmgr is initialized and ready to use
|
|
func Ready() bool {
|
|
return initialized
|
|
}
|
|
|
|
// Reload reloads previously initialized plugin
|
|
func Reload() error {
|
|
term.Warnf("Reloading password manager from %s\n", initialFilename)
|
|
return Load(initialFilename, initialOptions)
|
|
}
|
|
|
|
// PrintDebug proxies a call to plugin's PrintDebug function if it exists
|
|
func PrintDebug() {
|
|
if !initialized {
|
|
term.Errorf("password manager is not initialized\n")
|
|
return
|
|
}
|
|
|
|
printsym, err := p.Lookup("PrintDebug")
|
|
if err != nil {
|
|
term.Errorf("the password manager doesn't have PrintDebug() handler\n")
|
|
return
|
|
}
|
|
|
|
printfunc, ok := printsym.(func())
|
|
if !ok {
|
|
term.Errorf("the passwordd manager PrintDebug() handler has invalid signature (must be func())\n")
|
|
return
|
|
}
|
|
term.Warnf("running password manager PrintDebug()\n")
|
|
printfunc()
|
|
fmt.Println()
|
|
}
|