162 γραμμές
3,4 KiB
Go
162 γραμμές
3,4 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"log"
|
||
|
"os/exec"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/godbus/dbus"
|
||
|
"github.com/godbus/dbus/introspect"
|
||
|
"github.com/99designs/keyring"
|
||
|
)
|
||
|
|
||
|
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 = `
|
||
|
<node>
|
||
|
<interface name="org.kde.krunner1">
|
||
|
<method name="Actions">
|
||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="RemoteActions" />
|
||
|
<arg name="matches" type="a(sss)" direction="out" />
|
||
|
</method>
|
||
|
<method name="Run">
|
||
|
<arg name="matchId" type="s" direction="in"/>
|
||
|
<arg name="actionId" type="s" direction="in"/>
|
||
|
</method>
|
||
|
<method name="Match">
|
||
|
<arg name="query" type="s" direction="in"/>
|
||
|
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="RemoteMatches"/>
|
||
|
<arg name="matches" type="a(sssida{sv})" direction="out"/>
|
||
|
</method>
|
||
|
</interface>` + introspect.IntrospectDataString + `</node>`
|
||
|
|
||
|
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",
|
||
|
})
|
||
|
if err != nil {
|
||
|
log.Fatal("Unable to Open KDE Wallet ", err.Error())
|
||
|
}
|
||
|
r.wallet = wallet
|
||
|
|
||
|
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, _ := r.wallet.Get(selection)
|
||
|
log.Println(code.Data)
|
||
|
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
|
||
|
|
||
|
}
|
||
|
|