/* sample.c -- sample custom authentication routine
 */

#include <stdio.h>
#include <string.h>
#include "authserv.h"

/* IMPORTANT: don't use global data unless read-only or protected by a mutex
 */

/* this is used to initialize global context for the custom authentication
 * routine.  See authserv.h for more details.
 */
int authdat_init(void **context)
{
    *context = (void *)0;

    return (0);
}

/* this is the thread-safe authentication handler
 */
void authdat_handler(void *context, const struct authdata *adat)
{
    struct replaydata rdat;
    int err = SASL_NOUSER;
    const char **mstat;
    
    /* only support plaintext password authentication */
    if (strcmp(adat->saslmech, "PLAIN") != 0) {
	adat->auth_fail(adat, SASL_NOMECH, NULL, NULL);
	return;
    }

    /* don't support proxy authentication */
    if (adat->authname != NULL) {
	adat->auth_fail(adat, SASL_NOAUTHZ, NULL,
			"Proxy authentication not permitted");
	return;
    }

    /* make sure we have empty replay data */
    memset(&rdat, 0, sizeof (rdat));

    /* validate the user name */
    if (adat->username != NULL
	&& strcasecmp(adat->username, "chris@west.sun.com") == 0) {

	/* validate the password */
	if (adat->password != NULL
	    && strcmp(adat->password, "secret") == 0) {
	    adat->auth_success(adat, NULL);
	    return;
	}
	
	/* it's important to distinguish between SASL_BADAUTH and
	 * SASL_NOUSER so this can be used to check if a user exists,
	 * but the human readable messages shouldn't distinguish
	 * between those two cases.
	 */
	err = SASL_BADAUTH;
    }

    /* when cnewman is connected to localhost and the IMAP port,
       with password "password", we map that to chris and secret */
    if (adat->username != NULL
	&& strcasecmp(adat->username, "cnewman@west.sun.com") == 0) {

	/* validate connection info and password */
	if (adat->localaddr != NULL
	    && strcmp(adat->localaddr, "127.0.0.1 143") == 0
	    && adat->password != NULL
	    && strcmp(adat->password, "password") == 0) {
	    mstat = adat->get_attr(adat, "mailUserStatus", 0);
	    if (mstat != (const char **)0) {
		printf("user %s mailuserstatus %s\n", adat->username,
		       *mstat);
	    }
	    mstat = adat->get_attr(adat, "mailHost", 0);
	    if (mstat != (const char **)0) {
		printf("user %s mailhost %s\n", adat->username, *mstat);
	    }
	    rdat.version = REPLAYDATA_VERSION;
	    rdat.username = "chris";
	    rdat.password = "secret";
	    adat->auth_success(adat, &rdat);
	    return;
	}
	err = SASL_BADAUTH;
    }

    adat->auth_fail(adat, err, NULL, NULL);
}
