Example #1
0
/*
 * skey_authenticate()
 *
 * Used when calling program will allow input of the user's
 * response to the challenge.
 *
 * Returns: 0 success, -1 failure
 *
 */
int
skey_authenticate(char *username)
{
	char pbuf[SKEY_MAX_PW_LEN+1], skeyprompt[SKEY_MAX_CHALLENGE+1];
	struct skey skey;
	int i;

	/* Get the S/Key challenge (may be fake) */
	i = skeychallenge(&skey, username, skeyprompt);
	(void)fprintf(stderr, "%s\nResponse: ", skeyprompt);
	(void)fflush(stderr);

	/* Time out on user input after 2 minutes */
	tgetline(fileno(stdin), pbuf, sizeof(pbuf), 120);
	sevenbit(pbuf);
	(void)rewind(stdin);

	/* Is it a valid response? */
	if (i == 0 && skeyverify(&skey, pbuf) == 0) {
		if (skey.n < 5) {
			(void)fprintf(stderr,
			    "\nWarning! Key initialization needed soon.  (%d logins left)\n",
			    skey.n);
		}
		return (0);
	}
	return (-1);
}
Example #2
0
/*
 * skey_passcheck()
 *
 * Check to see if answer is the correct one to the current
 * challenge.
 *
 * Returns: 0 success, -1 failure
 *
 */
int
skey_passcheck(char *username, char *passwd)
{
	struct skey skey;
	int i;

	i = skeylookup(&skey, username);
	if (i == -1 || i == 1)
		return (-1);

	if (skeyverify(&skey, passwd) == 0)
		return (skey.n);

	return (-1);
}
Example #3
0
int
pw_auth (const char *cipher, const char *user, int reason, const char *input)
{
	char prompt[1024];
	char *clear = NULL;
	const char *cp;
	int retval;

#ifdef	SKEY
	int use_skey = 0;
	char challenge_info[40];
	struct skey skey;
#endif

	/*
	 * There are programs for adding and deleting authentication data.
	 */

	if (reason == PW_ADD || reason == PW_DELETE)
		return 0;

	/*
	 * There are even programs for changing the user name ...
	 */

	if (reason == PW_CHANGE && input != (char *) 0)
		return 0;

	/*
	 * WARNING:
	 *
	 * When we change a password and we are root, we don't prompt.
	 * This is so root can change any password without having to
	 * know it.  This is a policy decision that might have to be
	 * revisited.
	 */

	if (reason == PW_CHANGE && getuid () == 0)
		return 0;

	/*
	 * WARNING:
	 *
	 * When we are logging in a user with no ciphertext password,
	 * we don't prompt for the password or anything.  In reality
	 * the user could just hit <ENTER>, so it doesn't really
	 * matter.
	 */

	if (cipher == (char *) 0 || *cipher == '\0')
		return 0;

#ifdef	SKEY
	/*
	 * If the user has an S/KEY entry show them the pertinent info
	 * and then we can try validating the created cyphertext and the SKEY.
	 * If there is no SKEY information we default to not using SKEY.
	 */

	if (skeychallenge (&skey, user, challenge_info) == 0)
		use_skey = 1;
#endif

	/*
	 * Prompt for the password as required.  FTPD and REXECD both
	 * get the cleartext password for us.
	 */

	if (reason != PW_FTP && reason != PW_REXEC && !input) {
		if (!(cp = getdef_str ("LOGIN_STRING")))
			cp = _(PROMPT);
#ifdef	SKEY
		if (use_skey)
			printf ("[%s]\n", challenge_info);
#endif

		snprintf (prompt, sizeof prompt, cp, user);
		clear = getpass (prompt);
		if (!clear) {
			static char c[1];

			c[0] = '\0';
			clear = c;
		}
		input = clear;
	}

	/*
	 * Convert the cleartext password into a ciphertext string.
	 * If the two match, the return value will be zero, which is
	 * SUCCESS. Otherwise we see if SKEY is being used and check
	 * the results there as well.
	 */

	retval = strcmp (pw_encrypt (input, cipher), cipher);

#ifdef  SKEY
	/*
	 * If (1) The password fails to match, and
	 * (2) The password is empty and
	 * (3) We are using OPIE or S/Key, then
	 * ...Re-prompt, with echo on.
	 * -- AR 8/22/1999
	 */
	if (retval && !input[0] && (use_skey)) {
		strncat (prompt, "(Echo on) ",
			 (sizeof (prompt) - strlen (prompt)));
		clear = getpass_with_echo (prompt);
		if (!clear) {
			static char c[1];

			c[0] = '\0';
			clear = c;
		}
		input = clear;
	}

	if (retval && use_skey) {
		int passcheck = -1;

		if (skeyverify (&skey, input) == 0)
			passcheck = skey.n;
		if (passcheck > 0)
			retval = 0;
	}
#endif

	/*
	 * Things like RADIUS authentication may need the password -
	 * if the external variable wipe_clear_pass is zero, we will
	 * not wipe it (the caller should wipe clear_pass when it is
	 * no longer needed).  --marekm
	 */

	clear_pass = clear;
	if (wipe_clear_pass && clear && *clear)
		strzero (clear);
	return retval;
}