package main import ( "log" "os/exec" "strings" "github.com/99designs/keyring" "github.com/godbus/dbus" "github.com/godbus/dbus/introspect" ) var messages = map[string]string{ "errconn": "DBus Connection Problem", "errname": "DBus Unable to request name or name taken", } const servicename = "labs.infl00p.otp" const ifacename = "org.kde.krunner1" const ifacepath = "/krunner" const intro = ` ` + introspect.IntrospectDataString + `` type runner struct { wallet keyring.Keyring } type match struct { ID string Text string IconName string Type int32 Relevance float64 Properties map[string]interface{} } func main() { var r runner // Open Dbus Connection conn, err := dbus.SessionBus() if err != nil { log.Fatal(messages["errconn"]) } rep, err := conn.RequestName(servicename, dbus.NameFlagDoNotQueue) if err != nil || rep != dbus.RequestNameReplyPrimaryOwner { log.Fatal(messages["errname"]) } // KWallet wallet, err := keyring.Open(keyring.Config{ AllowedBackends: []keyring.BackendType{keyring.KWalletBackend}, ServiceName: "kdewallet", KWalletFolder: "otprunner", KWalletAppID: "otprunner", }) if err != nil { log.Fatal("Unable to Open KDE Wallet ", err.Error()) } r.wallet = wallet // test data r.wallet.Set(keyring.Item{"koko1",[]byte("lala1"),"Label koko1", "Description1", true, true}) r.wallet.Set(keyring.Item{"koko2",[]byte("lala2"),"Label koko2", "Description2", true, true}) conn.Export(r, ifacepath, ifacename) conn.Export(introspect.Introspectable(intro), ifacepath, "org.freedesktop.DBus.Introspectable") // block select {} } func (r runner) Actions() ([]string, *dbus.Error) { return []string{}, nil } func (r runner) Match(query string) ([]match, *dbus.Error) { key := strings.Split(query, " ") matches := make([]match,0,100) // List all keys in keyring keys, err := r.wallet.Keys() if err != nil { log.Fatal("List Keys ", err.Error()) } if len(key) > 1 && key[0] == "otp" { if len(keys) > 0 { size:=0 rel:=1.0 for i, v := range(keys) { if v != "" && strings.Contains(v,key[1]) { log.Println(size) matches=matches[:size+1] matches[size].ID = strings.ToLower(strings.Replace(v," ", "_",-1)) matches[size].Text = v matches[size].IconName = "document-export-key" matches[size].Type = 100 matches[size].Relevance = rel rel= rel/1.1 size+=1 log.Println(i, matches[i]) } } return matches, nil } } return matches, nil } func (r runner) Run(selection string, id string) *dbus.Error { code, err := r.wallet.Get(selection) if err != nil { log.Println(code) log.Println(err) } err = AddToClipboard(string(code.Data)) if err != nil { log.Fatal(err) } return nil } func AddToClipboard(s string) error { cmd := exec.Command("xclip","-r","-selection","clipboard") stdin, err := cmd.StdinPipe() if err != nil { return err } err = cmd.Start() if err != nil { return err } _, err = stdin.Write([]byte(s)) if err != nil { return err } err = stdin.Close() if err != nil { return err } err = cmd.Wait() if err != nil { return err } return nil }