C++の応用 - PolKit
ナビゲーションに移動
検索に移動
概要
PolKitのインストール
# RHEL sudo dnf install polkit-devel # SUSE sudo zypper install polkit-devel
CMakeファイルの設定
# CMakeLists.txtファイル
# 実行ファイルの場合
add_executable(<プロジェクト名>
# ...略
)
# ライブラリの場合
add_library(<プロジェクト名>
# ...略
)
include_directories(
# ...略
/usr/lib64/glib-2.0/include
/usr/include/glib-2.0
/usr/include/polkit-1
# ...略
)
target_link_libraries(<プロジェクト名>
# ...略
glib-2.0
polkit-gobject-1
gobject-2.0
gio-2.0
# ...略
)
サンプルコード
#include <polkit/polkit.h>
void check_authorization(PolkitAuthority *authority, GAsyncResult *res, gpointer user_data);
gboolean do_cancel(GCancellable *cancellable);
int main()
{
// Action ID for PolKit
const gchar *action_id = "org.qt.policykit.examples2.write";
// メインイベントループを作成
GMainLoop *loop = g_main_loop_new(nullptr, FALSE);
// 権威への参照を同期的に取得 (応答を受け取るまで呼び出し元のスレッドはブロックされる)
// 非同期にする場合は、polkit_authority_get_async関数を使用する
PolkitAuthority *authority = polkit_authority_get_sync(nullptr, nullptr);
// 多くのクライアントはD-Busを介してメカニズムと通信するため、PolkitSystemBusNameを使用する
// しかし、この例では、呼び出しプロセスのプロセスIDを使用する
// 親プロセスが終了した場合、init(1)が認可されているかどうかをチェックしないように注意する (常に認可されている)
// 親プロセスのPIDを取得
auto parent_pid = getppid();
if (parent_pid == 1) {
g_printerr("Parent process was reaped by init(1)\n");
return -1;
}
// 詳細情報の取得
PolkitSubject *subject = polkit_unix_process_new_for_owner(parent_pid, 0, getuid());
// PolKit認証画面でタイムアウトを使用する場合 (以下の例では、10[sec])
GCancellable *cancellable = g_cancellable_new();
g_timeout_add(1000 * 10, (GSourceFunc)do_cancel, cancellable);
// 認証画面の表示 (タイムアウト設定なし)
polkit_authority_check_authorization(authority, subject, action_id, nullptr,
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
nullptr, (GAsyncReadyCallback)check_authorization, loop);
// 認証画面の表示 (タイムアウト設定あり)
// polkit_authority_check_authorization(authority, subject, action_id, nullptr,
// POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
// cancellable, (GAsyncReadyCallback)check_authorization, loop);
// メインイベントループの実行
g_main_loop_run(loop);
// 終了処理
g_object_unref(authority);
g_object_unref(subject);
g_object_unref(cancellable);
g_main_loop_unref(loop);
return 0;
}
// 認証処理
void check_authorization(PolkitAuthority *authority, GAsyncResult *res, gpointer user_data)
{
GError *error = nullptr;
PolkitAuthorizationResult *result = polkit_authority_check_authorization_finish(authority, res, &error);
if (error != nullptr) {
// タイムアウトになった場合 (タイムアウト処理を指定する必要がある)
g_print ("Error checking authorization: %s\n", error->message);
g_error_free(error);
}
else {
const gchar *result_str;
if (polkit_authorization_result_get_is_authorized(result)) {
// 認証に成功した場合
result_str = "authorized";
}
else if (polkit_authorization_result_get_is_challenge(result)) {
// より詳細な情報が提供された場合に認可されているかどうかを取得
result_str = "challenge";
}
else {
// 認証をキャンセルした場合
result_str = "not authorized";
}
g_print("Authorization result: %s\n", result_str);
}
// メインイベントループの終了
auto loop = static_cast<GMainLoop*>(user_data);
g_main_loop_quit(loop);
}
// タイムアウト処理
gboolean do_cancel(GCancellable *cancellable)
{
g_print("Timer has expired; cancelling authorization check\n");
g_cancellable_cancel(cancellable);
return FALSE;
}