5 "github.com/keybase/go-keychain"
19 var cache map[string][]byte
22 cache = make(map[string][]byte)
25 listener, err := net.Listen("unix", path)
29 defer listener.Close()
33 conn, err := listener.Accept()
38 go handleConnection(conn)
41 log.Print("Open and ready for business on UNIX socket at ", path)
43 // Need to catch signals in order for `defer`-ed clean-up items to run.
44 c := make(chan os.Signal, 1)
45 signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGTERM)
47 log.Print("Got signal ", sig)
50 func getSockPath() string {
51 user, err := user.Current()
55 return user.HomeDir + "/.passage.sock"
58 func handleConnection(conn net.Conn) {
60 decoder := json.NewDecoder(conn)
62 err := decoder.Decode(&request)
68 cache_key, err := json.Marshal(request)
72 if cached, exists := cache[string(cache_key)]; exists {
74 log.Print("Wrote result from cache")
78 query := keychain.NewItem()
79 query.SetSecClass(keychain.SecClassGenericPassword)
80 query.SetService(request.Service)
81 query.SetAccount(request.Account)
82 query.SetMatchLimit(keychain.MatchLimitOne)
83 query.SetReturnData(true)
84 results, err := keychain.QueryItem(query)
87 } else if len(results) != 1 {
88 log.Print("Item not found")
90 password := results[0].Data
92 cache[string(cache_key)] = password
93 log.Print("Wrote result from keychain")