Bugfix: Fixes #316, logonui - validate default session

This commit is contained in:
Rory Fewell
2024-06-06 21:15:05 +01:00
parent da7a18c76b
commit befecbf114
8 changed files with 201 additions and 77 deletions

View File

@@ -791,6 +791,8 @@ static gboolean on_timeout_delay_done(
{
WinTCWelcomeUI* welcome_ui = WINTC_WELCOME_UI(user_data);
GError* error = NULL;
switch (welcome_ui->current_state)
{
case WINTC_GINA_STATE_STARTING:
@@ -802,9 +804,21 @@ static gboolean on_timeout_delay_done(
break;
case WINTC_GINA_STATE_LAUNCHING:
wintc_gina_logon_session_finish(
welcome_ui->logon_session
);
if (
!wintc_gina_logon_session_finish(
welcome_ui->logon_session,
&error
)
)
{
wintc_nice_error_and_clear(&error);
wintc_welcome_ui_change_state(
welcome_ui,
WINTC_GINA_STATE_PROMPT
);
}
break;
default:

View File

@@ -1026,28 +1026,27 @@ static void on_self_adjustment_changed(
static void on_logon_session_attempt_complete(
WINTC_UNUSED(WinTCGinaLogonSession* logon_session),
WinTCGinaResponse response,
WINTC_UNUSED(WinTCGinaResponse response),
gpointer user_data
)
{
WinTCWelcomeUserList* user_list = WINTC_WELCOME_USER_LIST(user_data);
if (response == WINTC_GINA_RESPONSE_FAIL)
{
gtk_entry_set_text(
GTK_ENTRY(user_list->entry_password),
""
);
// Reset the UI state after any logon attempt
//
gtk_entry_set_text(
GTK_ENTRY(user_list->entry_password),
""
);
gtk_widget_set_sensitive(
user_list->button_go,
TRUE
);
gtk_widget_set_sensitive(
user_list->entry_password,
TRUE
);
}
gtk_widget_set_sensitive(
user_list->button_go,
TRUE
);
gtk_widget_set_sensitive(
user_list->entry_password,
TRUE
);
}
static void on_button_go_clicked(

View File

@@ -37,6 +37,8 @@ add_library(
src/authwnd.c
public/authwnd.h
public/challenge.h
src/error.c
public/error.h
src/logon.c
public/logon.h
public/state.h

View File

@@ -0,0 +1,15 @@
#ifndef __MSGINA_ERROR_H__
#define __MSGINA_ERROR_H__
#include <glib.h>
#define WINTC_GINA_ERROR wintc_gina_error_quark()
typedef enum
{
WINTC_GINA_ERROR_NO_SESSIONS
} WinTCGinaError;
GQuark wintc_gina_error_quark(void);
#endif

View File

@@ -78,9 +78,11 @@ gboolean wintc_gina_logon_session_establish(
* authentication.
*
* @param logon_session The logon session.
* @param error Storage location for any error that occurred.
*/
void wintc_gina_logon_session_finish(
WinTCGinaLogonSession* logon_session
gboolean wintc_gina_logon_session_finish(
WinTCGinaLogonSession* logon_session,
GError** error
);
/**

View File

@@ -496,47 +496,45 @@ static void on_logon_session_attempt_complete(
{
WinTCGinaAuthWindow* window = WINTC_GINA_AUTH_WINDOW(user_data);
switch (response)
// Reset the UI state
//
gtk_entry_set_text(
GTK_ENTRY(window->entry_password),
""
);
gtk_entry_set_text(
GTK_ENTRY(window->entry_username),
""
);
gtk_widget_set_sensitive(
window->button_submit,
TRUE
);
gtk_widget_set_sensitive(
window->entry_password,
TRUE
);
gtk_widget_set_sensitive(
window->entry_username,
TRUE
);
wintc_gina_strip_stop_animating(
WINTC_GINA_STRIP(window->strip)
);
// Now handle specifics for whether the attempt succeeded or not
//
if (response == WINTC_GINA_RESPONSE_OKAY)
{
case WINTC_GINA_RESPONSE_OKAY:
wintc_gina_auth_window_change_state(
window,
WINTC_GINA_STATE_LAUNCHING
);
break;
case WINTC_GINA_RESPONSE_FAIL:
// FIXME: Prompt for failure
gtk_entry_set_text(
GTK_ENTRY(window->entry_password),
""
);
gtk_entry_set_text(
GTK_ENTRY(window->entry_username),
""
);
gtk_widget_set_sensitive(
window->button_submit,
TRUE
);
gtk_widget_set_sensitive(
window->entry_password,
TRUE
);
gtk_widget_set_sensitive(
window->entry_username,
TRUE
);
wintc_gina_strip_stop_animating(
WINTC_GINA_STRIP(window->strip)
);
break;
default: break;
wintc_gina_auth_window_change_state(
window,
WINTC_GINA_STATE_LAUNCHING
);
}
// else (WINTC_GINA_RESPONSE_FAIL)
// FIXME: Error should be handled here, when we have one
}
static void on_button_submit_clicked(
@@ -576,6 +574,8 @@ static gboolean on_timeout_delay_done(
{
WinTCGinaAuthWindow* window = WINTC_GINA_AUTH_WINDOW(user_data);
GError* error = NULL;
switch (window->current_state)
{
case WINTC_GINA_STATE_STARTING:
@@ -587,9 +587,21 @@ static gboolean on_timeout_delay_done(
break;
case WINTC_GINA_STATE_LAUNCHING:
wintc_gina_logon_session_finish(
window->logon_session
);
if (
!wintc_gina_logon_session_finish(
window->logon_session,
&error
)
)
{
wintc_nice_error_and_clear(&error);
wintc_gina_auth_window_change_state(
window,
WINTC_GINA_STATE_PROMPT
);
}
break;
default:

View File

@@ -0,0 +1,8 @@
#include <glib.h>
#include "../public/error.h"
//
// GLIB BOILERPLATE
//
G_DEFINE_QUARK(wintc-gina-error-quark, wintc_gina_error)

View File

@@ -3,6 +3,7 @@
#include <wintc/comgtk.h>
#include "../public/challenge.h"
#include "../public/error.h"
#include "../public/logon.h"
//
@@ -40,6 +41,10 @@ struct _WinTCGinaLogonSession
//
// FORWARD DECLARATIONS
//
static void reset_auth_state(
WinTCGinaLogonSession* logon_session
);
static void on_greeter_authentication_complete(
LightDMGreeter* greeter,
gpointer user_data
@@ -153,27 +158,83 @@ gboolean wintc_gina_logon_session_establish(
return TRUE;
}
void wintc_gina_logon_session_finish(
WinTCGinaLogonSession* logon_session
gboolean wintc_gina_logon_session_finish(
WinTCGinaLogonSession* logon_session,
GError** error
)
{
WINTC_SAFE_REF_CLEAR(error);
WINTC_LOG_DEBUG("GINA - finish requested");
if (!logon_session->auth_complete)
{
g_warning("%s", "Attempt to complete incomplete logon.");
return;
return FALSE;
}
// FIXME: Error handling required
// FIXME: If this fails, we need to restart auth! The UI
// does not handle this either
// Attempt to resolve a session, because we can't actually rely on LightDM
// having a default that is valid
//
lightdm_greeter_start_session_sync(
logon_session->greeter,
NULL,
NULL
);
GList* avail_sessions = lightdm_get_sessions();
const gchar* def_session = lightdm_greeter_get_default_session_hint(
logon_session->greeter
);
const gchar* use_session = NULL;
if (!avail_sessions)
{
// FIXME: This string will need localising, though there is no such
// string in Windows (or similar afaik) as this situation does
// not ever occur on Windows
//
g_set_error(
error,
WINTC_GINA_ERROR,
WINTC_GINA_ERROR_NO_SESSIONS,
"%s",
"There are no available sessions on this system. "
"Logon cannot be completed."
);
reset_auth_state(logon_session);
return FALSE;
}
for (GList* iter = avail_sessions; iter; iter = iter->next)
{
LightDMSession* session = (LightDMSession*) iter->data;
if (g_strcmp0(def_session, lightdm_session_get_key(session)) == 0)
{
use_session = def_session;
}
}
// If we didn't find the default session, just use the first one
//
if (use_session == NULL)
{
use_session =
lightdm_session_get_key((LightDMSession*) avail_sessions->data);
}
// Perform the logon attempt
//
gboolean success =
lightdm_greeter_start_session_sync(
logon_session->greeter,
use_session,
error
);
if (!success)
{
reset_auth_state(logon_session);
}
return success;
}
gboolean wintc_gina_logon_session_is_available(
@@ -210,6 +271,18 @@ void wintc_gina_logon_session_try_logon(
);
}
//
// PRIVATE FUNCTIONS
//
static void reset_auth_state(
WinTCGinaLogonSession* logon_session
)
{
logon_session->auth_complete = FALSE;
lightdm_greeter_authenticate(logon_session->greeter, NULL, NULL);
}
//
// CALLBACKS
//
@@ -236,12 +309,11 @@ static void on_greeter_authentication_complete(
);
// If the auth failed, have to restart
// FIXME: Error handling
//
if (!logon_session->auth_complete)
{
// FIXME: Error handling
//
lightdm_greeter_authenticate(greeter, NULL, NULL);
reset_auth_state(logon_session);
}
}