/*
 * Copyright (c) 2001 Markus Friedl.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "includes.h"
RCSID("$OpenBSD: auth-bsdauth.c,v 1.1 2001/05/18 14:13:28 markus Exp $");

#ifdef BSD_AUTH
#include "xmalloc.h"
#include "auth.h"
#include "log.h"

static void *
bsdauth_init_ctx(Authctxt *authctxt)
{
	return authctxt;
}

static int
bsdauth_query(void *ctx, char **name, char **infotxt, 
   u_int *numprompts, char ***prompts, u_int **echo_on)
{
        Authctxt *authctxt = ctx;
        char *challenge = NULL;

        if (authctxt->as != NULL) {
                debug2("bsdauth_query: try reuse session");
                challenge = auth_getitem(authctxt->as, AUTHV_CHALLENGE);
                if (challenge == NULL) {
                        auth_close(authctxt->as);
                        authctxt->as = NULL;
                }
        }

        if (challenge == NULL) {
                debug2("bsdauth_query: new bsd auth session");
                debug3("bsdauth_query: style %s",
		    authctxt->style ? authctxt->style : "<default>");
                authctxt->as = auth_userchallenge(authctxt->user,
		     authctxt->style, "auth-ssh", &challenge);
                if (authctxt->as == NULL)
                        challenge = NULL;
                debug2("bsdauth_query: <%s>", challenge ? challenge : "empty");
        }
        
        if (challenge == NULL)
                return -1;

        *name       = xstrdup("");
        *infotxt    = xstrdup("");
        *numprompts = 1;
        *prompts = xmalloc(*numprompts * sizeof(char*));
        *echo_on = xmalloc(*numprompts * sizeof(u_int));
        (*echo_on)[0] = 0;
        (*prompts)[0] = xstrdup(challenge);

        return 0;
}

static int
bsdauth_respond(void *ctx, u_int numresponses, char **responses)
{
        Authctxt *authctxt = ctx;
        int authok;
        
        if (authctxt->as == 0)
                error("bsdauth_respond: no bsd auth session");

        if (numresponses != 1)
                return -1;

        authok = auth_userresponse(authctxt->as, responses[0], 0);
        authctxt->as = NULL;
        debug3("bsdauth_respond: <%s> = <%d>", responses[0], authok);

        return (authok == 0) ? -1 : 0;
}

static void
bsdauth_free_ctx(void *ctx)
{
        Authctxt *authctxt = ctx;

        if (authctxt && authctxt->as) {
                auth_close(authctxt->as);
                authctxt->as = NULL;
        }
}

KbdintDevice bsdauth_device = {
	"bsdauth",
	bsdauth_init_ctx,
	bsdauth_query,
	bsdauth_respond,
	bsdauth_free_ctx
};
#endif
