listener.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. Items []dbus.ObjectPath // items in the collection
  86. Private string // specifies whether the collection is private or not
  87. Label string // The displayable label of this collection.
  88. Locked string // Whether the collection is locked and must be authenticated by the client application.
  89. Created uint64 // The unix time when the collection was created.
  90. Modified uint64 // The unix time when the collection was last modified.
  91. }
  92. // deletes the collection
  93. func (c *Collection) Delete() (dbus.ObjectPath, *dbus.Error) {
  94. return dbus.ObjectPath("prompt"), nil
  95. }
  96. /*
  97. Searches the collection for matching items
  98. :param attr: the attributes to attempt to match to a key in the collection
  99. */
  100. func (c *Collection) SearchItems(attr map[string]string) ([]dbus.ObjectPath, *dbus.Error) {
  101. // implement a recursive searching thing
  102. return []dbus.ObjectPath{}, nil
  103. }
  104. /*
  105. Creates a new item in the collection with the properties defined in 'props'.
  106. Returns the items dbus object path, as well as a path to a dbus prompt
  107. :param fields: a map of properties to assign to the item. Will be used to match during lookups
  108. :param secret: the secret to encode into the collection
  109. :param replace: replace secret if a matching one is found in the store
  110. */
  111. func (c *Collection) CreateItem(fields map[string]string, secret SecretStruct, replace bool) (dbus.ObjectPath, dbus.ObjectPath) {
  112. return dbus.ObjectPath("/"), dbus.ObjectPath("/")
  113. }
  114. /*
  115. Opens a session for the Secret Service Interface
  116. :param algorithm: the encryption algorithm to use with the client
  117. :param input: the data used when implementing more advanced encryption algos
  118. */
  119. func (s *SecretService) OpenSession(algorithm string, input dbus.Variant) (dbus.Variant, dbus.ObjectPath, *dbus.Error) {
  120. if algorithm != "PLAIN" {
  121. return dbus.Variant{}, "/", dbus.MakeFailedError(fmt.Errorf("only PLAIN is supported"))
  122. }
  123. sessionPath := dbus.ObjectPath(path.Join(s.SessionBase, "1"))
  124. return input, sessionPath, nil
  125. }
  126. /*
  127. Creates a collection with the Service object
  128. :param properties: a set of properties that are used by client apps
  129. :param alias: the shortname of the collection
  130. */
  131. func (s *SecretService) CreateCollection(properties map[string]dbus.Variant, alias string) (dbus.ObjectPath, dbus.ObjectPath, *dbus.Error) {
  132. collPath := dbus.ObjectPath(path.Join(s.CollectionBase, "login"))
  133. s.Collections = append(s.Collections, collPath)
  134. return collPath, "/", nil
  135. }
  136. /*
  137. search for items in the keychain that satisfy 'attrs'
  138. :param attrs: a map of search criteria
  139. */
  140. func (s *SecretService) SearchItems(attrs map[string]string) ([]dbus.ObjectPath, []dbus.ObjectPath, *dbus.Error) {
  141. // Just return empty results for now
  142. return []dbus.ObjectPath{}, []dbus.ObjectPath{}, nil
  143. }
  144. /*
  145. sets all dbus.Objects in 'objects' to the 'unlocked' position
  146. :param objects: a slice of dbus.Objects to unlock
  147. */
  148. func (s *SecretService) Unlock(objects []dbus.ObjectPath) ([]dbus.ObjectPath, dbus.ObjectPath, *dbus.Error) {
  149. return objects, "/", nil // No prompt
  150. }
  151. /*
  152. Sets all dbus.Objects in 'objects' to the 'locked' position
  153. :param objects: a slice of dbus.Objects to unlock
  154. */
  155. func (s *SecretService) Lock(objects []dbus.ObjectPath) ([]dbus.ObjectPath, dbus.ObjectPath, *dbus.Error) {
  156. return objects, "/", nil // No prompt
  157. }
  158. /*
  159. retrives secrets from an array of items/collections
  160. :param items: a slice of dbus.ObjectPath that will have their secrets returned
  161. */
  162. func (s *SecretService) GetSecrets(items []dbus.ObjectPath, session dbus.ObjectPath) (map[dbus.ObjectPath]SecretStruct, *dbus.Error) {
  163. return map[dbus.ObjectPath]SecretStruct{}, nil
  164. }
  165. /*
  166. returns the collection with the given alias 'name'
  167. :param name: the name of the alias to return
  168. */
  169. func (s *SecretService) ReadAlias(name string) (dbus.ObjectPath, *dbus.Error) {
  170. return dbus.ObjectPath("/dev/aetherial/KeychainLinker/login"), nil
  171. }
  172. /*
  173. sets the collections alias name to the specified value in 'name'
  174. :param name: the alias name to assign
  175. :param collection: the dbus.ObjectPath to assign the alias name to
  176. */
  177. func (s *SecretService) SetAlias(name string, collection dbus.ObjectPath) *dbus.Error {
  178. // will implement later
  179. return nil
  180. }