--- a/hasl/haslcontext.h Fri Jul 14 01:51:47 2023 -0500
+++ b/hasl/haslcontext.h Fri Jul 14 01:54:10 2023 -0500
@@ -25,6 +25,76 @@
#define HASL_CONTEXT_DOMAIN (g_quark_from_static_string("hasl-context"))
+ * The context holds all of the data that the client knows about for + * authentication. The [class@Mechanism]s use this data to authenticate. + * A client can limit which mechanisms the context will use with + * [method@Context.set_allowed_mechanisms]. + * The context also keeps track of which mechanisms have been tried and will + * mark one as failed when [method@Context.next] is called. The client then + * can call [method@Context.get_current_mechanism] and repeat until + * successfully authenticated or all mechanisms have been exhausted. + * A simple example is found below. + * // After you connect to the server, you can create your context and start + * // the authentication process. + * HaslContext *context = NULL; + * char *mechanism = NULL; + * context = hasl_context_new(); + * hasl_context_set_username(context, "alice"); + * hasl_context_set_password(context, "hunter2"); + * hasl_context_set_allowed_mechanisms(context, "PLAIN,EXTERNAL"); + * mechanism = hasl_context_next(context); + * // Attempt your authentication using the mechanism name stored in + * // In your receive handler you can now pass the data into hasl_context_step. + * HaslMechanismResult res; + * GError *error = NULL; + * guint8 *client_out = NULL; + * gsize client_out_length = 0; + * // Note that if client_out is not NULL it is your responsibility to free it. + * res = hasl_context_step(context, server_input, server_input_length, + * &client_out, &client_out_length, &error); + * if(res == HASL_MECHANISM_RESULT_ERROR) { + * char *mechanism = NULL; + * // Possibly handle error. + * // Tell the context to try the next mechanism. + * mechanism = hasl_context_next(context); + * // If you don't have any more mechanisms, authentication failed. + * if(mechanism == NULL) { + * // Terminate connection. + * // Tell the server you would like to try another mechanism with the + * // value stored in mechanism. + * } else if(res == HASL_MECHANISM_RESULT_SUCCESS) { + * // Authentication complete. + * } else if(res == HASL_MECHANISM_CONTINUE) { + * // Otherwise send client_out to the server. #define HASL_TYPE_CONTEXT (hasl_context_get_type())
G_DECLARE_FINAL_TYPE(HaslContext, hasl_context, HASL, CONTEXT, GObject)
--- a/hasl/haslmechanism.h Fri Jul 14 01:51:47 2023 -0500
+++ b/hasl/haslmechanism.h Fri Jul 14 01:54:10 2023 -0500
@@ -23,6 +23,17 @@
+ * The base class for all mechanisms. + * All mechanisms need to implement [method@Mechanism.step] but may optionally + * implement [method@Mechanism.possible]. #define HASL_TYPE_MECHANISM (hasl_mechanism_get_type())
G_DECLARE_DERIVABLE_TYPE(HaslMechanism, hasl_mechanism, HASL, MECHANISM,
--- a/hasl/haslmechanismexternal.h Fri Jul 14 01:51:47 2023 -0500
+++ b/hasl/haslmechanismexternal.h Fri Jul 14 01:54:10 2023 -0500
@@ -26,6 +26,21 @@
+ * HaslMechanismExternal: + * Implements the SASL EXTERNAL mechanism per + * [RFC 4422](https://www.rfc-editor.org/rfc/rfc4422). + * If [property@Context:authzid] is set, it will be used. + * There are multiple ways that a server could externally authenticate a user, + * so there is no dependency on [property@Context:tls] as the server could be + * authenticating via IP addresses for example. #define HASL_TYPE_MECHANISM_EXTERNAL (hasl_mechanism_external_get_type())
G_DECLARE_FINAL_TYPE(HaslMechanismExternal, hasl_mechanism_external, HASL,
MECHANISM_EXTERNAL, HaslMechanism)