99designs/keyring

dashes in secret service backend break roundtrip

nickatsegment opened this issue · 7 comments

Hi, looks like if you've got a dash in ServiceName in the secret service backend, it will fail to find it next time.

Here's a test:

ad34891

ubuntu@primary:~/Home/dev/src/github.com/99designs/keyring$ go test -count 1 -run TestRoundtripPublicOnly -v ./...
=== RUN   TestRoundtripPublicOnly
    libsecret_test.go:172: The specified item could not be found in the keyring
2021/03/30 17:56:17 collection: /org/freedesktop/secrets/collection/session
2021/03/30 17:56:17 collection with _2d: /org/freedesktop/secrets/collection/keyring_2dtest
    libsecret_test.go:185: The specified item could not be found in the keyring
--- FAIL: TestRoundtripPublicOnly (2.67s)
FAIL
FAIL    github.com/99designs/keyring    2.678s
?       github.com/99designs/keyring/cmd/keyring        [no test files]
FAIL

^ running gnome-keyring-daemon in the background.

I noticed through dbus-monitor that the actual collection name is keyring_2dtest, with some sort of escaping applied to the - character. I'm not deep into DBus/Secret Service, but it looks like sort of like URI escaping, like url.PathEscape.

Needs some more investigation, but yeah, 100% busted.

Simplified my branch a bit: you merely need to re-open to see the problem.

ubuntu@primary:~/Home/dev/src/github.com/99designs/keyring$ go test -count 1 -run TestLibSecretGetWhenNotEmpty -v ./...
=== RUN   TestLibSecretGetWhenNotEmpty
    libsecret_test.go:114: The specified item could not be found in the keyring
    libsecret_test.go:39: The collection does not exist. Please add a key first
--- FAIL: TestLibSecretGetWhenNotEmpty (2.23s)
FAIL
FAIL    github.com/99designs/keyring    2.240s
?       github.com/99designs/keyring/cmd/keyring        [no test files]
FAIL

https://github.com/gsterjov/go-libsecret/blob/master/service.go not seeing any normalization going on here.

https://freedesktop.org/wiki/Specifications/secret-storage-spec/secrets-api-0.1.html#object-paths says:

The object path for a collection, where xxxx represents a possibly encoded or truncated version of the initial label of the collection.

(Elsewhere they use "encoded" to mean "encrypted", but I don't see how that makes sense in this context.)

1d6ce07 shows that the collection path we get back is different than the one we supplied:

ubuntu@primary:~/Home/dev/src/github.com/99designs/keyring$ go test -count 1 -run TestLibSecretGetWhenNotEmpty -v ./...
=== RUN   TestLibSecretGetWhenNotEmpty
    libsecret_test.go:105: tried to create collection at path /org/freedesktop/secrets/collection/keyring-test, but got /org/freedesktop/secrets/collection/keyring_2dtest
    libsecret_test.go:39: The collection does not exist. Please add a key first
--- FAIL: TestLibSecretGetWhenNotEmpty (2.75s)
FAIL
FAIL    github.com/99designs/keyring    2.757s
?       github.com/99designs/keyring/cmd/keyring        [no test files]
FAIL

I see in my dbus-monitor session that we are passing the unencoded name, so it must be some mechanism in the server :(

method call time=1617150870.102990 sender=:1.77 -> destination=org.freedesktop.secrets serial=55 path=/org/freedesktop/secrets; interface=org.freedesktop.Secret.Service; member=CreateCollection
   array [
      dict entry(
         string "org.freedesktop.Secret.Collection.Label"
         variant             string "keyring-test"
      )
   ]
   string ""

that's because in linux
special character in service name is encoded
_+ hex
so cannot find it

i'll submit pr

submitted pr