Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

Commit

Permalink
feat: working on unlocking
Browse files Browse the repository at this point in the history
  • Loading branch information
RossComputerGuy committed Apr 30, 2024
1 parent 8052db0 commit c208578
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 33 deletions.
6 changes: 5 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@

pubspecLock = lib.importJSON ./pubspec.lock.json;

postInstall = ''
mv $out/bin/genesis_shell $out/bin/genesis-shell
'';

meta = {
mainProgram = "genesis_shell";
mainProgram = "genesis-shell";
};
};
};
Expand Down
25 changes: 22 additions & 3 deletions lib/views/system/lock.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart';
import 'package:intl/intl.dart';

Expand All @@ -15,11 +16,27 @@ class SystemLockView extends StatefulWidget {
}

class _SystemLockViewState extends State<SystemLockView> {
static const platform = MethodChannel('com.expidusos.genesis.shell/auth');

TextEditingController passcodeController = TextEditingController();
String? errorText = null;

void _onSubmitted(String input) {
passcodeController.clear();
print(input);
setState(() {
errorText = null;
});

platform.invokeMethod('auth', {
'password': input,
}).then((user) {
setState(() {
passcodeController.clear();
errorText = null;
});
print(user);
}).catchError((err) => setState(() {
errorText = '${err.code}: ${err.message}: ${err.details.toString()}';
}));
}

@override
Expand Down Expand Up @@ -98,9 +115,11 @@ class _SystemLockViewState extends State<SystemLockView> {
child: TextField(
controller: passcodeController,
obscureText: true,
decoration: const InputDecoration(
decoration: InputDecoration(
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 4.0),
errorMaxLines: 5,
errorText: errorText,
),
style: Theme.of(context).textTheme.displayMedium,
onSubmitted: _onSubmitted,
Expand Down
3 changes: 3 additions & 0 deletions linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)

install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/data/pam" DESTINATION "${CMAKE_INSTALL_PREFIX}/etc/pam.d"
RENAME "genesis-shell")

foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
install(FILES "${bundled_library}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
Expand Down
48 changes: 19 additions & 29 deletions linux/channels/auth.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,45 @@
#include <security/pam_appl.h>
#include <security/pam_misc.h>

#include <pwd.h>

#include "outputs.h"
#include "../application-priv.h"

static void message_callback(GObject* obj, GAsyncResult* result, gpointer user_data) {
GArray* array_resp = (GArray*)user_data;

g_autoptr(FlMethodResponse) response = fl_method_channel_invoke_method_finish(FL_METHOD_CHANNEL(obj), result, nullptr);
g_autoptr(FlValue) resp_value = fl_method_response_get_result(response, nullptr);

struct pam_response resp;
resp.resp_retcode = 0;
resp.resp = g_strdup(fl_value_get_string(resp_value));
g_array_append_val(array_resp, resp);
}

static int conversation(int num_msg, const struct pam_message** msg, struct pam_response** resp, void* appdata_ptr) {
GenesisShellApplication* self = GENESIS_SHELL_APPLICATION(appdata_ptr);

GArray* array_resp = g_array_new(false, true, sizeof (struct pam_response));

struct pam_response* array_resp = (struct pam_response*)malloc(num_msg * sizeof(struct pam_response));
for (int i = 0; i < num_msg; i++) {
const char* msg_content = msg[i]->msg;

fl_method_channel_invoke_method(self->auth, "ask", fl_value_new_string(msg_content), nullptr, message_callback, array_resp);
}

while (true) {
if ((array_resp->len / sizeof (struct pam_response)) == num_msg) {
break;
}
array_resp[i].resp_retcode = 0;
array_resp[i].resp = g_strdup((const gchar*)appdata_ptr);
}

*resp = static_cast<struct pam_response*>(g_array_steal(array_resp, nullptr));
*resp = array_resp;
return PAM_SUCCESS;
}

void auth_method_call_handler(FlMethodChannel* channel, FlMethodCall* method_call, gpointer user_data) {
g_autoptr(FlMethodResponse) response = nullptr;
if (strcmp(fl_method_call_get_name(method_call), "start") == 0) {
if (strcmp(fl_method_call_get_name(method_call), "auth") == 0) {
FlValue* args = fl_method_call_get_args(method_call);

gchar* username = nullptr;
if (fl_value_lookup_string(args, "username") != nullptr) {
username = (gchar*)fl_value_get_string(fl_value_lookup_string(args, "username"));
} else {
struct passwd* pw = nullptr;
if ((pw = getpwuid(getuid())) == NULL) {
fl_method_call_respond_error(method_call, "shadow", "failed to get the username", NULL, NULL);
return;
}

username = pw->pw_name;
}

const gchar* password = fl_value_get_string(fl_value_lookup_string(args, "password"));

struct pam_conv* conv = (struct pam_conv*)malloc(sizeof(struct pam_conv));
conv->conv = conversation;
conv->appdata_ptr = user_data;
conv->appdata_ptr = (void*)password;

pam_handle_t* handle = NULL;
int r = pam_start("genesis-shell", username, conv, &handle);
Expand All @@ -70,7 +60,7 @@ void auth_method_call_handler(FlMethodChannel* channel, FlMethodCall* method_cal
return;
}

r = pam_acct_mgmt(handle, PAM_SILENT);
r = pam_setcred(handle, PAM_REFRESH_CRED);
if (r != PAM_SUCCESS) {
fl_method_call_respond_error(method_call, "PAM", "pam_acct_mgmt failed", fl_value_new_string(pam_strerror(handle, r)), NULL);
pam_end(handle, r);
Expand Down
5 changes: 5 additions & 0 deletions linux/data/pam
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Genesis Shell login management

auth required pam_unix.so
account required pam_unix.so
password required pam_unix.so
2 changes: 2 additions & 0 deletions nix/module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
isNormalUser = true;
};

security.pam.services.genesis-shell = {};

nix.enable = false;

system.stateVersion = lib.version;
Expand Down

0 comments on commit c208578

Please sign in to comment.