|
|
|
|
@@ -25,15 +25,80 @@
|
|
|
|
|
#define SSHD_SERVICE "sshd.service"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef SSHD_SOCKET
|
|
|
|
|
#define SSHD_SOCKET "sshd.socket"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
|
SYSTEMD_UNIT_UNKNOWN,
|
|
|
|
|
SYSTEMD_UNIT_SSHD_SERVICE,
|
|
|
|
|
SYSTEMD_UNIT_SSHD_SOCKET,
|
|
|
|
|
} SystemdUnit;
|
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
|
SYSTEMD_SERVICE_STATE_UNKNOWN,
|
|
|
|
|
SYSTEMD_SERVICE_STATE_DISABLED,
|
|
|
|
|
SYSTEMD_SERVICE_STATE_ENABLED_AND_ACTIVE,
|
|
|
|
|
} SystemdServiceState;
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
SystemdUnit unit;
|
|
|
|
|
SystemdServiceState state;
|
|
|
|
|
} SystemdService;
|
|
|
|
|
|
|
|
|
|
#define CONTAINER_OF(ptr, type, member) \
|
|
|
|
|
((type *) ((guint8 *) (ptr) - G_STRUCT_OFFSET (type, member)))
|
|
|
|
|
|
|
|
|
|
#define SYSTEMD_SERVICE_UNIT_NAME(service) \
|
|
|
|
|
((service)->unit == SYSTEMD_UNIT_SSHD_SERVICE ? SSHD_SERVICE : \
|
|
|
|
|
(service)->unit == SYSTEMD_UNIT_SSHD_SOCKET ? SSHD_SOCKET : "UNKNOWN")
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
AdwSwitchRow *widget;
|
|
|
|
|
GtkWidget *row;
|
|
|
|
|
GCancellable *cancellable;
|
|
|
|
|
SystemdService sshd_service;
|
|
|
|
|
SystemdService sshd_socket;
|
|
|
|
|
} CallbackData;
|
|
|
|
|
|
|
|
|
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (CallbackData, g_free)
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
systemd_service_cleanup (SystemdService *service)
|
|
|
|
|
{
|
|
|
|
|
CallbackData *callback_data;
|
|
|
|
|
|
|
|
|
|
if (service->unit == SYSTEMD_UNIT_SSHD_SERVICE)
|
|
|
|
|
{
|
|
|
|
|
callback_data = CONTAINER_OF (service, CallbackData, sshd_service);
|
|
|
|
|
}
|
|
|
|
|
else if (service->unit == SYSTEMD_UNIT_SSHD_SOCKET)
|
|
|
|
|
{
|
|
|
|
|
callback_data = CONTAINER_OF (service, CallbackData, sshd_socket);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
service->unit = SYSTEMD_UNIT_UNKNOWN;
|
|
|
|
|
|
|
|
|
|
if (callback_data->sshd_service.unit == SYSTEMD_UNIT_UNKNOWN &&
|
|
|
|
|
callback_data->sshd_socket.unit == SYSTEMD_UNIT_UNKNOWN)
|
|
|
|
|
{
|
|
|
|
|
g_free(callback_data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SystemdService, systemd_service_cleanup)
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
state_ready_callback (GObject *source_object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data);
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
set_switch_state (AdwSwitchRow *widget,
|
|
|
|
|
gboolean active)
|
|
|
|
|
@@ -52,7 +117,8 @@ active_state_ready_callback (GObject *source_object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
g_autoptr(CallbackData) callback_data = user_data;
|
|
|
|
|
CallbackData *callback_data;
|
|
|
|
|
g_autoptr(SystemdService) service = user_data;
|
|
|
|
|
g_autoptr(GVariant) active_variant = NULL;
|
|
|
|
|
g_autoptr(GVariant) child_variant = NULL;
|
|
|
|
|
g_autoptr(GVariant) tmp_variant = NULL;
|
|
|
|
|
@@ -75,15 +141,51 @@ active_state_ready_callback (GObject *source_object,
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (service->unit == SYSTEMD_UNIT_SSHD_SERVICE)
|
|
|
|
|
{
|
|
|
|
|
callback_data = CONTAINER_OF (service, CallbackData, sshd_service);
|
|
|
|
|
}
|
|
|
|
|
else if (service->unit == SYSTEMD_UNIT_SSHD_SOCKET)
|
|
|
|
|
{
|
|
|
|
|
callback_data = CONTAINER_OF (service, CallbackData, sshd_socket);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
child_variant = g_variant_get_child_value (active_variant, 0);
|
|
|
|
|
tmp_variant = g_variant_get_variant (child_variant);
|
|
|
|
|
active_state = g_variant_get_string (tmp_variant, NULL);
|
|
|
|
|
|
|
|
|
|
active = g_str_equal (active_state, "active");
|
|
|
|
|
|
|
|
|
|
/* set the switch to the correct state */
|
|
|
|
|
if (callback_data->widget)
|
|
|
|
|
set_switch_state (callback_data->widget, active);
|
|
|
|
|
if (active)
|
|
|
|
|
{
|
|
|
|
|
g_debug ("%s is active...", SYSTEMD_SERVICE_UNIT_NAME (service));
|
|
|
|
|
service->state = SYSTEMD_SERVICE_STATE_ENABLED_AND_ACTIVE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_debug ("%s is not active...", SYSTEMD_SERVICE_UNIT_NAME (service));
|
|
|
|
|
service->state = SYSTEMD_SERVICE_STATE_DISABLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if we now have states for both the service and the socket, then we can
|
|
|
|
|
* set the switch state */
|
|
|
|
|
if (callback_data->sshd_service.state != SYSTEMD_SERVICE_STATE_UNKNOWN &&
|
|
|
|
|
callback_data->sshd_socket.state != SYSTEMD_SERVICE_STATE_UNKNOWN)
|
|
|
|
|
{
|
|
|
|
|
gboolean active = (callback_data->sshd_service.state == SYSTEMD_SERVICE_STATE_ENABLED_AND_ACTIVE ||
|
|
|
|
|
callback_data->sshd_socket.state == SYSTEMD_SERVICE_STATE_ENABLED_AND_ACTIVE);
|
|
|
|
|
|
|
|
|
|
/* set the switch to the correct state */
|
|
|
|
|
if (callback_data->widget)
|
|
|
|
|
{
|
|
|
|
|
g_debug ("Setting switch state for %s: %d", SYSTEMD_SERVICE_UNIT_NAME (service), active);
|
|
|
|
|
set_switch_state (callback_data->widget, active);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
@@ -91,12 +193,26 @@ path_ready_callback (GObject *source_object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
g_autoptr(CallbackData) callback_data = user_data;
|
|
|
|
|
CallbackData *callback_data;
|
|
|
|
|
g_autoptr(SystemdService) service = user_data;
|
|
|
|
|
g_autoptr(GVariant) path_variant = NULL;
|
|
|
|
|
g_autoptr(GVariant) child_variant = NULL;
|
|
|
|
|
const gchar *object_path;
|
|
|
|
|
g_autoptr(GError) error = NULL;
|
|
|
|
|
|
|
|
|
|
if (service->unit == SYSTEMD_UNIT_SSHD_SERVICE)
|
|
|
|
|
{
|
|
|
|
|
callback_data = CONTAINER_OF (service, CallbackData, sshd_service);
|
|
|
|
|
}
|
|
|
|
|
else if (service->unit == SYSTEMD_UNIT_SSHD_SOCKET)
|
|
|
|
|
{
|
|
|
|
|
callback_data = CONTAINER_OF (service, CallbackData, sshd_socket);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
path_variant = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
|
|
|
|
|
result, &error);
|
|
|
|
|
|
|
|
|
|
@@ -131,8 +247,8 @@ path_ready_callback (GObject *source_object,
|
|
|
|
|
-1,
|
|
|
|
|
callback_data->cancellable,
|
|
|
|
|
active_state_ready_callback,
|
|
|
|
|
callback_data);
|
|
|
|
|
g_steal_pointer (&callback_data);
|
|
|
|
|
service);
|
|
|
|
|
g_steal_pointer (&service);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
@@ -140,12 +256,26 @@ state_ready_callback (GObject *source_object,
|
|
|
|
|
GAsyncResult *result,
|
|
|
|
|
gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
g_autoptr(CallbackData) callback_data = user_data;
|
|
|
|
|
CallbackData *callback_data;
|
|
|
|
|
g_autoptr(SystemdService) service = user_data;
|
|
|
|
|
g_autoptr(GVariant) state_variant = NULL;
|
|
|
|
|
g_autoptr(GVariant) child_variant = NULL;
|
|
|
|
|
const gchar *state_string;
|
|
|
|
|
g_autoptr(GError) error = NULL;
|
|
|
|
|
|
|
|
|
|
if (service->unit == SYSTEMD_UNIT_SSHD_SERVICE)
|
|
|
|
|
{
|
|
|
|
|
callback_data = CONTAINER_OF (service, CallbackData, sshd_service);
|
|
|
|
|
}
|
|
|
|
|
else if (service->unit == SYSTEMD_UNIT_SSHD_SOCKET)
|
|
|
|
|
{
|
|
|
|
|
callback_data = CONTAINER_OF (service, CallbackData, sshd_socket);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
state_variant = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
|
|
|
|
|
result, &error);
|
|
|
|
|
if (!state_variant)
|
|
|
|
|
@@ -156,9 +286,13 @@ state_ready_callback (GObject *source_object,
|
|
|
|
|
/* this may fail if systemd or remote login service is not available */
|
|
|
|
|
g_debug ("Error getting remote login state: %s", error->message);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* hide the remote login row, since the service is not available */
|
|
|
|
|
if (callback_data->row)
|
|
|
|
|
gtk_widget_set_visible (callback_data->row, FALSE);
|
|
|
|
|
{
|
|
|
|
|
g_debug ("Setting widget visibility FALSE for %s", SYSTEMD_SERVICE_UNIT_NAME (service));
|
|
|
|
|
gtk_widget_set_visible (callback_data->row, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -168,30 +302,46 @@ state_ready_callback (GObject *source_object,
|
|
|
|
|
|
|
|
|
|
if (g_str_equal (state_string, "enabled"))
|
|
|
|
|
{
|
|
|
|
|
g_debug ("%s is enabled - checking if running...", SYSTEMD_SERVICE_UNIT_NAME (service));
|
|
|
|
|
/* service is enabled, so check whether it is running or not */
|
|
|
|
|
g_dbus_connection_call (G_DBUS_CONNECTION (source_object),
|
|
|
|
|
"org.freedesktop.systemd1",
|
|
|
|
|
"/org/freedesktop/systemd1",
|
|
|
|
|
"org.freedesktop.systemd1.Manager",
|
|
|
|
|
"GetUnit",
|
|
|
|
|
g_variant_new ("(s)", SSHD_SERVICE),
|
|
|
|
|
g_variant_new ("(s)", SYSTEMD_SERVICE_UNIT_NAME (service)),
|
|
|
|
|
(GVariantType*) "(o)",
|
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
|
-1,
|
|
|
|
|
callback_data->cancellable,
|
|
|
|
|
path_ready_callback,
|
|
|
|
|
callback_data);
|
|
|
|
|
g_steal_pointer (&callback_data);
|
|
|
|
|
service);
|
|
|
|
|
g_steal_pointer (&service);
|
|
|
|
|
}
|
|
|
|
|
else if (g_str_equal (state_string, "disabled"))
|
|
|
|
|
{
|
|
|
|
|
/* service is available, but is currently disabled */
|
|
|
|
|
set_switch_state (callback_data->widget, FALSE);
|
|
|
|
|
g_debug ("%s is disabled...", SYSTEMD_SERVICE_UNIT_NAME (service));
|
|
|
|
|
service->state = SYSTEMD_SERVICE_STATE_DISABLED;
|
|
|
|
|
/* if we now have states for both the service and the socket, then we can
|
|
|
|
|
* set the switch state */
|
|
|
|
|
if (callback_data->sshd_service.state != SYSTEMD_SERVICE_STATE_UNKNOWN &&
|
|
|
|
|
callback_data->sshd_socket.state != SYSTEMD_SERVICE_STATE_UNKNOWN)
|
|
|
|
|
{
|
|
|
|
|
gboolean active = (callback_data->sshd_service.state == SYSTEMD_SERVICE_STATE_ENABLED_AND_ACTIVE ||
|
|
|
|
|
callback_data->sshd_socket.state == SYSTEMD_SERVICE_STATE_ENABLED_AND_ACTIVE);
|
|
|
|
|
|
|
|
|
|
/* set the switch to the correct state */
|
|
|
|
|
if (callback_data->widget)
|
|
|
|
|
{
|
|
|
|
|
g_debug ("Setting switch state for %s: %d", SYSTEMD_SERVICE_UNIT_NAME (service), active);
|
|
|
|
|
set_switch_state (callback_data->widget, active);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* unknown state */
|
|
|
|
|
g_warning ("Unknown state %s for %s", state_string, SSHD_SERVICE);
|
|
|
|
|
g_warning ("Unknown state %s for %s", state_string, SYSTEMD_SERVICE_UNIT_NAME (service));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -225,7 +375,19 @@ bus_ready_callback (GObject *source_object,
|
|
|
|
|
-1,
|
|
|
|
|
callback_data->cancellable,
|
|
|
|
|
state_ready_callback,
|
|
|
|
|
callback_data);
|
|
|
|
|
&callback_data->sshd_service);
|
|
|
|
|
g_dbus_connection_call (connection,
|
|
|
|
|
"org.freedesktop.systemd1",
|
|
|
|
|
"/org/freedesktop/systemd1",
|
|
|
|
|
"org.freedesktop.systemd1.Manager",
|
|
|
|
|
"GetUnitFileState",
|
|
|
|
|
g_variant_new ("(s)", SSHD_SOCKET),
|
|
|
|
|
(GVariantType*) "(s)",
|
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
|
-1,
|
|
|
|
|
callback_data->cancellable,
|
|
|
|
|
state_ready_callback,
|
|
|
|
|
&callback_data->sshd_socket);
|
|
|
|
|
g_steal_pointer (&callback_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -243,6 +405,10 @@ cc_remote_login_get_enabled (GCancellable *cancellable,
|
|
|
|
|
callback_data->widget = widget;
|
|
|
|
|
callback_data->row = row;
|
|
|
|
|
callback_data->cancellable = cancellable;
|
|
|
|
|
callback_data->sshd_service.unit = SYSTEMD_UNIT_SSHD_SERVICE;
|
|
|
|
|
callback_data->sshd_service.state = SYSTEMD_SERVICE_STATE_UNKNOWN;
|
|
|
|
|
callback_data->sshd_socket.unit = SYSTEMD_UNIT_SSHD_SOCKET;
|
|
|
|
|
callback_data->sshd_socket.state = SYSTEMD_SERVICE_STATE_UNKNOWN;
|
|
|
|
|
|
|
|
|
|
g_bus_get (G_BUS_TYPE_SYSTEM, callback_data->cancellable,
|
|
|
|
|
bus_ready_callback, callback_data);
|
|
|
|
|
|