Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions linux/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
cmake_minimum_required(VERSION 3.10)
set(PROJECT_NAME "secure_application")
project(${PROJECT_NAME} LANGUAGES CXX)

set(PLUGIN_NAME "${PROJECT_NAME}_plugin")

list(APPEND PLUGIN_SOURCES
"secure_application_plugin.cc"
)

add_library(${PLUGIN_NAME} SHARED
${PLUGIN_SOURCES}
)
apply_standard_settings(${PLUGIN_NAME})
set_target_properties(${PLUGIN_NAME} PROPERTIES
CXX_VISIBILITY_PRESET hidden)
target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
target_include_directories(${PLUGIN_NAME} INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(${PLUGIN_NAME} PRIVATE flutter)
target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK)

# List of absolute paths to libraries that should be bundled with the plugin
set(secure_application_bundled_libraries
""
PARENT_SCOPE
)
26 changes: 26 additions & 0 deletions linux/include/secure_application/secure_application_plugin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef FLUTTER_PLUGIN_SECURE_APPLICATION_PLUGIN_H_
#define FLUTTER_PLUGIN_SECURE_APPLICATION_PLUGIN_H_

#include <flutter_linux/flutter_linux.h>

G_BEGIN_DECLS

#ifdef FLUTTER_PLUGIN_IMPL
#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default")))
#else
#define FLUTTER_PLUGIN_EXPORT
#endif

typedef struct _SecureApplicationPlugin SecureApplicationPlugin;
typedef struct {
GObjectClass parent_class;
} SecureApplicationPluginClass;

FLUTTER_PLUGIN_EXPORT GType secure_application_plugin_get_type();

FLUTTER_PLUGIN_EXPORT void secure_application_plugin_register_with_registrar(
FlPluginRegistrar* registrar);

G_END_DECLS

#endif // FLUTTER_PLUGIN_SECURE_APPLICATION_PLUGIN_H_
80 changes: 80 additions & 0 deletions linux/secure_application_plugin.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include "include/secure_application/secure_application_plugin.h"

#include <flutter_linux/flutter_linux.h>
#include <gtk/gtk.h>
#include <sys/utsname.h>

#include <cstring>

#define SECURE_APPLICATION_PLUGIN(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), secure_application_plugin_get_type(), \
SecureApplicationPlugin))

struct _SecureApplicationPlugin {
GObject parent_instance;
FlMethodChannel* channel;
};

G_DEFINE_TYPE(SecureApplicationPlugin, secure_application_plugin,
g_object_get_type())

// Mirrors Windows: respond Success() to every method call. The actual lock /
// blur UI is rendered Dart-side by SecureGate, so the native plugin only needs
// to acknowledge channel calls and invoke "lock" on system events.
static void secure_application_plugin_handle_method_call(
SecureApplicationPlugin* self, FlMethodCall* method_call) {
g_autoptr(FlMethodResponse) response = nullptr;
const gchar* method = fl_method_call_get_name(method_call);

if (strcmp(method, "getPlatformVersion") == 0) {
struct utsname uname_data = {};
uname(&uname_data);
g_autofree gchar* version = g_strdup_printf("Linux %s", uname_data.version);
g_autoptr(FlValue) result = fl_value_new_string(version);
response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
} else {
response = FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
}
fl_method_call_respond(method_call, response, nullptr);
}

static void method_call_cb(FlMethodChannel* channel, FlMethodCall* method_call,
gpointer user_data) {
SecureApplicationPlugin* plugin = SECURE_APPLICATION_PLUGIN(user_data);
secure_application_plugin_handle_method_call(plugin, method_call);
}

static void secure_application_plugin_dispose(GObject* object) {
SecureApplicationPlugin* self = SECURE_APPLICATION_PLUGIN(object);
g_clear_object(&self->channel);
G_OBJECT_CLASS(secure_application_plugin_parent_class)->dispose(object);
}

static void secure_application_plugin_class_init(
SecureApplicationPluginClass* klass) {
G_OBJECT_CLASS(klass)->dispose = secure_application_plugin_dispose;
}

static void secure_application_plugin_init(SecureApplicationPlugin* self) {}

void secure_application_plugin_register_with_registrar(
FlPluginRegistrar* registrar) {
SecureApplicationPlugin* plugin = SECURE_APPLICATION_PLUGIN(
g_object_new(secure_application_plugin_get_type(), nullptr));

g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
plugin->channel =
fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar),
"secure_application", FL_METHOD_CODEC(codec));
fl_method_channel_set_method_call_handler(
plugin->channel, method_call_cb, g_object_ref(plugin), g_object_unref);

// NOTE: We deliberately do NOT hook the GTK window-state-event to invoke
// "lock" on iconify the way the Windows plugin hooks SC_MINIMIZE. On Linux,
// local_auth has no platform implementation, so an app that engages
// SecureGate's locked state has no way to authenticate back out — the user
// is stranded on the lock screen. Apps that want explicit lock-on-minimize
// on Linux can call `lock()` themselves from a Dart-side WindowListener.

g_object_unref(plugin);
}
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ flutter:
fileName: secure_application_web.dart
windows:
pluginClass: SecureApplicationPlugin
linux:
pluginClass: SecureApplicationPlugin