Документация
ОС Аврора 5.1.5

Пользовательские модули аутентификации

Authd — это сервис аутентификации с возможностью настройки различных факторов. Для аутентификации Authd может использовать один или несколько факторов (плагинов). Без выбранного фактора Authd отрабатывает корректно и аутентифицирует без каких либо запросов. Однако в целях безопасности на данный момент для всех прошивок по умолчанию в качестве фактора задан пароль.

Настройка списка факторов выполняется индивидуально для каждого пользователя администратором в системном приложении Настройки.

Authd сканирует каталог /usr/lib/authd/, чтобы найти установленные в систему факторы (плагины .so).

Authd содержит в себе:

  • сервис;
  • плагины (список может пополняться):
    • Блокировка;
    • Ограничение входа в систему;
    • Пароль;
    • Смарт-карта;
    • Простое подтверждение (пакет authd-tests);
  • консольное приложение auth-cli, которое позволяет проверять пароль из командной строки.

Каждый плагин реализует собственный фактор аутентификации.

Authd поддерживает API блокировок через D-Bus-интерфейс.

У каждого пользователя есть свой список факторов. Настройка списка факторов выполняется индивидуально для каждого пользователя администратором в системном приложении «Настройки».

Содержание:

Процесс аутентификации

Клиент подключается к сервису 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/ в файлах с именем вида .conf, где  — идентификатор пользователя. Список факторов изменяется при помощи API и вручную.

Редактирование файлов конфигурации не поддерживается во время работы 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 в «Настройках») и опционален для других типов;
  • Каталог настроек settings. Каталог опционален для всех типов плагинов и должен содержать:
    • Файл settings.pro.
    • Каталог -settings с файлами SectionItem.qml, Settings.qml, auth.json.

Требования к API плагина

С точки зрения плагина процесс аутентификации выглядит следующим образом:

  1. Старт аутентификации со стороны AuthService (если данный фактор выбран у пользователя).
  2. При необходимости плагин запрашивает ввод пользователя с помощью Qt-сигнала inputRequested. AuthService передаёт запрос зарегистрированному AuthUiClient, который отображает UI-страницу с соответствующей формой ввода.
  3. После ввода пользовательские данные отправляются AuthService и передаются плагину для проверки.
  4. Результат проверки возвращается AuthService с помощью Qt-сигнала methodFinished, в случае ошибки передаётся код, который транслируется в строку с переводом.
  5. Если результат проверки успешный, то 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

Файл .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-.cc содержит основную логику работы плагина. Он необходим для всех типов плагинов. На его основе собирается файл .so. При необходимости интерфейс может дополняться.

Файл policy.conf

Чтобы задать максимальное возможное число попыток пользователя связаться с плагином, нужно создать файл policy.conf и задать значение max-attempts:

max-attempts=7

Данный файл должен размещаться по пути /usr/share/ru.<имя_организации>._client/policy.conf.

Его можно разместить по данному пути, добавив в .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 для текущего пользователя размещается в файле /srv/shared/ru.<имя_организации>/_client/.conf.

Текущее значение max-attempts, если оно меняется на сервере в процессе работы, размещается в файле /srv/shared/ru.<имя_организации>/_client/current.conf.

Файлы MethodPage.qml и Info.qml

MethodPage.qml — страница для аутентификации. Она необходима для явного типа плагина, и также может использоваться, если тип плагина неявный.

Info.qml — вспомогательная страница для MethodPage.qml. Она обязательная, если есть страница аутентификации.  Нужна для перевода сообщений пользователю и вспомогательных данных.

Страница обязательно содержит в корневом элементе js-функции:

  • function infoMessage(id) — функция возвращает текстовое сообщение для пользователя в процессе аутентификации, например, просьбу ввести пароль, придумать новый и т. п.;
  • function resultMessage(id) — функция возвращает текстовое сообщение для пользователя об итогах аутентификации, например, об успехе или ошибке.

Файл settings-.cc

settings-.cc — плагин с настройками для использования в QML. Он собирается в libauthd-.so.

Каталог settings

Каталог settings хранит набор файлов для приложения «Настройки» в -settings и содержит конфигурационный файл settings.pro.

Настройки могут быть общими и пользовательскими.

Файл в 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

Каталог -settings находится в settings и содержит файлы:

  • 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() {
        // если аутентификация не была пройдена
    })
}) 

Мы используем cookies для персонализации сайта и его более удобного использования. Вы можете запретить cookies в настройках браузера.

Пожалуйста ознакомьтесь с политикой использования cookies.