Пользовательские модули аутентификации
Authd — это сервис аутентификации с возможностью настройки различных факторов. Для аутентификации Authd может использовать один или несколько факторов (плагинов). Без выбранного фактора Authd отрабатывает корректно и аутентифицирует без каких либо запросов. Однако в целях безопасности на данный момент для всех прошивок по умолчанию в качестве фактора задан пароль.
Настройка списка факторов выполняется индивидуально для каждого пользователя администратором в системном приложении Настройки.
Authd сканирует каталог /usr/lib/authd/, чтобы найти установленные в систему факторы (плагины .so).
Authd содержит в себе:
- сервис;
- плагины (список может пополняться):
- Блокировка;
- Ограничение входа в систему;
- Пароль;
- Смарт-карта;
- Простое подтверждение (пакет authd-tests);
- консольное приложение auth-cli, которое позволяет проверять пароль из командной строки.
Примечание. Данные плагины нельзя подписать профилем стороннего разработчика. Для подписания плагинов необходимо использовать профили безопасности подписи разработчика от ОМП.
Каждый плагин реализует собственный фактор аутентификации.
Authd поддерживает API блокировок через D-Bus-интерфейс.
У каждого пользователя есть свой список факторов. Настройка списка факторов выполняется индивидуально для каждого пользователя администратором в системном приложении «Настройки».
Содержание:
- Процесс аутентификации
- Типы клиентов
- Типы плагинов
- Конфигурация AuthService
- Текущее состояние AuthService
- Разработка нового плагина
- Использование Authd
Процесс аутентификации
Клиент подключается к сервису AuthService с помощью локального unix-сокета
/var/run/authd/authd.socket и выполняет запрос RequestChallenge.
AuthService генерирует случайный идентификатор, привязывает его к имени подключения
и возвращает клиенту.
Используя этот идентификатор, клиент делает запрос Authenticate.
AuthService определяет пользователя, от имени которого выполнен запрос, и последовательно вызывает
метод authenticate для каждого выбранного у данного пользователя фактора.
Обработчик метода authenticate может запросить ввод пользовательских данных, тогда AuthService
транслирует запрос на отображение формы ввода зарегистрированному сервису AuthUiClient.
В настоящий момент для каждого процесса, в рамках которого выполняется аутентификация, необходимо зарегистрировать свой AuthUiClient. В рамках обработки запроса AuthUiClient отображает форму ввода, специфичную для текущего фактора.
После ввода пользователем данных AuthUiClient возвращает их с помощью SetResponse и они
передаются для проверки.
Если данные корректны, AuthService переходит к следующему фактору.
Если факторов больше нет, и все предыдущие проверки были успешны, генерируется
аутентификационный токен и отправляется клиенту.
Используя этот токен, клиент может делать привилегированные запросы.
Типы клиентов
В текущей реализации поддерживаются следующие типы клиентов:
unlock-uiРазблокировка шифрованного раздела с домашними директориями пользователей (/home) во время загрузки мобильного устройства. Для первого фактора, запросившего ввод пользователя, отображается соответсвующая страница UI. Пользователь вводит данные этого фактора. Эти данные перехватываются authd, используются для разблокировки /home и кешируются.lipstickРазблокировка экрана во время работы мобильного устройства.settingsПодтверждение привилегированного действия администратором в приложении Настройки.
В дальнейшем, в зависимости от типа клиента могут использоваться разные списки факторов.
Типы плагинов
Плагины Authd могут быть трёх типов:
- Явными — проверки аутентификации требуют взаимодействия с пользователем. Пример: ввод пароля.
- Неявными — проверки аутентификации выполняются без взаимодействия с пользователем. Пример: вход по дням недели.
- Не аутентифицирующими — данный тип плагина не реализует функции аутентификации. Используется для выполнения привилегированных действий после прохождения аутентификации. Например, для сброса устройства к заводским настройкам.
Конфигурация AuthService
При старте AuthService читает конфигурационный файл /etc/authd/authd.conf.
С помощью данного файла можно настроить списки обязательных, выбранных по умолчанию и неизменяемых
факторов для администратора и пользователей.
Конфигурационный файл имеет секции [worker] и [devlock].
Секция [worker]
В секции [worker] читаются следующие опции:
| Опция | Описание |
|---|---|
admin-mandatory-factors |
Список обязательных факторов для администратора (defaultuser) |
admin-immutable-factors |
Список факторов для администратора, которые не могут быть включены или отключены |
admin-default-factors |
Список факторов по умолчанию для администратора. Этот список применяется, если у администратора не выбран ни один из факторов |
user-mandatory-factors |
Список обязательных факторов для обычных пользователей |
user-immutable-factors |
Список неизменных факторов для обычных пользователей |
user-default-factors |
Список факторов по умолчанию для обычных пользователей |
В списках должны быть указаны внутренние имена факторов через запятую. По умолчанию все списки пусты. Внутренние имена перечислены в следующей таблице:
| Внутреннее имя | Описание | Тип |
|---|---|---|
lockout |
Блокировка устройства | Implicit |
loginrestriction |
Расписание входа пользователя | Implicit |
confirm |
Простое подтверждение да/нет (тестовый плагин) | Auth |
password |
Пароль в luks-слоте шифрованного раздела | Auth |
reset |
Сброс устройства к заводским настройкам | Non-auth |
smartcard |
Смарт-карта (opensc-совместимая USB или NFC) | Auth |
Неинтерактивные факторы выбираются автоматически, в Настройках они отсутствуют.
[devlock]
| Опция | Описание |
|---|---|
permissive-mode |
Включить аутентификацию пользователя, даже если какой-то фактор не сработал (удобно для отладки) |
Пример
Пример конфигурационного файла /etc/authd/authd.conf:
[worker]
admin-mandatory-factors = password
admin-immutable-factors = password, confirm
user-default-factors = password
[devlock]
permissive-mode = true
Текущее состояние AuthService
Списки выбранных факторов для пользователей хранятся в директории
/var/lib/authd/users/ в файлах с именем вида
Редактирование файлов конфигурации не поддерживается во время работы Authd, потому что любое подобное изменение будет потеряно.
Разработка нового плагина
В операционную систему могут быть добавлены новые плагины, что позволяет расширить выбор факторов аутентификации или выполняемых привилегированных действий без изменения кода AuthService. Для этого необходимо сформировать rpm-пакет, включающий:
- Плагин, обращающийся к AuthService и выполняющий проверку введённых данных
(разделяемая библиотека .so).
Плагин должен содержать:
- Файлы
.json и method-.cc . Файлы обязательны для всех типов плагинов. Библиотека .so должна содержать реализацию методов базового класса AuthPluginInterface, в том числе, метод authenticate. - Файл policy.conf, задающий число попыток пользователя для связи (этот файл специфичен для плагинов).
- Файлы
- QML-плагин для использования в QML-форме ввода данных для взаимодействия с AuthService
(разделяемая библиотека .so).
Плагин должен содержать:
- Файл страницы для аутентификации MethodPage
.qml обязателен для явного плагина и опционален для неявного. - Файл
Info.qml , является вспомогательным для предыдущего и нужен для отображения сообщений на страничке MethodPage.qml и сообщений об ошибках на общей для всех плагинов страничке AuthFailed.qml. - Файл настроек плагина settings-
.cc обязателен для явного плагина. Файл (Важно чтобы на выходе получился корректный qml-плагин (тоже *.so, но отличный от *.so authd-плагина), который можно использовать на своей страничкеSectionItem.qml в «Настройках») и опционален для других типов;
- Файл страницы для аутентификации MethodPage
- Каталог настроек settings.
Каталог опционален для всех типов плагинов и должен содержать:
- Файл settings.pro.
- Каталог
-settings с файламиSectionItem.qml ,Settings.qml ,auth.json .
Требования к API плагина
С точки зрения плагина процесс аутентификации выглядит следующим образом:
- Старт аутентификации со стороны AuthService (если данный фактор выбран у пользователя).
- При необходимости плагин запрашивает ввод пользователя с помощью Qt-сигнала
inputRequested. AuthService передаёт запрос зарегистрированному AuthUiClient, который отображает UI-страницу с соответствующей формой ввода. - После ввода пользовательские данные отправляются AuthService и передаются плагину для проверки.
- Результат проверки возвращается AuthService с помощью Qt-сигнала
methodFinished, в случае ошибки передаётся код, который транслируется в строку с переводом. - Если результат проверки успешный, то AuthService переходит к следующему фактору.
AuthService ожидает, что плагин имеет обработчики следующих запросов:
- Authd-плагин (библиотека .so, реализующая методы AuthPluginInterface).
- Непривилегированный процесс, запускаемый плагином в контейнере (<название_плагина>-клиент), который реализует описанные методы.
- Аутентификация
authenticate. - Получение и установка глобальной опции:
getOption,setOption. - Получение и установка пользовательской опции:
getUserOption,setUserOption. - Выполнение глобальных привилегированных действий:
action. - Выполнение пользовательских привилегированных действий:
userAction.
Пользовательские опции отличаются от глобальных привязкой к идентификатору заданного пользователя.
При запросе незнакомой опции методы getOption и getUserOption должны вернуть пустой variant,
а setOption и setUserOption — false.
API методов плагина
QVariantMap readyForAuthentication()
Метод позволяет получить информацию о том, что клиент готов к аутентификации и узнать страницу, которую нужно видеть при аутентификации.
Ответ:
bool res— готов/не готов;QString page— c помощью какой страницы аутентифицироваться;
Варианты ответов могут расширяться.
QVariantMap authentificate(QVariantMap param)
Метод проверяет вводимые данные, при успехе происходит аутентификация.
param содержит данные для аутентификации.
Примеры:
{ "pin": text }
{ "password": text }
{ "cert": text, "pin": text }
Ответ:
bool res— успешно/не успешно;QString err: "success", "failure", "login locked", "password expired", "no network connection";
Варианты ответов могут расширяться.
Клиент может присылать текущее количество неуспешных попыток: uint attempts.
QString validateCert(const QString &certName, const QString &userLogin, const QString &pin)
Метод производит проверку по логину, PIN и сертификату, при успехе происходит аутентификация.
certName— сертификат, выбранный из списка, переданногоgetCertList;userLogin— логин текущего пользователя;pin— PIN-код от сертификата.
Ответ:
QString err: "success", "failure", "login locked", "password expired", "no network connection", "cert is not valid".
Требования к файлам плагина
Файл .json
Файл PluginInfo при загрузке плагина.
Структура файла:
{
"Name": "имя плагина",
"Descr": "Описание плагина",
"Page": "Страница для аутентификации (если тип плагина явный, т. е. auth)",
"Version": "Номер версии (например, 0.0.1)",
"Type": "Тип плагина — auth/implicit/non-auth",
"Priority": "Порядковый номер приоритета процесса"
}
Название плагина указывается в нижнем регистре и используется в названиях каталогов и файлов (см. структуру плагина выше). Название страницы обычно соответствует названию плагина, но пишется в CamelCase. Оно используется в названии qml-файлов (см. структуру плагина выше).
Пример для явного плагина:
{
"Name": "myplugin",
"Descr": "Описание",
"Page": "MyPlugin",
"Version": "0.0.1",
"Type": "auth",
"Priority": 10
}
Пример для неявного плагина:
{
"Name": "myplugin",
"Descr": "Описание",
"Page": "MyPlugin",
"Version": "0.0.1",
"Type": "implicit",
"Priority": 50
}
Пример для не аутентифицирующего плагина:
{
"Name": "myplugin",
"Descr": "Описание",
"Page": "",
"Version": "0.0.1",
"Type": "non-auth",
"Priority": 50
}
Файл method-.cc
Файл method-
Файл policy.conf
Чтобы задать максимальное возможное число попыток пользователя связаться с плагином,
нужно создать файл policy.conf и задать значение max-attempts:
max-attempts=7
Данный файл должен размещаться по пути
/usr/share/ru.<имя_организации>.
Его можно разместить по данному пути, добавив
в .spec-файл
в секции %install и %files строки:
%install
install -D -m 0644 policy.conf %{buildroot}/usr/share/ru.<имя_организации>.<plugin>_client/policy.conf
%files
...
/usr/share/ru.<имя_организации>.<plugin>_client/policy.conf
Значение attempts для текущего пользователя
Текущее значение max-attempts, если оно меняется на сервере в процессе работы, размещается
в файле /srv/shared/ru.<имя_организации>/
Файлы MethodPage.qml и Info.qml
MethodPage
Страница обязательно содержит в корневом элементе js-функции:
function infoMessage(id)— функция возвращает текстовое сообщение для пользователя в процессе аутентификации, например, просьбу ввести пароль, придумать новый и т. п.;function resultMessage(id)— функция возвращает текстовое сообщение для пользователя об итогах аутентификации, например, об успехе или ошибке.
Файл settings-.cc
settings-
Каталог settings
Каталог settings хранит набор файлов для приложения «Настройки»
в
Настройки могут быть общими и пользовательскими.
Файл в settings settings.pro содержит пути:
- для общих настроек
path = /usr/share/jolla-settings/pages/users/general; - для пользовательских настроек
path = /usr/share/jolla-settings/pages/users/user-settings.
Пример pro-файла:
TEMPLATE = aux
settings.path = /usr/share/jolla-settings/pages/users/general
settings.files = password-settings
management.path =/usr/share/jolla-settings/pages/users/user-settings
management.files = passwords-management
INSTALLS += settings management
OTHER_FILES += *.qml *.json
Каталог
SectionItem.qml — секция в настройках;Settings.qml — страница с настройками, которая открывается при нажатии на секцию;auth.json — конфигурация для связи секции и страницы настроек.
Файл с именем <Plugin-name>SectionItem.qml добавляет пункт меню
в «Настройках безопасности пользователя».
Файл с именем <Plugin-name>Settings.qml — страницу, которая откроется при нажатии
на этот пункт меню.
Пример MyPluginSectionItem.qml:
import QtQuick 2.0
import Sailfish.Silica 1.0
import com.jolla.settings.system 1.0
SectionItem {
name: qsTr("Password Settings")
description: qsTr("Password policy settings")
}
Пример mypluginauth.json:
{
"page": "MyPluginSettings.qml",
"item": "MyPluginSectionItem.qml",
"order": 400
}
Использование Authd
Плагин Authd можно использовать на странице для подтверждения/аутентификации.
Для его использования в qml необходимо подключить библиотеку authclient:
import ru.omp.authclient 1.0
Компоненты для аутентификации:
AuthQuery {
id: query
}
AuthUi {
id: authUi
registered: true
}
Пример запуска для действия, например, нажатия кнопки:
onClicked: {
query.authenticate(function() {
//действие при успехе
}, function() {
// если аутентификация не была пройдена
})
}
Если аутентификация должна быть запущена из диалога:
const obj = SettingsUtils.openDialogPage(Qt.resolvedUrl("NameDialog.qml"),
{ acceptDestination: query.tokenIsValid
? root
: root.authUi,
acceptDestinationAction: query.tokenIsValid
? PageStackAction.Pop
: PageStackAction.Replace })
obj.pageCompleted.connect(function(dialog) {
dialog.accepted.connect(function() {
//действие при успехе
}, function() {
// если аутентификация не была пройдена
})
})