Monday, November 22, 2021

Alter user during authentication using DSAPI

I had a need to alter user during web-authentication process on fly (skipping password validation). Initially the task looked impossible but I managed to solve it using DSAPI filter.
Though the solution looks quite unsecure it could be very useful in some cases (by high level administrators) who needs to 'signin' as a user in their organization to do some checks.

Here are few most important snippets how to do that:

1. Subscribe for the event kFilterAuthenticate

That means that our dsapi filter only intercepts one specific event: kFilterAuthenticate), as there are other 10-15 other events which we do not wanna touch.

EXPORT unsigned int FilterInit(FilterInitData* filterInitData) {
	STATUS   error = NOERROR;

	filterInitData->appFilterVersion = kInterfaceVersion;
	filterInitData->eventFlags = kFilterAuthenticate;

	// other logic
	// ...

2. Catch the authenticate event and process it

Get our event and associate it with a C function

EXPORT unsigned int HttpFilterProc(FilterContext* context, unsigned int eventType, void* eventData) {
	/* Include only those events we want to handle */
	switch (eventType) {
	case kFilterAuthenticate:
		return Authenticate(context, (FilterAuthenticate *) eventData);

   return kFilterNotHandled;
}	// end HttpFilterProc

3. Finally set a desired username

Below I only show the key moment - replace user name with another name

unsigned int Authenticate(FilterContext* context, FilterAuthenticate* authData) {
	/* logic that calculate username  */
    // .................................
    // char[] fullName = "CN=T5 Tester5/O=DmytroDev";
    // .................................

	/* Copy the canonical name for this user that dsapi requires.  */
	strncpy ((char *)authData->authName, fullName, authData->authNameSize);
	authData->authNameSize = strlen(alterAuthToken);
	authData->authType = kAuthenticBasic;
	authData->foundInCache = TRUE;

	return kFilterHandledEvent;

In order to improve security I have built an application on Domino side that generates tokens which have to be set in cookie and then DSAPI filter reads the cookie and get username from database. Tokens could be generated only by certain people are will be deleted by schedule agents after some time.

On the screenshot below you can see that I signed in as a "T5 Tester5" using my custom token AlterAuthToken while I am Anonymous.

No comments :