/* Verify user's identity using a password like that in NET/ROM */
/* Additional protection built in using an algorithm by PE1HZG */

#include "global.h"
#include "password.h"

#ifdef MSC
#include <time.h>
#endif

char *
gen_challenge (pw)
register struct password *pw;
{
    int row,cnt,num,chk;
    int pswlen;
    int retries;
    static char result[P_ROWS * P_NUMS * 4 + 3];
    static int initialize = 1;

    if (initialize){
	srand((int) time(NULL));	/* seed the random generator */
	initialize = 0;
    }

    if ((pswlen = strlen(pw->paswrd)) > 999)
	pswlen = 999;

    pw->okay = 0;			/* password not okay for now */
    result[0] = '\0';			/* clear result */

    for (row = 0; row < P_ROWS; row++) {
	for (cnt = 0; cnt < P_NUMS; cnt++) {
	    retries = 100;
	    do {
		do
		    num = rand() % pswlen; /* 0 .. len-1 */
		while (pw->paswrd[num] == ' '); /* ignore when space in passwd */

		for (chk = 0; chk < cnt; chk++) { /* no duplicates please */
		    if (pw->chall[row][chk] == num)
			break;
		}
	    } while (cnt != chk && retries--);

	    pw->chall[row][cnt] = num;
	    sprintf(result + strlen(result)," %d",pw->chall[row][cnt] + 1);
	}

	strcat(result,",");
    }

    result[strlen(result) - 1] = '\0';	/* chop off last comma */
    return (result + 1);		/* skip first space */
}

int
ok_password (pw,input)
register struct password *pw;
char *input;
{
    int row,cnt;

    for (row = 0; row < P_ROWS; row++) {
	for (cnt = 0; cnt < P_NUMS; cnt++) {
	    if (pw->paswrd[pw->chall[row][cnt]] != input[cnt])
		break;
	}
	if (cnt == P_NUMS)
	    return (pw->okay = 1);	/* it is correct! */
    }
    return 0;				/* sorry, no match */
}
