generator.c revision 59121
1/* generator.c: The opiegenerator() library function.
2
3%%% portions-copyright-cmetz-96
4Portions of this software are Copyright 1996-1998 by Craig Metz, All Rights
5Reserved. The Inner Net License Version 2 applies to these portions of
6the software.
7You should have received a copy of the license with this software. If
8you didn't get a copy, you may request one from <license@inner.net>.
9
10        History:
11
12	Modified by cmetz for OPIE 2.32. If secret=NULL, always return
13		as if opieauto returned "get the secret". Renamed
14		_opieparsechallenge() to __opieparsechallenge(). Check
15		challenge for extended response support and don't send
16		an init-hex response if extended response support isn't
17		indicated in the challenge.
18	Modified by cmetz for OPIE 2.31. Renamed "init" to "init-hex".
19		Removed active attack protection support. Fixed fairly
20		bug in how init response was computed (i.e., dead wrong).
21	Modified by cmetz for OPIE 2.3. Use _opieparsechallenge(). ifdef
22		around string.h. Output hex responses by default, output
23		OTP re-init extended responses (same secret) if sequence
24		number falls below 10.
25	Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
26		Bug fixes.
27	Created at NRL for OPIE 2.2.
28
29$FreeBSD: head/contrib/opie/libopie/generator.c 59121 2000-04-10 11:18:54Z kris $
30*/
31
32#include "opie_cfg.h"
33#if HAVE_STRING_H
34#include <string.h>
35#endif /* HAVE_STRING_H */
36#include "opie.h"
37
38static char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
39
40int opiegenerator FUNCTION((buffer, secret, response), char *buffer AND char *secret AND char *response)
41{
42  int algorithm;
43  int sequence;
44  char *seed;
45  char key[8];
46  int i;
47  int exts;
48
49  if (!(buffer = strstr(buffer, "otp-")))
50    return 1;
51
52  buffer += 4;
53
54  if (__opieparsechallenge(buffer, &algorithm, &sequence, &seed, &exts))
55    return 1;
56
57  if ((sequence < 2) || (sequence > 9999))
58    return 1;
59
60  if (!secret[0])
61   return 2;
62
63  if (opiepasscheck(secret))
64    return -2;
65
66  if (i = opiekeycrunch(algorithm, key, seed, secret))
67    return i;
68
69  if (sequence < 10) {
70    if (!(exts & 1))
71      return 1;
72
73    {
74    char newseed[OPIE_SEED_MAX + 1];
75    char newkey[8];
76    char *c;
77    char buf[OPIE_SEED_MAX + 48 + 1];
78
79    while (sequence-- != 0)
80      opiehash(key, algorithm);
81
82    if (opienewseed(strcpy(newseed, seed)) < 0)
83      return -1;
84
85    if (opiekeycrunch(algorithm, newkey, newseed, secret))
86      return -1;
87
88    for (i = 0; i < 499; i++)
89      opiehash(newkey, algorithm);
90
91    strcpy(response, "init-hex:");
92    strcat(response, opiebtoh(buf, key));
93    sprintf(buf, ":%s 499 %s:", algids[algorithm], newseed);
94    strcat(response, buf);
95    strcat(response, opiebtoh(buf, newkey));
96    };
97  } else {
98    while (sequence-- != 0)
99      opiehash(key, algorithm);
100
101    opiebtoh(response, key);
102  }
103
104  return 0;
105}
106