5 "github.com/keybase/go-keychain"
19 var cache 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 reload := make(chan os.Signal, 1)
44 signal.Notify(reload, syscall.SIGUSR1)
48 log.Print("Got signal ", sig, ": resetting")
53 // Need to catch signals in order for `defer`-ed clean-up items to run.
54 term := make(chan os.Signal, 1)
55 signal.Notify(term, os.Interrupt, os.Kill, syscall.SIGTERM)
57 log.Print("Got signal ", sig)
61 cache = make(map[string][]byte)
64 func getSockPath() string {
65 user, err := user.Current()
69 return user.HomeDir + "/.passage.sock"
72 func handleConnection(conn net.Conn) {
74 decoder := json.NewDecoder(conn)
76 err := decoder.Decode(&request)
82 cache_key, err := json.Marshal(request)
86 if cached, exists := cache[string(cache_key)]; exists {
88 log.Print("Wrote result from cache")
92 query := keychain.NewItem()
93 query.SetSecClass(keychain.SecClassGenericPassword)
94 query.SetService(request.Service)
95 query.SetAccount(request.Account)
96 query.SetMatchLimit(keychain.MatchLimitOne)
97 query.SetReturnData(true)
98 results, err := keychain.QueryItem(query)
101 } else if len(results) != 1 {
102 log.Print("Item not found")
104 password := results[0].Data
106 cache[string(cache_key)] = password
107 log.Print("Wrote result from keychain")