/*
 * snk_getpass
 *
 * SNK "getpass" function for logdaemon
 *
 * Written by William LeFebvre, Argonne National Laboratory
 *
 * Patterned after skey_getpass.c by Wietse Venema
 */

#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <termios.h>
#include <pwd.h>
#include <stdlib.h>

#include "snk.h"

/* Strip trailing cr/lf from a line of text */
void
rip(buf)
char *buf;
{
	char *cp;

	if((cp = strchr(buf,'\r')) != NULL)
		*cp = '\0';

	if((cp = strchr(buf,'\n')) != NULL)
		*cp = '\0';
}

static struct termios saved_ttymode;

/* restore - restore terminal modes when user aborts command */

static void restore_ttymode()
{
    tcsetattr(0, TCSANOW, &saved_ttymode);
    exit(1);
}

/* char *snk_getpass(char *prompt, struct passwd *pwd, int pwok)
 *	Prompt for and read a password for the user described in "pwd".
 *	The password entered by the user is returned.
 */

char   *snk_getpass(prompt, pwd, pwok)
char   *prompt;
struct passwd *pwd;
int     pwok;
{
    static char buf[128];
    void   rip();
    struct termios noecho_ttymode;
    char   *username = pwd ? pwd->pw_name : "nope";
    int    echo_input = 0;
    int    no_sc;
    struct scent sc;
    void   (*oldsig) ();    /* !!! */

    /* do first-stage lookup to see if this user has a SNK card assigned */
    if ((no_sc = getscent(&sc, username)) == 0)
    {
	/* write an appropriate SNK challenge prompt */
	printf("SNK Challenge \"%s\"", snk_challenge());
	if (!pwok)
	{
	    printf(" (SNK response required - echo on)");
	    echo_input = 1;
	}
	putchar('\n');
    }
    else
    {
	/* put out appropriate warning if !pwok */
	if (!pwok)
	{
	    fputs("SNK response required.\n", stdout);
	}
    }

    /* write the actual password prompt */
    fputs(prompt, stdout);
    fflush(stdout);

    if (pwok || no_sc)
    {
	/* turn off echo only if a regular password is okay */
	/* Save current input modes and turn echo off. */
	tcgetattr(0, &saved_ttymode);
	if ((oldsig = signal(SIGINT, SIG_IGN)) != SIG_IGN)
	    signal(SIGINT, restore_ttymode);
	tcgetattr(0, &noecho_ttymode);
	noecho_ttymode.c_lflag &= ~ECHO;
	tcsetattr(0, TCSANOW, &noecho_ttymode);

	/* Read password. */
	buf[0] = 0;
	fgets(buf, sizeof(buf), stdin);
	rip(buf);

	/* Restore previous input modes. */
	tcsetattr(0, TCSANOW, &saved_ttymode);
	if (oldsig != SIG_IGN)
	    signal(SIGINT, oldsig);

	/* turn on echo when first response was null,
	   but only if they have a SNK card */
	if (feof(stdin) == 0 && buf[0] == 0 && !no_sc)
	{
	    fputs(" (turning echo on)\n", stdout);
	    fputs(prompt, stdout);
	    fflush(stdout);
	    echo_input = 1;
	}
	else
	{
	    putchar('\n');
	}
    }

    /* Give SNK users a chance to do it with echo on. */
    if (echo_input)
    {
	fgets(buf, sizeof(buf), stdin);
	rip(buf);
    }

    return (buf);
}

