src/authinfo.c

/* [<][>]
[^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following functions.
  1. get_authenticator
  2. CMDauthinfo
  3. authinfo_ok_cmd
  4. authinfo_str_to_type
  5. authinfo_get
  6. authinfo_got_user

/* $Id: authinfo.c,v 1.5 2002/03/24 13:33:57 proff Exp $
 * $Copyright$
 */

/*
 * AUTHINFO support; we have a generic layer here so we can pass authinfo
 * commands off to any authenticator we like (see authinfo.h).
 */

#include "nglobal.h"
#include "acc.h"
#include "reg.h"

#include "authinfo.h"

/*
 * what authenticators do we include support for ?
 */
#ifdef AUTHINFO_LDAP
#include "authinfo_ldap.h"
#endif
#ifdef AUTHINFO_PASSWD
#include "authinfo_passwd.h"
#endif
#ifdef AUTHINFO_PIPE
#include "authinfo_pipe.h"
#endif
#ifdef AUTHINFO_RADIUS
#include "authinfo_radius.h"
#endif
#ifdef AUTHINFO_PAM
#include "authinfo_pam.h"
#endif

static authenticator *get_authenticator(char *a)
/* [<][>][^][v][top][bottom][index][help] */
{

#ifdef AUTHINFO_LDAP
        if (strCaseEq(a, "ldap"))
                return &ldap_authenticator;
#endif
#ifdef AUTHINFO_PASSWD
        if (strCaseEq(a, "passwd"))
                return &passwd_authenticator;
#endif
#ifdef AUTHINFO_RADIUS
        if (strCaseEq(a, "radius"))
                return &radius_authenticator;
#endif
#ifdef AUTHINFO_PIPE
        if (strCaseEq(a, "pipe"))
                return &pipe_authenticator;
#endif
#ifdef AUTHINFO_PAM
        if (strCaseEq(a, "pam"))
                return &pam_authenticator;
#endif
        /* XXX */
        return NULL;
}

EXPORT bool CMDauthinfo (char *buf)
/* [<][>][^][v][top][bottom][index][help] */
{
        char cmd[32]="", val[501]="";
        authenticator *authp;

        sscanf(buf, "%*s%*[\r\b\t ]%31[^\r\n\t ]%*[\r\n\t ]%480[^\r\n]", cmd, val);
        if (cmd[0] == '\0')
          {
                emitrn("350 Continue with authorization sequence"); 
                return FALSE;
          }

        if (ConnectAuth->authinfo && ConnectAuth->authinfo->authenticator)
                authp = ConnectAuth->authinfo->authenticator;
        else {
                /* if there is no auth; accept it anyway */
                emitf("%d Authentication accepted\r\n", NNTP_AUTH_OK_VAL);
                return (TRUE);
        }

        if (strCaseEq(cmd, "user")) {
                AuthState = user;
                return (authp->authinfo_user(val));
        } else if (strCaseEq(cmd, "pass")) {
                if (authp->authinfo_pass(val)) {
                        log(("Successful AUTHINFO PASS for %s", authinfo_user));
                        AuthState = valid;
                        return TRUE;
                }
                log(("Unsuccessful AUTHINFO PASS for %s", authinfo_user));
                AuthState = none;
                return FALSE;
#ifdef notyet
        } else if (strCaseEq(cmd, "sasl")) {
                if (authp->authinfo_sasl(val)) {
                        /* XXX ??? XXX */
                }
#endif
        }
        emitrn ("501 AUTHINFO PASS or AUTHINFO USER");
        return FALSE;
}

EXPORT bool authinfo_ok_cmd(int val)
/* [<][>][^][v][top][bottom][index][help] */
{

        if (val == c_authinfo || val == c_quit || val == c_help)
                return TRUE;

        return (AuthState == valid);
}

static int authinfo_str_to_type(const char *str)
/* [<][>][^][v][top][bottom][index][help] */
{
        if (strCaseEq(str, "none"))
                return (AUTHINFO_NONE);
        else
        if (strCaseEq(str, "userpass"))
                return (AUTHINFO_USERPASS);
        else
#ifdef notyet
        if (strCaseEq(str, "sasl"))
                return (AUTHINFO_SASL);
        else
#endif
        return (AUTHINFO_UNKNOWN);
}

EXPORT struct authinfo *authinfo_get(char *f, char *perm)
/* [<][>][^][v][top][bottom][index][help] */
{
        struct authinfo *ai;
        char *s;

        ai = Scalloc (1, sizeof *ai);
        ai->type = authinfo_str_to_type(con->authinfoDefaultType);
        ai->authenticator = get_authenticator(con->authinfoDefaultSource);

        if (perm == NULL || *perm == '\0')
                return (ai);

        /* can't use strtok(3) here as our caller is already using it ... */
        if (*perm != '=')
                loge (("bad access control in %s: auth or auth=arg;arg;", f));
        perm++;

        do {
                s = strchr(perm, ';');
                if (s != NULL)
                        *s++ = '\0';
                if (strCaseEq(perm, "user/pass") ||
                    strCaseEq(perm, "userpass"))
                        ai->type = AUTHINFO_USERPASS;
                else
                if (strCaseEq(perm, "sasl"))
                        ai->type = AUTHINFO_SASL;
#ifdef AUTHINFO_LDAP
                else
                if (strCaseEq(perm, "ldap"))
                        ai->authenticator = &ldap_authenticator;
#endif
#ifdef AUTHINFO_PASSWD
                else
                if (strCaseEq(perm, "passwd"))
                        ai->authenticator = &passwd_authenticator;
#endif
#ifdef AUTHINFO_PIPE
                else
                if (strCaseEq(perm, "pipe"))
                        ai->authenticator = &pipe_authenticator;
#endif
#ifdef AUTHINFO_RADIUS
                else
                if (strCaseEq(perm, "radius"))
                        ai->authenticator = &radius_authenticator;
#endif
#ifdef AUTHINFO_PAM
                else
                if (strCaseEq(perm, "pam"))
                        ai->authenticator = &pam_authenticator;
#endif
        } while ((perm = s));
        return (ai);
}

/*
 * the generic `got_user' routine; so far both the ldap & passwd code
 * use this.
 */
EXPORT char *authinfo_user = NULL;

EXPORT int authinfo_got_user(char *val)
/* [<][>][^][v][top][bottom][index][help] */
{
        if (authinfo_user)
                free (authinfo_user);
        authinfo_user = (char *)Smalloc(strlen(val) + 1);
        strcpy(authinfo_user, val);
        emitf("%d PASS required for [%s]\r\n", NNTP_AUTH_NEXT_VAL, authinfo_user);
        return TRUE;
}

/* [<][>][^][v][top][bottom][index][help] */