2
* Copyright (C) 2016 Canonical Ltd.
4
* This library is free software; you can redistribute it and/or modify it under
5
* the terms of the GNU Lesser General Public License as published by the Free
6
* Software Foundation; either version 2 or version 3 of the License.
7
* See http://www.gnu.org/copyleft/lgpl.html the full text of the license.
12
#include <snapd-glib/snapd-glib.h>
13
#include <polkit/polkit.h>
15
#include "login-service.h"
17
#if !defined(POLKIT_HAS_AUTOPTR_MACROS)
18
G_DEFINE_AUTOPTR_CLEANUP_FUNC(PolkitAuthorizationResult, g_object_unref)
19
G_DEFINE_AUTOPTR_CLEANUP_FUNC(PolkitSubject, g_object_unref)
22
static GMainLoop *loop;
23
static int result = EXIT_SUCCESS;
25
static PolkitAuthority *authority = NULL;
26
static IoSnapcraftSnapdLoginService *service = NULL;
30
GDBusMethodInvocation *invocation;
34
GPermission *permission;
39
free_login_request (LoginRequest *request)
41
g_object_unref (request->invocation);
42
g_free (request->username);
43
g_free (request->password);
44
g_free (request->otp);
45
if (request->permission != NULL)
46
g_object_unref (request->permission);
47
if (request->client != NULL)
48
g_object_unref (request->client);
49
g_slice_free (LoginRequest, request);
52
G_DEFINE_AUTOPTR_CLEANUP_FUNC (LoginRequest, free_login_request);
55
login_result_cb (GObject *object, GAsyncResult *result, gpointer user_data)
57
g_autoptr(LoginRequest) request = user_data;
58
SnapdAuthData *auth_data;
59
g_autoptr(GError) error = NULL;
61
if (!snapd_client_login_finish (request->client, result, &error)) {
62
g_dbus_method_invocation_return_gerror (request->invocation, error);
66
auth_data = snapd_client_get_auth_data (request->client);
67
io_snapcraft_snapd_login_service_complete_login (service, request->invocation,
68
snapd_auth_data_get_macaroon (auth_data),
69
(const gchar *const *) snapd_auth_data_get_discharges (auth_data));
73
auth_cb (GObject *object, GAsyncResult *result, gpointer user_data)
75
g_autoptr(LoginRequest) request = user_data;
76
g_autoptr(PolkitAuthorizationResult) r = NULL;
77
g_autoptr(GError) error = NULL;
79
r = polkit_authority_check_authorization_finish (authority, result, &error);
81
g_dbus_method_invocation_return_error (request->invocation,
83
SNAPD_ERROR_PERMISSION_DENIED,
84
"Failed to get permission from Polkit: %s", error->message);
88
if (!polkit_authorization_result_get_is_authorized (r)) {
89
g_dbus_method_invocation_return_error (request->invocation,
91
SNAPD_ERROR_PERMISSION_DENIED,
92
"Permission denied by Polkit");
96
g_debug ("Requesting login from snapd...");
98
request->client = snapd_client_new ();
99
if (!snapd_client_connect_sync (request->client, NULL, &error)) {
100
g_dbus_method_invocation_return_gerror (request->invocation, error);
104
snapd_client_login_async (request->client,
105
request->username, request->password, request->otp, NULL,
106
login_result_cb, request);
107
g_steal_pointer (&request);
111
login_cb (IoSnapcraftSnapdLoginService *service,
112
GDBusMethodInvocation *invocation,
113
const gchar *username,
114
const gchar *password,
118
g_autoptr(LoginRequest) request = NULL;
119
g_autoptr(PolkitSubject) subject = NULL;
121
request = g_slice_new0 (LoginRequest);
122
request->invocation = g_object_ref (invocation);
123
request->username = g_strdup (username);
124
request->password = g_strdup (password);
126
request->otp = g_strdup (otp);
128
g_debug ("Processing login request...");
130
subject = polkit_system_bus_name_new (g_dbus_method_invocation_get_sender (invocation));
131
polkit_authority_check_authorization (authority,
132
subject, "io.snapcraft.login", NULL,
133
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
135
auth_cb, g_steal_pointer (&request));
141
bus_acquired_cb (GDBusConnection *connection,
145
g_autoptr(GError) error = NULL;
147
g_debug ("Connected to D-Bus");
149
service = io_snapcraft_snapd_login_service_skeleton_new ();
150
g_signal_connect (service, "handle-login", G_CALLBACK (login_cb), NULL);
151
if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (service),
153
"/io/snapcraft/SnapdLoginService",
155
g_warning ("Failed to register object: %s", error->message);
156
result = EXIT_FAILURE;
157
g_main_loop_quit (loop);
162
name_acquired_cb (GDBusConnection *connection,
166
g_debug ("Acquired bus name %s", name);
170
name_lost_cb (GDBusConnection *connection,
174
if (connection == NULL) {
175
g_warning ("Failed to connect to bus");
176
result = EXIT_FAILURE;
179
g_info ("Lost bus name %s", name);
180
g_main_loop_quit (loop);
184
int main (int argc, char **argv)
186
g_autoptr(GError) error = NULL;
188
loop = g_main_loop_new (NULL, FALSE);
190
authority = polkit_authority_get_sync (NULL, &error);
191
if (authority == NULL) {
192
g_warning ("Failed to get Polkit authority: %s", error->message);
195
g_debug ("Connected to Polkit");
197
g_bus_own_name (G_BUS_TYPE_SYSTEM,
198
"io.snapcraft.SnapdLoginService",
199
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | G_BUS_NAME_OWNER_FLAGS_REPLACE,
205
g_main_loop_run (loop);