listener.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. package keychainlinker
  2. import (
  3. "fmt"
  4. "path"
  5. "strconv"
  6. "github.com/godbus/dbus/v5"
  7. "github.com/godbus/dbus/v5/introspect"
  8. )
  9. const DbusAdv = `
  10. <node>
  11. <interface name="dev.aetherial.git.KeychainLinker.Service">
  12. <method name="OpenSession">
  13. <arg name="algorithm" direction="in" type="s"/>
  14. <arg name="input" direction="in" type="v"/>
  15. <arg name="output" direction="out" type="v"/>
  16. <arg name="result" direction="out" type="o"/>
  17. </method>
  18. <method name="CreateCollection">
  19. <arg name="properties" direction="in" type="a{sv}"/>
  20. <arg name="alias" direction="in" type="s"/>
  21. <arg name="collection" direction="out" type="o"/>
  22. <arg name="prompt" direction="out" type="o"/>
  23. </method>
  24. <method name="SearchItems">
  25. <arg name="attributes" direction="in" type="a{ss}"/>
  26. <arg name="unlocked" direction="out" type="ao"/>
  27. <arg name="locked" direction="out" type="ao"/>
  28. </method>
  29. <method name="Unlock">
  30. <arg name="objects" direction="in" type="ao"/>
  31. <arg name="unlocked" direction="out" type="ao"/>
  32. <arg name="prompt" direction="out" type="o"/>
  33. </method>
  34. <method name="Lock">
  35. <arg name="objects" direction="in" type="ao"/>
  36. <arg name="locked" direction="out" type="ao"/>
  37. <arg name="prompt" direction="out" type="o"/>
  38. </method>
  39. <method name="GetSecrets">
  40. <arg name="items" direction="in" type="ao"/>
  41. <arg name="session" direction="in" type="o"/>
  42. <arg name="secrets" direction="out" type="a{o(ayays)}"/>
  43. </method>
  44. <method name="ReadAlias">
  45. <arg name="name" direction="in" type="s"/>
  46. <arg name="collection" direction="out" type="o"/>
  47. </method>
  48. <method name="SetAlias">
  49. <arg name="name" direction="in" type="s"/>
  50. <arg name="collection" direction="in" type="o"/>
  51. </method>
  52. <property name="Collections" type="ao" access="read"/>
  53. </interface>` + introspect.IntrospectDataString + `</node> `
  54. type Session struct {
  55. Path string
  56. Open int
  57. }
  58. /*
  59. Get the next session
  60. */
  61. func (s *Session) next() int {
  62. s.Open = s.Open + 1
  63. return s.Open
  64. }
  65. func (s *Session) OpenSession(algorithm string, input dbus.Variant) (dbus.Variant, dbus.ObjectPath, *dbus.Error) {
  66. if algorithm != "PLAIN" {
  67. return dbus.Variant{}, dbus.ObjectPath(""), &dbus.ErrMsgInvalidArg
  68. }
  69. nextPath := path.Join(s.Path, strconv.Itoa(s.next()))
  70. fmt.Println("recieved algorithm: ", algorithm, "\nresponding with path: ", nextPath)
  71. return dbus.MakeVariant(algorithm), dbus.ObjectPath(nextPath), nil
  72. }
  73. type SecretStruct struct {
  74. Session dbus.ObjectPath
  75. Parameters []byte
  76. Value []byte
  77. ContentType string
  78. }
  79. type SecretService struct {
  80. Collections []dbus.ObjectPath
  81. SessionBase string // e.g. "/org/freedesktop/secrets/session/"
  82. CollectionBase string // e.g. "/org/freedesktop/secrets/collection/"
  83. }
  84. type Collection struct {
  85. }
  86. // deletes the collection
  87. func (c *Collection) Delete() (dbus.ObjectPath, *dbus.Error) {
  88. return dbus.ObjectPath("prompt"), nil
  89. }
  90. /*
  91. Searches the collection for matching items
  92. :param attr: the attributes to attempt to match to a key in the collection
  93. */
  94. func (c *Collection) SearchItems(attr map[string]string) ([]dbus.ObjectPath, *dbus.Error) {
  95. // implement a recursive searching thing
  96. return []dbus.ObjectPath{}, nil
  97. }
  98. /*
  99. Creates a new item in the collection with the properties defined in 'props'.
  100. Returns the items dbus object path, as well as a path to a dbus prompt
  101. :param props: a map of properties to assign to the item
  102. :param secret: the secret to encode into the collection
  103. :param replace: replace secret if a matching one is found in the store
  104. */
  105. func (c *Collection) CreateItem(props map[string]dbus.Variant, secret SecretStruct, replace bool) (dbus.ObjectPath, dbus.ObjectPath) {
  106. return dbus.ObjectPath("/"), dbus.ObjectPath("/")
  107. }
  108. /*
  109. Opens a session for the Secret Service Interface
  110. :param algorithm: the encryption algorithm to use with the client
  111. :param input: the data used when implementing more advanced encryption algos
  112. */
  113. func (s *SecretService) OpenSession(algorithm string, input dbus.Variant) (dbus.Variant, dbus.ObjectPath, *dbus.Error) {
  114. if algorithm != "PLAIN" {
  115. return dbus.Variant{}, "/", dbus.MakeFailedError(fmt.Errorf("only PLAIN is supported"))
  116. }
  117. sessionPath := dbus.ObjectPath(path.Join(s.SessionBase, "1"))
  118. return input, sessionPath, nil
  119. }
  120. /*
  121. Creates a collection with the Service object
  122. :param properties: a set of properties that are used by client apps
  123. :param alias: the shortname of the collection
  124. */
  125. func (s *SecretService) CreateCollection(properties map[string]dbus.Variant, alias string) (dbus.ObjectPath, dbus.ObjectPath, *dbus.Error) {
  126. collPath := dbus.ObjectPath(path.Join(s.CollectionBase, "login"))
  127. s.Collections = append(s.Collections, collPath)
  128. return collPath, "/", nil
  129. }
  130. /*
  131. search for items in the keychain that satisfy 'attrs'
  132. :param attrs: a map of search criteria
  133. */
  134. func (s *SecretService) SearchItems(attrs map[string]string) ([]dbus.ObjectPath, []dbus.ObjectPath, *dbus.Error) {
  135. // Just return empty results for now
  136. return []dbus.ObjectPath{}, []dbus.ObjectPath{}, nil
  137. }
  138. /*
  139. sets all dbus.Objects in 'objects' to the 'unlocked' position
  140. :param objects: a slice of dbus.Objects to unlock
  141. */
  142. func (s *SecretService) Unlock(objects []dbus.ObjectPath) ([]dbus.ObjectPath, dbus.ObjectPath, *dbus.Error) {
  143. return objects, "/", nil // No prompt
  144. }
  145. /*
  146. Sets all dbus.Objects in 'objects' to the 'locked' position
  147. :param objects: a slice of dbus.Objects to unlock
  148. */
  149. func (s *SecretService) Lock(objects []dbus.ObjectPath) ([]dbus.ObjectPath, dbus.ObjectPath, *dbus.Error) {
  150. return objects, "/", nil // No prompt
  151. }
  152. /*
  153. retrives secrets from an array of items/collections
  154. :param items: a slice of dbus.ObjectPath that will have their secrets returned
  155. */
  156. func (s *SecretService) GetSecrets(items []dbus.ObjectPath, session dbus.ObjectPath) (map[dbus.ObjectPath]SecretStruct, *dbus.Error) {
  157. return map[dbus.ObjectPath]SecretStruct{}, nil
  158. }
  159. /*
  160. returns the collection with the given alias 'name'
  161. :param name: the name of the alias to return
  162. */
  163. func (s *SecretService) ReadAlias(name string) (dbus.ObjectPath, *dbus.Error) {
  164. return dbus.ObjectPath("/dev/aetherial/KeychainLinker/login"), nil
  165. }
  166. /*
  167. sets the collections alias name to the specified value in 'name'
  168. :param name: the alias name to assign
  169. :param collection: the dbus.ObjectPath to assign the alias name to
  170. */
  171. func (s *SecretService) SetAlias(name string, collection dbus.ObjectPath) *dbus.Error {
  172. // will implement later
  173. return nil
  174. }