summaryrefslogtreecommitdiff
path: root/contrib/opie/libopie/generator.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/opie/libopie/generator.c')
-rw-r--r--contrib/opie/libopie/generator.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/contrib/opie/libopie/generator.c b/contrib/opie/libopie/generator.c
new file mode 100644
index 0000000000000..ccd67c7532f46
--- /dev/null
+++ b/contrib/opie/libopie/generator.c
@@ -0,0 +1,110 @@
+/* generator.c: The opiegenerator() library function.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Use _opieparsechallenge(). ifdef
+ around string.h. Output hex responses by default, output
+ OTP re-init extended responses (same secret) if sequence
+ number falls below 10.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Bug fixes.
+ Created at NRL for OPIE 2.2.
+*/
+
+#include "opie_cfg.h"
+#if HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#include "opie.h"
+
+static char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
+
+int opiegenerator FUNCTION((buffer, secret, response), char *buffer AND char *secret AND char *response)
+{
+ int algorithm;
+ int sequence;
+ char *seed;
+ char key[8];
+ int i;
+
+ if (!(buffer = strstr(buffer, "otp-")))
+ return 1;
+
+ buffer += 4;
+
+ if (_opieparsechallenge(buffer, &algorithm, &sequence, &seed))
+ return 1;
+
+ if ((sequence < 2) || (sequence > 9999))
+ return 1;
+
+ if (opiepasscheck(secret))
+ return -2;
+
+ if (i = opiekeycrunch(algorithm, key, seed, secret))
+ return i;
+
+ if (sequence < 10) {
+ char newseed[OPIE_SEED_MAX + 1];
+ char newkey[8], cko[8], ckn[8], ckxor[8], cv[8];
+ char *c;
+ char buf[OPIE_SEED_MAX + 48 + 1];
+
+ if (opienewseed(strcpy(newseed, seed)) < 0)
+ return -1;
+
+ if (opiekeycrunch(algorithm, newkey, newseed, secret))
+ return -1;
+
+ for (i = 0; i < 499; i++)
+ opiehash(newkey, algorithm);
+
+ if (opiekeycrunch(algorithm | 0x10, cko, seed, secret))
+ return -1;
+
+ if (opiekeycrunch(algorithm | 0x10, ckn, newseed, secret))
+ return -1;
+
+ for (i = 0; i < 8; i++)
+ ckxor[i] = cko[i] ^ ckn[i];
+
+ strcpy(response, "init:");
+ strcat(response, opiebtoh(buf, key));
+ sprintf(buf, ":%s 499 %s:", algids[algorithm], newseed);
+ strcat(response, buf);
+ strcat(response, opiebtoh(buf, newkey));
+ strcat(response, ":");
+ strcat(response, opiebtoh(buf, ckxor));
+ strcat(response, ":");
+
+ c = buf;
+ memcpy(c, ckn, sizeof(ckn)); c += sizeof(ckn);
+ memcpy(c, key, sizeof(key)); c += sizeof(key);
+#ifdef HAVE_ANSISPRINTF
+ c += sprintf(c, "%s 499 %s", algids[algorithm], newseed);
+#else /* HAVE_ANSISPRINTF */
+ sprintf(c, "%s 499 %s", algids[algorithm], newseed);
+ while(*c) c++;
+#endif /* HAVE_ANSISPRINTF */
+ memcpy(c, newkey, sizeof(newkey)); c += sizeof(newkey);
+ memcpy(c, ckxor, sizeof(ckxor)); c += sizeof(ckxor);
+ memcpy(c, ckn, sizeof(ckn)); c += sizeof(ckn);
+ opiehashlen(algorithm, buf, cv, (unsigned int)c - (unsigned int)buf);
+
+ strcat(response, opiebtoh(buf, cv));
+ } else {
+ while (sequence-- != 0)
+ opiehash(key, algorithm);
+
+ opiebtoh(response, key);
+ }
+
+ return 0;
+}