122347Spst/* challenge.c: The opiechallenge() library function.
222347Spst
329964Sache%%% portions-copyright-cmetz-96
492914SmarkmPortions of this software are Copyright 1996-1999 by Craig Metz, All Rights
522347SpstReserved. The Inner Net License Version 2 applies to these portions of
622347Spstthe software.
722347SpstYou should have received a copy of the license with this software. If
822347Spstyou didn't get a copy, you may request one from <license@inner.net>.
922347Spst
1022347SpstPortions of this software are Copyright 1995 by Randall Atkinson and Dan
1122347SpstMcDonald, All Rights Reserved. All Rights under this copyright are assigned
1222347Spstto the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
1322347SpstLicense Agreement applies to this software.
1422347Spst
1522347Spst        History:
1622347Spst
1759118Skris	Modified by cmetz for OPIE 2.32. Added extended response set
1859118Skris		identifier to the challenge.
1922347Spst	Modified by cmetz for OPIE 2.3. Use opie_ prefix. Send debug info to
2022347Spst		syslog. Add sha plumbing.
2122347Spst	Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
2222347Spst        Created at NRL for OPIE 2.2 from opiesubr2.c
2389766Sache
2489766Sache$FreeBSD: releng/10.2/contrib/opie/libopie/challenge.c 270120 2014-08-18 02:13:45Z ache $
2589766Sache
2622347Spst*/
2722347Spst#include "opie_cfg.h"
2822347Spst#include <stdio.h>
2922347Spst#include <string.h>
3022347Spst#if DEBUG
3122347Spst#include <syslog.h>
3222347Spst#endif /* DEBUG */
3322347Spst#include "opie.h"
3422347Spst
3522347Spst/* Return an OTP challenge string for user 'name'.
3622347Spst
3722347Spst   The return values are:
3822347Spst
3922347Spst   0  = All good
4022347Spst   -1 = Low-level error (file, memory, I/O, etc.)
4122347Spst   1  = High-level error (user not found or locked)
4222347Spst
4322347Spst   This function MUST eventually be followed by an opieverify() to release
4422347Spst   the user lock and file handles.
4522347Spst
4622347Spst   This function will give you a blanked-out state block if it returns a
4722347Spst   nonzero status. Even though it returns a non-zero status and a blank
4822347Spst   state block, you still MUST call opieverify() to clear the lock and
4922347Spst   any internal state (the latter condition is not actually used yet).
5022347Spst*/
5122347Spst
5222347Spststatic char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
5322347Spst
5422347Spstint opiechallenge FUNCTION((mp, name, ss), struct opie *mp AND char *name AND char *ss)
5522347Spst{
5622347Spst  int rval = -1;
5722347Spst
5822347Spst  rval = opielookup(mp, name);
5922347Spst#if DEBUG
6022347Spst  if (rval) syslog(LOG_DEBUG, "opiechallenge: opielookup(mp, name=%s) returned %d", name, rval);
6122347Spst#endif /* DEBUG */
6222347Spst
6322347Spst  if (!rval) {
6422347Spst    rval = opielock(name);
6522347Spst#if DEBUG
6622347Spst    if (rval) syslog(LOG_DEBUG, "opiechallenge: opielock(name=%s) returned %d", name, rval);
6722347Spst#endif /* DEBUG */
6822347Spst  }
6922347Spst
7092914Smarkm  if (rval ||
71270120Sache    (snprintf(ss, OPIE_CHALLENGE_MAX+1, "otp-%s %d %s ext", algids[MDX], mp->opie_n - 1, mp->opie_seed) >= OPIE_CHALLENGE_MAX+1)) {
72270120Sache    if (!rval)
73270120Sache      rval = 1;
7422347Spst    opierandomchallenge(ss);
7522347Spst    memset(mp, 0, sizeof(*mp));
7692914Smarkm  }
7722347Spst
7822347Spst  return rval;
7922347Spst}
80