Очень длиннопост получился.
Я долго думал – собирать ли всё в одном посте, или всё-таки разбить на несколько, ведь с одной стороны keyrings – это одна тема, D-Bus – другая, а примеры работы с SecretServices – вообще третья.
Тем не менее – решил всё-таки оставить в одном, так как со всем этим разбирался по ходу дела, и все эти темы связаны друг с другом в обсуждаемом контесте хранения конфиденциальных данных.
Вообще история появления этого поста интересна сама по себе:
- началось всё с
qtkeychain
и Nextcloud (см. Linux: Nextcloud клиент, qtkeychain и ошибка «The name org.freedesktop.secrets was not provided by any .service files») - по ходу дела увидел, что пароли от RSA ключей для SSA можно хранить в keychain (см. SSH: RSA-ключи и ssh-agent — управление SSH-ключами и их паролями и Linux: KeePass, SSH и хранение паролей RSA-ключей)
Но когда попробовал использовать gnome-keyring
на Arch Linux – стокнулся с проблемами при регистрации самого сервиса и доступа к нему через ssh-agent
, что заставило углубиться в вопрос.
Собственно, в этом посте рассмотрим:
- что такое keyring вообще
- какая разница между Linux keyring и GNOME keyring, и связаны ли они друг с другом
- какие реализации keyring существуют
- что такое
org.freedesktop
SecretService, и какое он имеет отношение к GNOME keyring - что такое D-Bus, и куда его можно потыкать веточкой, что бы увидеть работу keyring
- и несколько примеров работы с Linux Keyring, GNOME Keyring, KWallet и KeePass в роли keyring backends
Пост ни разу не является предметным “HowTo” – он чисто обзорный, что бы получить представление об всех упомянутых компонентах.
Конкретную работу с KeePass и, возможно, GNOME Keyring для хранения данных рассмотрим в другой раз.
Весь пост писался путём долгого-долгого гугления, поэтому и в самом тексте, и в конце, будет достаточно много ссылок на документацию и материалы, которые использовались в процессе подготовки материала.
Ну и помните, что от ошибок и неточностей никто не застрахован. Welcome to the comments, if any.
Выглядел процесс примерно так:
Содержание
Что такое keyring
Для начала – что такое “keyring” вообще?
Начнём с Wikipedia – https://en.wikipedia.org/wiki/Keyring_(cryptography):
In cryptography, a keyring stores known encryption keys (and, in some cases, passwords).
Продолжим документацией самого GNOME – https://help.gnome.org/users/seahorse/stable/keyring.html.en:
Much like a keyring in real life allows you to keep certain sets of keys together, a keyring in Passwords and Keys allows you to keep passwords and keys in separate groups.
И даже заглянем в документацию MySQL – https://dev.mysql.com/doc/refman/5.7/en/keyring-service.html:
a keyring service that enables internal server components and plugins to securely store sensitive information for later retrieval
А закончим man-страницей keyrings(7) – http://man7.org/linux/man-pages/man7/keyrings.7.html:
The Linux key-management facility is primarily a way for various kernel components to retain or cache security data, authentication keys, encryption keys, and other data in the kernel.
Итак, понятие keyring – это механизм или конкретный сервис, предназначенный для хранения какой-либо конфиденциальной информации.
Окей, тут разобрались.
Linux keyring vs gnome-keyring
По теме:
- KERNEL KEY RETENTION SERVICE
- http://www.ict.griffith.edu.au/anthony/info/crypto/passwd_caching.txt
- http://www.ict.griffith.edu.au/anthony/info/crypto/
- https://wiki.gnome.org/Projects/GnomeKeyring
- https://wiki.archlinux.org/index.php/GNOME/Keyring
Теперь перейдём к рассмотрению разницы между Linux kernel keyring и GNOME Keyring: сначала сбило с толку, ибо предполагал, что GNOME Keyring каким-то образом использует механизм keyrings ядра, но нет – это просто разные вещи.
Вернёмся к man 7 Linux keyrings:
keyrings – in-kernel key management and retention facility
Т.е, Linux keyrings – это механизм ядра для хранения конфиденциальной информации.
И читаем документацию gnome-keyring
:
GNOME Keyring is a collection of components in GNOME that store secrets, passwords, keys, certificates and make them available to applications.
А GNOME Keyring – коллекция компонентов (gnome-keyring-daemon
, библиотеки, пакет seahorse
, etc) для хранения конфиденциальной информации. См. архитектуру GNOME Keyring.
Отличная подборка материалов тут – Tower Floor — Encryption, в частности см. документ Caching Passwords.
Резюме
Подведём итоги различий Linux keyrings и GNOME Keyring:
- ключевая разница:
- Linux keyring – механизм ядра для “кеширования паролей” – хранит их в памяти во время активной сессии системы/пользователя
gnome-keyring
– постоянное хранилище паролей, с хранением информации на диске
- хранение:
- Linux keyring – хранит в памяти, т.к. секреты доступны только во время сесии – их не надо хранить постоянно
gnome-keyring
– создаёт файл на диске, как правило в каталоге~/.local/share/keyrings/
- доступ:
- Linux keyring – через системные вызовы из user space в kernel space
gnome-keyring
– через DBus
- приложения для доступа:
- Linux keyring –
keyctl
,systemd-ask-password
, etc gnome-keyring
–secret-tool
, любая библиотека (python-keyring
),seahorse
, etc
- Linux keyring –
Реализации keyrings
Кроме того, python-keyring
упоминает:
- gsheet-keyring – a backend that stores secrets in a Google Sheet. For use with ipython-secrets.
- bitwarden-keyring – a backend that stores secrets in the BitWarden password manager.
И это далеко не все.
Клиенты для работы с такими хранилищами, опять-таки – список далеко не полный:
libsecret
python-keyring
- Java-клиент secret-service
qtkeychain
secret-tool
- библиотека
SecretStorage
Перехват паролей из gnome-keyting
По ходу гугления нашёл обсуждение интересного бага: https://bugs.launchpad.net/ubuntu/+source/gnome-keyring/+bug/1780365
Суть кратко:
- клиент и сервис общаются по D-Bus
- клиент запрашивает данные у SecretService (
gnome-keyring
в данном случае) - сервис через D-Bus шлёт данные клиенту
- другой процесс слушает dbus-сообщения, читает пароль
Что такое Secret Service
Ещё одно понятие, на которое пришлось немного потратить время.
Что за “Secret Service”? Какое он имеет отношение к GNOME Keyring и к KWallet?
Что он делает в Linux, и как его пощупать?
Обратимся к документации – https://specifications.freedesktop.org/secret-service/latest/ch01.html:
The Secret Service API allows client applications to store secrets securely in a service running in the user’s login session.
Ага, т.е. Secret Service – это не какой-то конкретный сервис, а просто спецификация, такой себе RFC, составленный проектами GNOME и KDE для определения того, как они должны реализовать API для клиентов, которые хотят использовать GNOME Keyring и к KWallet для хранения секретов.
При этом поддержка Secret Service API имеется не только у GNOME Keyring и к KWallet, но и у, например, KeePass, и других приложений.
IMHO, немного сбивает с толку само название – Secret Service, т.е. “секретный сервис”. Назвали бы его Secrets Service, т.е. “сервис секретов” – было бы куда понятнее.
Понятия Secret Service
- secret: сам пароль, или любая другая конфиденциальная информация
- item: каждый секрет плюс набор его атрибутов представляют собой item
- collection: а набор таких items преставляет собой коллекцию (аналог понятий keyring и wallet)
- коллекции и items представлены объектами D-Bus, каждый со своим уникальным path
- default collection: клиентские приложения без специальных условий должны добавлять записи в коллекцию default, которая должна быть доступна по пути
/org/freedesktop/secrets/aliases/default
D-Bus
Теперь пришло время попытаться вспомнить что же такое D-Bus, и как к нему вообще обращаться.
Итак, D-Bus – один из механизмов Linux kernel IPC – Inter Process Communication, позволяющий различным процессам внутри системы передавать другу другу данные или сигналы.
Ссылки по теме:
- документация – https://techbase.kde.org/Development/Tutorials/D-Bus/Introduction
- ещё одна: https://dbus.freedesktop.org/doc/dbus-tutorial.html
- про транспорты в D-Bus: https://dbus.freedesktop.org/doc/dbus-specification.html#transports
- D-Bus, quick recap
- Universal standard mapping between D-Bus and URI namespaces
- D-Bus Addresses — D-Bus connection endpoints
Кратко об основных понятиях и терминах D-Bus:
- D-Bus в общем: это шина для IPC, если в предыдущих примерах по SSH-агентам использовался UNIX-сокет, тот тут используется механизм bus, см. https://www.kernel.org/doc/html/latest/driver-api/driver-model/bus.html. В свою очередь D-Bus шины могут быть:
- шина сессии (session bus)
- системная шина (system bus)
- приватные шины (private bus)
- messages: базовый юнит коммуникации, передача аналогична пакетам TCP/IP, только в D-Bus сообщении все данные включаются целиком, а не разбиваются по различным пакетам
- отправка сообщения как правило приводит к вызову метода и каким-либо действиям приложения, которое этот метод предоставялет
- сообщение может быть отправлено приложением самому себе
- namespaces и addresses:
- т.к. различные приложения могут располагаться на одной шине (или “слушать одну шину“), и при этом одно приложение может предоставлять несколько объектов, которые могут получать сообщения, то требуется механизм адресации, такой адрес в D-Bus состоит из интерфейса + сервис + имя объекта
- пример namespace – org.freedesktop.dbus
- пример адреса – unix:tmpdir=/tmp/my-app-name
- interface: набор методов и сигналов на конкретной шине для конкретного object. Интерфейсы можно себе представлять себе как именованная группа методов и сигналов.
- большинство интерфейсов будут указывать непосредственно на соответствующие конструкции языка, на котором написано приложение, например на интерфейс Java или виртуальный класс С++
- пример интерфейса – org.freedesktop.Introspectable
- service: представляет собой конкретное подключение определённого приложения к шине
- под service тут подразумевается имя шины (в оригинале – “well-known” Bus names), но стоит учитывать что под “именем шины” подразумевается именно имя подключения к шине, но НЕ имя шины
- если у приложения более одного подключения к шине, или если приложение запущено в нескольких экземплярах – у имени сервиса может бтыь добавлен, например, PID, что бы сделать его уникальным
- пример service – org.kde.screensaver
- objects: одно приложение может предоставлять доступ к нескольким своим объектам, используя для логического разделения пути. Каждый такой path ассоцированный с сервисом представялет собой отдельный объект, например
/MainInterface
или/Documents/Doc1
. Объекты предоставляют доступ к интерфейсам, и один объект может предоставлять доступ к нескольким интерфейсам одновремнено - methods: у каждого объекта есть members, два типа таких членов – методы (methods) и сигналы (signals)
- методы – это messages, которые отправляются объекту, что бы вызвать операцию в приложении, которое этот объект создало
- методы могут передавать данные в input, например аргументы, и возвращать output с какими-либо значениями, которое вернёт приложение
- всегда имеют адрес отправителя и конкретный адрес получателя
- signals:
- аналогичны методам, но не привязаны к конкретному destination, и могут быть приняты любым приложением на этой же шине
- генерируются приложением, которое екпортит интерфейс
D-Bus tools
Консольные:
qdbus
– просмотр объектов и отправка сообщений через D-Busdbus-monitor
– отслеживание активности на шинеdbus-send
– отправка сообщений через D-Bus
С GUI:
qdbusviewer
– просмотр объектов и сообщений, входит в наборqt5-tools
d-feet
– D-Bus debuggerbustle
– D-Bus message analyser and profiler
Пример d-feet
, устанавливаем:
[simterm]
$ sudo pacman -S d-feet
[/simterm]
Запускаем, смотрим:
Keyrings examples
И примеры работы с разными бекендами из Python или CLI утилит.
Linux keyring
Как уже говорилось выше, Linux keyring – такой себе кеширующий механизм ядра.
Для работы с ним используются keyctl
из набора keyutils
, и systemd-ask-password
.
Почитать:
Из документации:
Each process subscribes to three keyrings: a thread-specific keyring, a process-specific keyring, and a session-specific keyring.
Посмотрим, какие keyring доступны в моей текущей сессии:
[simterm]
$ keyctl show @s Session Keyring 185597501 --alswrv 1000 1000 keyring: _ses 182944921 --alswrv 1000 65534 \_ keyring: _uid.1000
[/simterm]
Или пользователю:
[simterm]
$ keyctl show @u Keyring 182944921 --alswrv 1000 65534 keyring: _uid.1000
[/simterm]
Кроме того, в файле /proc/key-users
можно получить информацию обо всех хранилищах и их статистике по каждому пользователю:
[simterm]
$ cat /proc/key-users 0: 43 42/42 34/1000000 768/25000000 971: 1 1/1 1/200 9/20000 1000: 4 4/4 4/200 46/20000
[/simterm]
Доступные нашему процессу (bash
, который вызывает cat
) ключи:
[simterm]
$ cat /proc/keys 008f6a74 I--Q--- 1 perm 1f3f0000 1000 65534 keyring _uid_ses.1000: 1 0ae78499 I--Q--- 4 perm 1f3f0000 1000 65534 keyring _uid.1000: empty 0b0ffe3d I--Q--- 225 perm 3f030000 1000 1000 keyring _ses: 1 2a28e4fe I--Q--- 33 perm 3f030000 1000 1000 keyring _ses: 1
[/simterm]
Кейринги пользователя в текущей сессии:
[simterm]
$ keyctl describe @us -5: -lswrvalswrv------------ 1000 65534 keyring: _uid_ses.1000
[/simterm]
Ключи в текущем кейринге:
[simterm]
$ keyctl list @us 1 key in keyring: 182944921: --alswrv 1000 65534 keyring: _uid.1000
[/simterm]
Добавляем ключ:
[simterm]
$ keyctl add user example-key example-data @u 546850615
[/simterm]
Поиск ключа:
[simterm]
$ keyctl request user example-key 546850615
[/simterm]
Получаем его ID, читаем содержимое:
[simterm]
$ keyctl print 546850615 example-data
[/simterm]
keyctl()
syscall
Собственно, работа keyctl
утилиты заключается в выполнении системногно вызова keyctl(2)
:
[simterm]
$ strace -e keyctl keyctl print 546850615 keyctl(KEYCTL_READ, 546850615, NULL, 0) = 12 keyctl(KEYCTL_READ, 546850615, "example-data", 12) = 12 example-data +++ exited with 0 +++
[/simterm]
В первом вызове – keyctl(KEYCTL_READ, 546850615, NULL, 0) = 12
– выполняем сам вызов keyctl()
, которому передаём operation KEYCTL_READ
и ID ключа.
Окей, тут более-менее просто и понятно.
Использовались материалы:
- https://www.kernel.org/doc/Documentation/security/keys.txt
- https://www.ibm.com/developerworks/library/l-key-retention/
- http://man7.org/linux/man-pages/man7/keyrings.7.html
- http://man7.org/linux/man-pages/man1/keyctl.1.html
- http://man7.org/linux/man-pages/man2/keyctl.2.html
Перейдём к keyring storages.
gnome-keyring
Очень проблемный пакет, при этом наиболее широкоиспользуемый.
Устанавливаем, если не установлен:
[simterm]
$ sudo pacman -S gnome-keyring
[/simterm]
Проверяем D-Bus сервисы – ищем org.freedesktop.secrets
:
[simterm]
$ dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames ... string "org.freedesktop.secrets" ...
[/simterm]
“Ага, вот эти ребята” (с)
Можем получить описание сервиса с помощью org.freedesktop.DBus.Introspectable.Introspect
:
[simterm]
$ dbus-send --session --print-reply --dest=org.freedesktop.DBus /org/freedesktop/secrets org.freedesktop.DBus.Introspectable.Introspect ... <node> <interface name="org.freedesktop.DBus"> <method name="Hello"> <arg direction="out" type="s"/> </method> <method name="RequestName"> <arg direction="in" type="s"/> <arg direction="in" type="u"/> <arg direction="out" type="u"/> </method> <method name="ReleaseName"> <arg direction="in" type="s"/> <arg direction="out" type="u"/> </method> ...
[/simterm]
Или с помощью qdbus
– находим сам сервис:
[simterm]
$ qdbus | grep 'secrets\|keyring' org.freedesktop.secrets org.gnome.keyring
[/simterm]
Читаем хелп qdbus
:
[simterm]
$ qdbus --help ... With 0 arguments, qdbus will list the services available on the bus With just the servicename, qdbus will list the object paths available on the service With service name and object path, qdbus will list the methods, signals and properties available on the object
[/simterm]
Получаем описание сервиса:
[simterm]
$ qdbus org.freedesktop.secrets /org/freedesktop/secrets signal void org.freedesktop.DBus.Properties.PropertiesChanged(QString interface_name, QVariantMap changed_properties, QStringList invalidated_properties) method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name) method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name) method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value) method QString org.freedesktop.DBus.Introspectable.Introspect() method QString org.freedesktop.DBus.Peer.GetMachineId() method void org.freedesktop.DBus.Peer.Ping() ...
[/simterm]
D-Bus GetConnectionUnixProcessID
Собственно, мы хотим увидеть – кто “слушает” на том конце шины. Используем метод GetConnectionUnixProcessID
:
[simterm]
$ qdbus --session org.freedesktop.DBus / org.freedesktop.DBus.GetConnectionUnixProcessID org.freedesktop.secrets 1278791
[/simterm]
Тут мы:
- выполняем вызов к сервису org.freedesktop.DBus
- передаём путь /
- вызываем метод
org.freedesktop.DBus.GetConnectionUnixProcessID
- которому передаём аргументом имя сервиса, PID которого хотим узнать – org.freedesktop.secrets
И проверяем – кто такой 1278791:
[simterm]
$ ps xu | grep 1278791 setevoy 1278791 0.0 0.0 383876 8092 ? SLl Dec03 0:00 /usr/bin/gnome-keyring-daemon --start --foreground --components=secrets
[/simterm]
Хорошо.
Мы убедились, что роль Secret Service сейчас выполняет gnome-keyring
. Давайте что-то подобавляем-поудаляем.
Используем python-keyring
и secret-tool
.
python-keyring
Попробуем python-keyring
.
Устанавливаем:
[simterm]
$ sudo pacman -S python-keyring
[/simterm]
Проверяем:
[simterm]
>>> import keyring >>> keyring.set_password("system", "username", "password") >>> keyring.get_password("system", "username") 'password'
[/simterm]
В случае ошибок вида (может случится при первом запуске после установки gnome-keyring
):
[simterm]
>>> keyring.set_password("system", "username", "password") Traceback (most recent call last): ... jeepney.wrappers.DBusErrorResponse: [org.freedesktop.DBus.Error.UnknownMethod] ('No such interface “org.freedesktop.DBus.Properties” on object at path /org/freedesktop/secrets/collection/login',)
[/simterm]
Или:
[simterm]
Traceback (most recent call last): ... raise PromptDismissedException('Prompt dismissed.') secretstorage.exceptions.PromptDismissedException: Prompt dismissed.
[/simterm]
Выполняем скрипт /etc/X11/xinit/xinitrc.d/50-systemd-user.sh
:
[simterm]
$ . /etc/X11/xinit/xinitrc.d/50-systemd-user.sh
[/simterm]
И создаём хранилище и пароль для него:
Смотрим в dbus-monitor
, что происходит в D-Bus:
[simterm]
... method call time=1575542111.465749 sender=:1.576 -> destination=org.freedesktop.secrets serial=7 path=/org/freedesktop/secrets/aliases/default; interface=org.freedesktop.Secret.Collection; member=CreateItem array [ dict entry( string "org.freedesktop.Secret.Item.Attributes" variant array [ dict entry( string "application" string "Python keyring library" ) dict entry( string "service" string "system" ) dict entry( string "username" string "username" ) ] ) dict entry( string "org.freedesktop.Secret.Item.Label" variant string "Password for 'username' on 'system'" ) ] ... struct { object path "/org/freedesktop/secrets/session/s14" } ... signal time=1575542111.476006 sender=:1.220 -> destination=(null destination) serial=689 path=/org/freedesktop/secrets/collection/example_2dkeyring; interface=org.freedesktop.Secret.Collection; member=ItemCreated object path "/org/freedesktop/secrets/collection/example_2dkeyring/5" ...
[/simterm]
Тут:
- sender=:1.576 – находим 1.576 в списке сервисов D-Bus – это наш Python:
- destination=org.freedesktop.secrets
наш/usr/bin/gnome-keyring-daemon
, видели выше в выводеorg.freedesktop.DBus.GetConnectionUnixProcessID
Проверяем в gnome-keyring
с помощью, например, seahorse
:
Окей, работает.
secret-tools
Ещё один вариант – использовать secret-tools
.
Добавим пароль:
[simterm]
$ secret-tool store --label=SecretToolExample username username service secret Password:
[/simterm]
Получаем его:
[simterm]
$ secret-tool lookup username username service secret password
[/simterm]
Проверяем его в Seahorse:
KWallet
Устанавливаем:
[simterm]
$ sudo pacman -S kwallet
[/simterm]
Проверяем D-Bus:
[simterm]
$ qdbus --session org.freedesktop.DBus / org.freedesktop.DBus.GetConnectionUnixProcessID org.freedesktop.secrets 1278791 $ ps aux | grep 1278791 setevoy 1278791 0.0 0.0 384008 8048 ? SLl Dec03 0:00 /usr/bin/gnome-keyring-daemon --start --foreground --components=secrets
[/simterm]
А почему не kwallet
, почему до сих пор gnome-keyring
?
Окей, убиваем его:
[simterm]
$ kill 1278791
[/simterm]
И сервис файл старый:
[simterm]
$ cat /usr/share/dbus-1/services/org.freedesktop.secrets.service [D-BUS Service] Name=org.freedesktop.secrets Exec=/usr/bin/gnome-keyring-daemon --start --foreground --components=secrets
[/simterm]
Ладно – удалим gnome-keyring
польностью:
[simterm]
$ sudo pacman -Rsn seahorse $ sudo pacman -Rsn gnome-keyring
[/simterm]
Сервис-файла теперь нет:
[simterm]
$ cat /usr/share/dbus-1/services/org.freedesktop.secrets.service 2019/12/05 13:15:03 open /usr/share/dbus-1/services/org.freedesktop.secrets.service: no such file or directory
[/simterm]
Переустанавливаем kwallet
:
[simterm]
$ sudo pacman -S kwallet warning: kwallet-5.64.0-1 is up to date -- reinstalling ...
[/simterm]
Сервис-файл не создался:
[simterm]
$ qdbus --session org.freedesktop.DBus / org.freedesktop.DBus.GetConnectionUnixProcessID org.freedesktop.secrets Error: org.freedesktop.DBus.Error.NameHasNoOwner Could not get PID of name 'org.freedesktop.secrets': no such name
[/simterm]
Странно…
А D-Bus и Secret Service вообще подерживается в KWallet?
Reddit говорит, что нет:
In brief, there is no longer a secret service implementation for KDE that I am aware of
И в документации ksecretsservice
почти всё в ToDo…
Печаль. Лично мне нравятся Qt-based KDE приложения. Да и ещё более странен сам факт того, что Secret Service спецификация разрабатывалась GNOME и KDE проектами вместе, а реализована, получается, только в GNOME Keyring…
Still, мы можем использовать KWallet без Secret Service интеграции.
Запускаем менеджер кошельков:
[simterm]
$ kwalletmanager5
[/simterm]
Создаём тестовый кошелёк:
Задаём пароль кошелька:
Но тут, понятноое дело, что ломается интеграция с Secret Service, например – наша Python-библиотека теперь говорит :
[simterm]
>>> keyring.set_password("system", "username", "password") Traceback (most recent call last): ... raise value jeepney.wrappers.DBusErrorResponse: [org.freedesktop.DBus.Error.ServiceUnknown] ('The name org.freedesktop.secrets was not provided by any .service files',) The above exception was the direct cause of the following exception: Traceback (most recent call last): ... raise SecretServiceNotAvailableException(data) from resp secretstorage.exceptions.SecretServiceNotAvailableException: The name org.freedesktop.secrets was not provided by any .service files During handling of the above exception, another exception occurred: Traceback (most recent call last): ... raise RuntimeError("Unable to initialize SecretService: %s" % e) RuntimeError: Unable to initialize SecretService: The name org.freedesktop.secrets was not provided by any .service files
[/simterm]
Но можно заменить keyring
бекенд с SecretService и DBus на прямое указание kwallet5
, нагуглилось тут>>>:
[simterm]
>>> kwallet5 = keyring.backends.kwallet.DBusKeyring() >>> keyring.set_keyring(kwallet5) >>> keyring.get_keyring() <keyring.backends.kwallet.DBusKeyring object at 0x7f7efba66fa0>
[/simterm]
Добавляем пароль:
[simterm]
>>> keyring.set_password("system", "username", "password")
[/simterm]
Проверяем D-Bus сообщения:
[simterm]
method call time=1575545736.524015 sender=:1.318 -> destination=:1.269 serial=38 path=/modules/kwalletd5; interface=org.kde.KWallet; member=writePassword int32 365838442 string "system" string "username" string "password" string "Python keyring library"
[/simterm]
И сам KWallet:
KeePass
Сам KeePass тоже может играть роль keyring backend используя Secret Storage спецификацию.
Если gnome-keyring
не удалён – то будет ошибка вида “Another secret service is running“:
Удалям gnome-keyring
, активируем Secret Service:
[simterm]
method call time=1575546064.021083 sender=:1.599 -> destination=org.freedesktop.DBus serial=26 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=RequestName string "org.freedesktop.secrets" uint32 4 signal time=1575546064.021157 sender=org.freedesktop.DBus -> destination=(null destination) serial=258 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChanged string "org.freedesktop.secrets" string "" string ":1.599" signal time=1575546064.021212 sender=org.freedesktop.DBus -> destination=:1.599 serial=16 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired string "org.freedesktop.secrets" method return time=1575546064.021245 sender=org.freedesktop.DBus -> destination=:1.599 serial=17 reply_serial=26 uint32 1
[/simterm]
Проверяем кто слушает на org.freedesktop.secrets:
[simterm]
$ qdbus --session org.freedesktop.DBus / org.freedesktop.DBus.GetConnectionUnixProcessID org.freedesktop.secrets 4006761 $ ps aux | grep 4006761 setevoy 4006761 2.0 0.5 475888 89656 tty1 SLl 13:40 0:02 keepassxc
[/simterm]
Окей.
И запишем что-то в базу:
[simterm]
$ secret-tool store --label=SecretToolExample username username service secret Password: libsecret-Message: 13:45:13.448: Remote error from secret service: org.freedesktop.DBus.Error.UnknownObject: No such object path '/org/freedesktop/secrets/aliases/default' secret-tool: No such object path '/org/freedesktop/secrets/aliases/default'
[/simterm]
Эм…
Ага, надо в настройках базы настроить внутренний путь, см. комментарий тут>>>.
В самой базе добавим новую группу:
Далее идём в Database > Database settings, и указываем локальный путь к папке, которая будет использоваться в роли Secret Service storage:
Перезапускаем KeePass, в D-Bus видно, как добавляется коллекция:
[simterm]
signal time=1575546948.831195 sender=:1.613 -> destination=(null destination) serial=22 path=/org/freedesktop/secrets; interface=org.freedesktop.Secret.Service; member=CollectionCreated object path "/org/freedesktop/secrets/collection/Main" signal time=1575546982.884850 sender=:1.613 -> destination=(null destination) serial=23 path=/org/freedesktop/secrets; interface=org.freedesktop.Secret.Service; member=CollectionChanged object path "/org/freedesktop/secrets/collection/Main"
[/simterm]
Добавляем пароль:
[simterm]
$ secret-tool store --label=SecretToolExample username username service secret Password:
[/simterm]
Проверяем D-Bus:
[simterm]
... method call time=1575547056.148892 sender=:1.616 -> destination=org.freedesktop.secrets serial=10 path=/org/freedesktop/secrets/aliases/default; interface=org.freedesktop.Secret.Collection; member=CreateItem array [ dict entry( string "org.freedesktop.Secret.Item.Attributes" variant array [ dict entry( string "service" string "secret" ) dict entry( string "username" string "username" ) ] ) dict entry( string "org.freedesktop.Secret.Item.Label" variant string "SecretToolExample" ) ] ...
[/simterm]
И в самом KeePass:
На этом всё.
Ссылки по теме
keyrings, Secret Service, etc
- GNOME Keyring – GNOME project docs
- GNOME/Keyring – Arch Linux Wiki
- KDE Wallet
- Python Keyring Lib
- Manage Passwords, Encryption Keys, And More With Seahorse
- secret-tool examples
- Keychain
- Using Linux keyring secrets from your scripts
- Secret Service API Draft
- Python bindings to FreeDesktop.org Secret Service API
- Python keyring lib
- Libsecret Library Reference Manual
- Credentials located in gnome-keyring can be compromised easily
- “Please enter password for encrypted keyring” when running Python script on Ubuntu
- Use keyring to store your credentials
- In KDE Plasma, keyring uses gnome-keyring by default – просто поулыбаться
- Get started with the Linux key retention service
D-Bus
- D-Bus Tutorial
- D-Bus/Introduction
- D-Bus Specification
- D-Bus API Design Guidelines
- Introspecting D-Bus from the command-line
- Understanding D-Bus
- dbus-python tutorial
- Universal standard mapping between D-Bus and URI namespaces
- D-Bus, quick recap