55#include < gdk/gdkx.h>
66#endif
77
8- #include < pwd.h>
9- #include < security/pam_appl.h>
10- #include < sys/types.h>
11- #include < unistd.h>
8+ #include < polkit/polkit.h>
129
1310#include < iostream>
1411#include < map>
@@ -21,149 +18,76 @@ struct _MyApplication {
2118 char ** dart_entrypoint_arguments;
2219};
2320
24- struct pam_response_t {
25- const char * password;
26- };
27-
2821G_DEFINE_TYPE (MyApplication, my_application, GTK_TYPE_APPLICATION )
2922
30- static gboolean can_authenticate () {
31- pam_handle_t * pamh = nullptr ;
32- struct pam_conv conv = { nullptr , nullptr } ;
33-
34- int ret = pam_start ( " login " , nullptr , &conv, &pamh );
35- if (ret != PAM_SUCCESS ) {
36- return FALSE ;
23+ static void can_authenticate (FlMethodCall* method_call ) {
24+ GError* error = nullptr ;
25+ PolkitAuthority* authority = polkit_authority_get_sync ( nullptr , &error) ;
26+ if (error) {
27+ fl_method_call_respond (method_call, FL_METHOD_RESPONSE ( fl_method_error_response_new ( " authCheckError " , error-> message , nullptr )), nullptr );
28+ g_clear_error (&error);
29+ return ;
3730 }
38-
39- pam_end (pamh, ret);
40- return TRUE ;
31+ if (authority == nullptr ) {
32+ fl_method_call_respond (method_call, FL_METHOD_RESPONSE (fl_method_success_response_new (fl_value_new_bool (false ))), nullptr );
33+ return ;
34+ }
35+ fl_method_call_respond (method_call, FL_METHOD_RESPONSE (fl_method_success_response_new (fl_value_new_bool (true ))), nullptr );
4136}
4237
43- static gchar* get_real_name ( ) {
38+ static void authenticate_async_callback (PolkitAuthority* authority, GAsyncResult* result, gpointer user_data ) {
4439 GError* error = nullptr ;
45- GDBusConnection* connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM , nullptr , &error);
46- if (!connection) return strdup (" Unknown" );
47-
48- gchar* user_path = nullptr ;
49- GVariant* result = g_dbus_connection_call_sync (
50- connection,
51- " org.freedesktop.Accounts" ,
52- " /org/freedesktop/Accounts" ,
53- " org.freedesktop.Accounts" ,
54- " FindUserByName" ,
55- g_variant_new (" (s)" , getenv (" USER" )),
56- G_VARIANT_TYPE (" (o)" ),
57- G_DBUS_CALL_FLAGS_NONE ,
58- -1 ,
59- nullptr ,
60- &error
61- );
62-
63- if (!result) return strdup (" Unknown" );
64-
65- g_variant_get (result, " (&o)" , &user_path);
66-
67- // Now get the RealName property
68- GVariant* name_result = g_dbus_connection_call_sync (
69- connection,
70- " org.freedesktop.Accounts" ,
71- user_path,
72- " org.freedesktop.DBus.Properties" ,
73- " Get" ,
74- g_variant_new (" (ss)" , " org.freedesktop.Accounts.User" , " RealName" ),
75- G_VARIANT_TYPE (" (v)" ),
76- G_DBUS_CALL_FLAGS_NONE ,
77- -1 ,
78- nullptr ,
79- &error
80- );
81-
82- if (!name_result) return strdup (" Unknown" );
83-
84- GVariant* name_value = nullptr ;
85- g_variant_get (name_result, " (v)" , &name_value);
86-
87- const char * real_name = g_variant_get_string (name_value, nullptr );
88- return strdup (real_name);
89- }
9040
91- static gchar* get_avatar_path () {
92- std::string path = " /var/lib/AccountsService/icons/" ;
93- path += getenv (" USER" );
94- return strdup (path.c_str ());
95- }
96-
97- static int pam_conversation (int num_msg, const struct pam_message ** msg, struct pam_response ** resp, void * appdata_ptr) {
98- struct pam_response_t * data = static_cast <struct pam_response_t *>(appdata_ptr);
99- // Allocate response memory
100- *resp = static_cast <struct pam_response *>(
101- calloc (num_msg, sizeof (struct pam_response )));
102-
103- if (*resp == nullptr ) {
104- return PAM_CONV_ERR ;
105- }
41+ // Retrieve the result from the async operation
42+ PolkitAuthorizationResult* auth_result = polkit_authority_check_authorization_finish (authority, result, &error);
10643
107- for (int i = 0 ; i < num_msg; i++) {
108- (*resp)[i].resp = strdup (data->password );
44+ if (error) {
45+ std::cout << error->message << std::endl;
46+ fl_method_call_respond ((FlMethodCall*)user_data, FL_METHOD_RESPONSE (fl_method_error_response_new (" authError" , error->message , nullptr )), nullptr );
47+ g_clear_error (&error);
48+ g_object_unref (user_data);
49+ return ;
10950 }
110-
111- return PAM_SUCCESS ;
112- }
113-
114- static void authenticate (const gchar* password, FlMethodCall* method_call) {
115- // Get the current username
116- struct passwd * pw = getpwuid (getuid ());
117- if (pw == nullptr ) {
118- fl_method_call_respond (method_call, FL_METHOD_RESPONSE (fl_method_error_response_new (" authError" , " Cannot get current user." , nullptr )), nullptr );
51+ if (auth_result == nullptr ) {
52+ fl_method_call_respond ((FlMethodCall*)user_data, FL_METHOD_RESPONSE (fl_method_success_response_new (fl_value_new_bool (false ))), nullptr );
53+ g_object_unref (user_data);
11954 return ;
12055 }
12156
122- // Set up PAM conversation
123- struct pam_response_t data;
124- data.password = password;
57+ gboolean success = polkit_authorization_result_get_is_authorized (auth_result);
58+ fl_method_call_respond ((FlMethodCall*)user_data, FL_METHOD_RESPONSE (fl_method_success_response_new (fl_value_new_bool (success))), nullptr );
12559
126- struct pam_conv conv;
127- conv.conv = pam_conversation;
128- conv.appdata_ptr = &data;
60+ g_object_unref (user_data); // Unref the method call after use
61+ }
12962
130- // Start PAM session
131- pam_handle_t * pamh = nullptr ;
132- int ret = pam_start ( " login " , pw-> pw_name , &conv, &pamh );
133- if (ret != PAM_SUCCESS ) {
134- fl_method_call_respond (method_call, FL_METHOD_RESPONSE (fl_method_error_response_new (" authError" , " Could not start authentication session. " , nullptr )), nullptr );
63+ static void authenticate (FlMethodCall* method_call) {
64+ GError* error = nullptr ;
65+ PolkitAuthority* authority = polkit_authority_get_sync ( nullptr , &error );
66+ if (error || authority == nullptr ) {
67+ fl_method_call_respond (method_call, FL_METHOD_RESPONSE (fl_method_error_response_new (" authError" , error-> message , nullptr )), nullptr );
13568 return ;
13669 }
13770
138- // Try to authenticate
139- ret = pam_authenticate (pamh, 0 );
140-
141- // Clean up
142- pam_end (pamh, ret);
143-
144- FlValue* success = fl_value_new_bool (ret == PAM_SUCCESS );
145- fl_method_call_respond (method_call, FL_METHOD_RESPONSE (fl_method_success_response_new (success)), nullptr );
71+ PolkitSubject* subject = polkit_unix_process_new_for_owner (getpid (), 0 , -1 );
72+ polkit_authority_check_authorization (
73+ authority,
74+ subject,
75+ " app.openauthenticator.authenticate" ,
76+ nullptr ,
77+ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION ,
78+ nullptr ,
79+ (GAsyncReadyCallback) authenticate_async_callback,
80+ g_object_ref (method_call)
81+ );
14682}
14783
14884static void method_call_cb (FlMethodChannel* channel, FlMethodCall* method_call, gpointer user_data) {
14985 const gchar* method = fl_method_call_get_name (method_call);
15086
15187 if (strcmp (method, " localAuth.isDeviceSupported" ) == 0 ) {
152- g_autoptr (FlValue) result = fl_value_new_bool (can_authenticate ());
153- g_autoptr (FlMethodResponse) response = FL_METHOD_RESPONSE (fl_method_success_response_new (result));
154- fl_method_call_respond (method_call, response, nullptr );
155- } else if (strcmp (method, " localAuth.getRealName" ) == 0 ) {
156- g_autoptr (FlValue) result = fl_value_new_string (get_real_name ());
157- g_autoptr (FlMethodResponse) response = FL_METHOD_RESPONSE (fl_method_success_response_new (result));
158- fl_method_call_respond (method_call, response, nullptr );
159- } else if (strcmp (method, " localAuth.getAvatarPath" ) == 0 ) {
160- g_autoptr (FlValue) result = fl_value_new_string (get_avatar_path ());
161- g_autoptr (FlMethodResponse) response = FL_METHOD_RESPONSE (fl_method_success_response_new (result));
162- fl_method_call_respond (method_call, response, nullptr );
88+ can_authenticate (method_call);
16389 } else if (strcmp (method, " localAuth.authenticate" ) == 0 ) {
164- FlValue* args = fl_method_call_get_args (method_call);
165- FlValue* password = fl_value_lookup_string (args, " password" );
166- authenticate (fl_value_get_string (password), method_call);
90+ authenticate (method_call);
16791 } else {
16892 g_autoptr (FlMethodResponse) response = FL_METHOD_RESPONSE (fl_method_not_implemented_response_new ());
16993 fl_method_call_respond (method_call, response, nullptr );
0 commit comments