forked from Telodendria/Telodendria
144 lines
5.8 KiB
C
144 lines
5.8 KiB
C
/*
|
|
* Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net>
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person
|
|
* obtaining a copy of this software and associated documentation files
|
|
* (the "Software"), to deal in the Software without restriction,
|
|
* including without limitation the rights to use, copy, modify, merge,
|
|
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
* and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
#ifndef TELODENDRIA_UIA_H
|
|
#define TELODENDRIA_UIA_H
|
|
|
|
/***
|
|
* @Nm Uia
|
|
* @Nd User Interactive Authentication.
|
|
* @Dd April 28 2023
|
|
* @Xr User Db Cron
|
|
*
|
|
* .Nm
|
|
* takes care of all the logic for performing user interactive
|
|
* authentication as defined by the Matrix specification. API endpoints
|
|
* that require authentication via user interactive authentication
|
|
* build up flows and add any necessary parameters, and pass them all
|
|
* into
|
|
* .Fn UiaComplete .
|
|
* The goal is to make it easy for the numerous API endpoints that
|
|
* utilize this authentication mechanism to implement it.
|
|
*/
|
|
|
|
#include <Array.h>
|
|
#include <HashMap.h>
|
|
#include <HttpServer.h>
|
|
#include <Matrix.h>
|
|
|
|
/**
|
|
* An opaque structure that represents a single stage, which consists
|
|
* of the type and a JSON object that contains implementation-specific
|
|
* parameters for completing the stage.
|
|
*/
|
|
typedef struct UiaStage UiaStage;
|
|
|
|
/**
|
|
* Build a single stage with the type and a JSON object of parameters
|
|
* the client may require to complete it. Consult the Matrix
|
|
* specification for the valid types.
|
|
*/
|
|
extern UiaStage * UiaStageBuild(char *, HashMap *);
|
|
|
|
/**
|
|
* Build a flow that consists only of a dummy stage. This is useful
|
|
* when an endpoint is required by the specification to use user
|
|
* interactive authentication, but doesn't want to actually require
|
|
* the user to do anything. Since the dummy flow is a fairly common
|
|
* flow, it seemed sensible to have a function for it. Other flows are
|
|
* built manually by the caller that that wishes to perform user
|
|
* interactive authentication.
|
|
*/
|
|
extern Array * UiaDummyFlow(void);
|
|
|
|
/**
|
|
* This function should be called periodically to purge old sessions.
|
|
* Sessions are only valid for a few minutes after their last access.
|
|
* After that, they should be purged so that the database doesn't fill
|
|
* up with old session files. This function is specifically designed
|
|
* to be called via the Cron API.
|
|
*/
|
|
extern void UiaCleanup(MatrixHttpHandlerArgs *);
|
|
|
|
/**
|
|
* Validate an auth object and maintain session state to track the
|
|
* progress of a client through user interactive authentication flows.
|
|
* The idea is that an API endpoint will not progress until user
|
|
* interactive authentication has succeeded.
|
|
* .Pp
|
|
* This function does the bulk of the work for user interactive
|
|
* authentication. It takes many parameters:
|
|
* .Bl -bullet -offset indent
|
|
* .It
|
|
* An array of arrays of stages. Stages should be created with
|
|
* .Fn UiaStageBuild
|
|
* and then put into an array to create a flow. Those flows should then
|
|
* be put into an array and passed as this parameter. It is important
|
|
* to note here that because of the loose typing of the Array API, it
|
|
* is very easy to make mistakes here; if you are implementing a new
|
|
* endpoint that requires user interactive authentication, it is best
|
|
* to refer to the source code of an existing endpoint to get a better
|
|
* idea of how it works.
|
|
* .It
|
|
* An HTTP server context. This is required to set the response headers
|
|
* in the even of an error.
|
|
* .It
|
|
* The database where user interactive authentication sessions are
|
|
* persisted.
|
|
* .It
|
|
* The JSON request body that contains the client's auth object, which
|
|
* will be read, parsed, and handled as appropriate.
|
|
* .It
|
|
* A pointer to a pointer where a JSON response can be placed if
|
|
* necessary. If this function encounters a client error, such as a
|
|
* failure to authenticate, or outstanding stages that have not yet
|
|
* been completed, it will place a JSON response here that is expected
|
|
* to be returned to the client. This response will include a
|
|
* description of all the flows, stages, and the stage parameters.
|
|
* .It
|
|
* A valid configuration structure, because a few values are read from
|
|
* the configuration during certain stages of authentication.
|
|
* .El
|
|
* .Pp
|
|
* This function returns an integer value less than zero if it
|
|
* experiences an internal failure, such as a failure to allocate
|
|
* memory memory, or a corrupted database. It returns 0 if the client
|
|
* has remaining stages to complete, including the current stage if
|
|
* that one did not complete successfully. In this case, this function
|
|
* will set the proper response headers and the passed response
|
|
* pointer, so the caller should immediately return the response to
|
|
* the client. This function returns 1 if and only if the client has
|
|
* successfully completed all stages. Only in this latter case shall
|
|
* the caller proceed with its logic.
|
|
*/
|
|
extern int
|
|
UiaComplete(Array *, HttpServerContext *, Db *, HashMap *, HashMap **, Config *);
|
|
|
|
/**
|
|
* Free an array of flows, as described above. Even though the caller
|
|
* constructs this array, it is convenient to free it in its
|
|
* entirety in a single function call.
|
|
*/
|
|
extern void UiaFlowsFree(Array *);
|
|
|
|
#endif
|