diff options
Diffstat (limited to 'contrib/opie/libopie/generator.c')
-rw-r--r-- | contrib/opie/libopie/generator.c | 366 |
1 files changed, 38 insertions, 328 deletions
diff --git a/contrib/opie/libopie/generator.c b/contrib/opie/libopie/generator.c index 24c6a73..eef7cac 100644 --- a/contrib/opie/libopie/generator.c +++ b/contrib/opie/libopie/generator.c @@ -1,7 +1,7 @@ /* generator.c: The opiegenerator() library function. %%% portions-copyright-cmetz-96 -Portions of this software are Copyright 1996-1999 by Craig Metz, All Rights +Portions of this software are Copyright 1996-1998 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 @@ -9,9 +9,6 @@ you didn't get a copy, you may request one from <license@inner.net>. History: - Modified by cmetz for OPIE 2.4. Added opieauto code based on - previously released test code. Renamed buffer to challenge. - Use struct opie_otpkey for keys. Modified by cmetz for OPIE 2.32. If secret=NULL, always return as if opieauto returned "get the secret". Renamed _opieparsechallenge() to __opieparsechallenge(). Check @@ -28,368 +25,81 @@ you didn't get a copy, you may request one from <license@inner.net>. Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al. Bug fixes. Created at NRL for OPIE 2.2. + +$FreeBSD$ */ #include "opie_cfg.h" #if HAVE_STRING_H #include <string.h> #endif /* HAVE_STRING_H */ -#if OPIEAUTO -#include <errno.h> -#if HAVE_STDLIB_H -#include <stdlib.h> -#endif /* HAVE_STDLIB_H */ -#include <sys/stat.h> - -#include <sys/socket.h> -#include <sys/un.h> -#endif /* OPIEAUTO */ -#if DEBUG -#include <syslog.h> -#endif /* DEBUG */ #include "opie.h" static char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" }; -#if OPIEAUTO -#ifndef max -#define max(x, y) (((x) > (y)) ? (x) : (y)) -#endif /* max */ - -static int opieauto_connect FUNCTION_NOARGS -{ - int s; - struct sockaddr_un sun; - char buffer[1024]; - char *c, *c2 ="/.opieauto"; - uid_t myuid = getuid(), myeuid = geteuid(); - - if (!myuid || !myeuid || (myuid != myeuid)) { -#if DEBUG - syslog(LOG_DEBUG, "opieauto_connect: superuser and/or setuid not allowed"); -#endif /* DEBUG */ - return -1; - }; - - memset(&sun, 0, sizeof(struct sockaddr_un)); - sun.sun_family = AF_UNIX; - - if (!(c = getenv("HOME"))) { -#if DEBUG - syslog(LOG_DEBUG, "opieauto_connect: no HOME variable?"); -#endif /* DEBUG */ - return -1; - }; - - if (strlen(c) > (sizeof(sun.sun_path) - strlen(c2) - 1)) { -#if DEBUG - syslog(LOG_DEBUG, "opieauto_connect: HOME is too long: %s", c); -#endif /* DEBUG */ - return -1; - }; - - strcpy(sun.sun_path, c); - strcat(sun.sun_path, c2); - - if ((s = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { -#if DEBUG - syslog(LOG_DEBUG, "opieauto_connect: socket: %s(%d)", strerror(errno), errno); -#endif /* DEBUG */ - return -1; - }; - - { - struct stat st; - - if (stat(sun.sun_path, &st) < 0) { -#if DEBUG - syslog(LOG_DEBUG, "opieauto_connect: stat: %s(%d)\n", strerror(errno), errno); -#endif /* DEBUG */ - goto ret; - }; - - if (connect(s, (struct sockaddr *)&sun, sizeof(struct sockaddr_un))) { -#if DEBUG - syslog(LOG_DEBUG, "opieauto_connect: connect: %s(%d)\n", strerror(errno), errno); -#endif /* DEBUG */ - goto ret; - }; - - if ((st.st_uid != myuid) || (!S_ISSOCK(st.st_mode)) || ((st.st_mode & 07777) != 0600)) { -#if DEBUG - syslog(LOG_DEBUG, "opieauto_connect: something's fishy about the socket\n"); -#endif /* DEBUG */ - goto ret; - }; - }; - - return s; - -ret: - close(s); - return -1; -}; -#endif /* OPIEAUTO */ - -int opiegenerator FUNCTION((challenge, secret, response), char *challenge AND char *secret AND char *response) +int opiegenerator FUNCTION((buffer, secret, response), char *buffer AND char *secret AND char *response) { int algorithm; int sequence; char *seed; - struct opie_otpkey key; + char key[8]; int i; int exts; -#if OPIEAUTO - int s; - int window; - char cmd[1+1+1+1+4+1+OPIE_SEED_MAX+1+4+1+4+1+4+1+4+1]; - char *c; -#endif /* OPIEAUTO */ - if (!(challenge = strstr(challenge, "otp-"))) + if (!(buffer = strstr(buffer, "otp-"))) return 1; - challenge += 4; + buffer += 4; - if (__opieparsechallenge(challenge, &algorithm, &sequence, &seed, &exts)) + if (__opieparsechallenge(buffer, &algorithm, &sequence, &seed, &exts)) return 1; if ((sequence < 2) || (sequence > 9999)) return 1; - if (*secret) { - if (opiepasscheck(secret)) - return -2; - - if (i = opiekeycrunch(algorithm, &key, seed, secret)) - return i; - - if (sequence <= OPIE_SEQUENCE_RESTRICT) { - if (!(exts & 1)) - return 1; - - { - char newseed[OPIE_SEED_MAX + 1]; - struct opie_otpkey newkey; - char *c; - char buf[OPIE_SEED_MAX + 48 + 1]; - - while (sequence-- != 0) - opiehash(&key, algorithm); - - 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); - - strcpy(response, "init-hex:"); - strcat(response, opiebtoh(buf, &key)); - if (snprintf(buf, sizeof(buf), ":%s 499 %s:", algids[algorithm], - newseed) >= sizeof(buf)) { -#ifdef DEBUG - syslog(LOG_DEBUG, "opiegenerator: snprintf truncation at init-hex"); -#endif /* DEBUG */ - return -1; - } - strcat(response, buf); - strcat(response, opiebtoh(buf, &newkey)); - }; - }; - }; - -#if OPIEAUTO - if ((s = opieauto_connect()) >= 0) { - if ((i = read(s, cmd, sizeof(cmd)-1)) < 0) { -#if DEBUG - syslog(LOG_DEBUG, "opiegenerator: read: %s(%d)\n", strerror(errno), errno); -#endif /* DEBUG */ - close(s); - s = -1; - goto l0; - }; - cmd[i] = 0; - if ((cmd[0] != 'C') || (cmd[1] != '+') || (cmd[2] != ' ')) { -#if DEBUG - syslog(LOG_DEBUG, "opiegenerator: got invalid/failing C+ response: %s\n", cmd); -#endif /* DEBUG */ - close(s); - s = -1; - goto l0; - }; - - window = strtoul(&cmd[3], &c, 10); - if (!window || (window >= (OPIE_SEQUENCE_MAX - OPIE_SEQUENCE_RESTRICT)) || !isspace(*c)) { -#if DEBUG - syslog(LOG_DEBUG, "opiegenerator: got bogus option response: %s\n", cmd); -#endif /* DEBUG */ - close(s); - s = -1; - goto l0; - }; - }; - -l0: - if (*secret) { - int j; + if (!secret[0]) + return 2; - if (s < 0) { - j = 0; - goto l1; - }; + if (opiepasscheck(secret)) + return -2; - j = max(sequence - window + 1, OPIE_SEQUENCE_RESTRICT); + if (i = opiekeycrunch(algorithm, key, seed, secret)) + return i; - for (i = j; i > 0; i--) - opiehash(&key, algorithm); + if (sequence < 10) { + if (!(exts & 1)) + return 1; { - char buf[16+1]; + char newseed[OPIE_SEED_MAX + 1]; + char newkey[8]; + char *c; + char buf[OPIE_SEED_MAX + 48 + 1]; - opiebtoa8(buf, &key); + while (sequence-- != 0) + opiehash(key, algorithm); - if (snprintf(cmd, sizeof(cmd), "S= %d %d %s %s\n", algorithm, sequence, - seed, buf) >= sizeof(cmd)) { -#if DEBUG - syslog(LOG_DEBUG, "opiegenerator: snprintf truncation at S=\n"); -#endif /* DEBUG */ - goto l1; - } - } + if (opienewseed(strcpy(newseed, seed)) < 0) + return -1; - if (write(s, cmd, i = strlen(cmd)) != i) { -#if DEBUG - syslog(LOG_DEBUG, "opiegenerator: write: %s(%d)\n", strerror(errno), errno); -#endif /* DEBUG */ - goto l1; - }; + if (opiekeycrunch(algorithm, newkey, newseed, secret)) + return -1; - if ((i = read(s, cmd, sizeof(cmd))) < 0) { -#if DEBUG - syslog(LOG_DEBUG, "opiegenerator: read: %s(%d)\n", strerror(errno), errno); -#endif /* DEBUG */ - }; - close(s); + for (i = 0; i < 499; i++) + opiehash(newkey, algorithm); - cmd[i] = 0; - i = strlen(seed); - if ((cmd[0] != 'S') || (cmd[1] != '+') || (cmd[2] != ' ') || (strtoul(&cmd[3], &c, 10) != algorithm) || (strtoul(c + 1, &c, 10) != sequence) || strncmp(++c, seed, i) || (*(c + i) != '\n')) { -#if DEBUG - syslog(LOG_DEBUG, "opiegenerator: got invalid/failing S+ response: %s\n", cmd); -#endif /* DEBUG */ + strcpy(response, "init-hex:"); + strcat(response, opiebtoh(buf, key)); + sprintf(buf, ":%s 499 %s:", algids[algorithm], newseed); + strcat(response, buf); + strcat(response, opiebtoh(buf, newkey)); }; - -l1: - for (i = sequence - j; i > 0; i--) - opiehash(&key, algorithm); - - opiebtoh(response, &key); } else { - if (s < 0) - goto l2; - - if ((snprintf(cmd, sizeof(cmd), "s= %d %d %s\n", algorithm, sequence, - seed) >= sizeof(cmd))) { -#if DEBUG - syslog(LOG_DEBUG, "opiegenerator: snprintf truncation at s=\n"); -#endif /* DEBUG */ - goto l2; - } - - if (write(s, cmd, i = strlen(cmd)) != i) { -#if DEBUG - syslog(LOG_DEBUG, "opiegenerator: write: %s(%d)\n", strerror(errno), errno); -#endif /* DEBUG */ - goto l2; - }; - - if ((i = read(s, cmd, sizeof(cmd))) < 0) { -#if DEBUG - syslog(LOG_DEBUG, "opiegenerator: read: %s(%d)\n", strerror(errno), errno); -#endif /* DEBUG */ - goto l2; - }; - close(s); - - i = strlen(seed); - - if ((cmd[0] != 's') || (cmd[2] != ' ') || (strtoul(&cmd[3], &c, 10) != algorithm) || (strtoul(c + 1, &c, 10) != sequence) || strncmp(++c, seed, i)) { -#if DEBUG - if (c) - *c = 0; - else - cmd[3] = 0; - - syslog(LOG_DEBUG, "opiegenerator: got bogus/invalid s response: %s\n", cmd); -#endif /* DEBUG */ - goto l2; - }; - - c += i; - - if (cmd[1] == '-') { -#if DEBUG - if (*c != '\n') { - *c = 0; - syslog(LOG_DEBUG, "opiegenerator: got invalid s- response: %s\n", cmd); - }; -#endif /* DEBUG */ - goto l2; - }; - - if (cmd[1] != '+') { -#if DEBUG - *c = 0; - syslog(LOG_DEBUG, "opiegenerator: got invalid s response: %s\n", cmd); -#endif /* DEBUG */ - goto l2; - }; - - { - char *c2; - - if (!(c2 = strchr(++c, '\n'))) { -#if DEBUG - *c = 0; - syslog(LOG_DEBUG, "opiegenerator: got invalid s+ response: %s\n", cmd); -#endif /* DEBUG */ - goto l2; - }; - - *c2++ = 0; - }; - - if (!opieatob8(&key, c)) - goto l2; - - opiebtoh(response, &key); - }; - - if (s >= 0) - close(s); -#else /* OPIEAUTO */ - if (*secret) { while (sequence-- != 0) - opiehash(&key, algorithm); + opiehash(key, algorithm); - opiebtoh(response, &key); - } else - return -2; -#endif /* OPIEAUTO */ + opiebtoh(response, key); + } return 0; - -#if OPIEAUTO -l2: -#if DEBUG - syslog(LOG_DEBUG, "opiegenerator: no opieauto response available.\n"); -#endif /* DEBUG */ - if (s >= 0) - close(s); - - return -2; -#endif /* OPIEAUTO */ -}; +} |