verify.c revision 22347
122347Spst/* verify.c: The opieverify() library function.
222347Spst
322347Spst%%% copyright-cmetz
422347SpstThis software is Copyright 1996 by Craig Metz, All Rights Reserved.
522347SpstThe Inner Net License Version 2 applies to this software.
622347SpstYou should have received a copy of the license with this software. If
722347Spstyou didn't get a copy, you may request one from <license@inner.net>.
822347Spst
922347Spst	History:
1022347Spst
1122347Spst	Created by cmetz for OPIE 2.3 using the old verify.c as a guide.
1222347Spst*/
1322347Spst
1422347Spst#include "opie_cfg.h"
1522347Spst#ifdef HAVE_STRING_H
1622347Spst#include <string.h>
1722347Spst#endif /* HAVE_STRING_H */
1822347Spst#include "opie.h"
1922347Spst
2022347Spst#define RESPONSE_STANDARD  0
2122347Spst#define RESPONSE_WORD      1
2222347Spst#define RESPONSE_HEX       2
2322347Spst#define RESPONSE_INIT      3
2422347Spst#define RESPONSE_INIT_WORD 4
2522347Spst#define RESPONSE_UNKNOWN   5
2622347Spst
2722347Spststruct _rtrans {
2822347Spst  int type;
2922347Spst  char *name;
3022347Spst};
3122347Spst
3222347Spststatic struct _rtrans rtrans[] = {
3322347Spst  { RESPONSE_WORD, "word" },
3422347Spst  { RESPONSE_HEX, "hex" },
3522347Spst  { RESPONSE_INIT, "init" },
3622347Spst  { RESPONSE_INIT_WORD, "init-word" },
3722347Spst  { RESPONSE_STANDARD, "" },
3822347Spst  { RESPONSE_UNKNOWN, NULL }
3922347Spst};
4022347Spst
4122347Spststatic char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
4222347Spst
4322347Spststatic int changed FUNCTION((opie), struct opie *opie)
4422347Spst{
4522347Spst  struct opie opie2;
4622347Spst
4722347Spst  memset(&opie2, 0, sizeof(struct opie));
4822347Spst  opie2.opie_principal = opie->opie_principal;
4922347Spst  if (__opiereadrec(&opie2))
5022347Spst    return 1;
5122347Spst
5222347Spst  if ((opie2.opie_n != opie->opie_n) || strcmp(opie2.opie_val, opie->opie_val) || strcmp(opie2.opie_seed, opie->opie_seed))
5322347Spst    return 1;
5422347Spst
5522347Spst  memset(&opie2, 0, sizeof(struct opie));
5622347Spst  return 0;
5722347Spst}
5822347Spst
5922347Spstint opieverify FUNCTION((opie, response), struct opie *opie AND char *response)
6022347Spst{
6122347Spst  int i, rval = -1;
6222347Spst  char *c;
6322347Spst  char key[8], fkey[8], lastkey[8];
6422347Spst  struct opie nopie;
6522347Spst
6622347Spst  if (!opie || !response)
6722347Spst    goto verret;
6822347Spst
6922347Spst  if (!opie->opie_principal)
7022347Spst#if DEBUG
7122347Spst    abort();
7222347Spst#else /* DEBUG */
7322347Spst    goto verret;
7422347Spst#endif /* DEBUG */
7522347Spst
7622347Spst  if (!opieatob8(lastkey, opie->opie_val))
7722347Spst    goto verret;
7822347Spst
7922347Spst  if (c = strchr(response, ':')) {
8022347Spst    *(c++) = 0;
8122347Spst    {
8222347Spst      struct _rtrans *r;
8322347Spst      for (r = rtrans; r->name && strcmp(r->name, response); r++);
8422347Spst      i = r->type;
8522347Spst    }
8622347Spst  } else
8722347Spst    i = RESPONSE_STANDARD;
8822347Spst
8922347Spst  switch(i) {
9022347Spst  case RESPONSE_STANDARD:
9122347Spst    i = 1;
9222347Spst
9322347Spst    if (opieetob(key, response) == 1) {
9422347Spst      memcpy(fkey, key, sizeof(key));
9522347Spst      opiehash(fkey, MDX);
9622347Spst      i = memcmp(fkey, lastkey, sizeof(key));
9722347Spst    }
9822347Spst    if (i && opieatob8(key, response)) {
9922347Spst      memcpy(fkey, key, sizeof(key));
10022347Spst      opiehash(fkey, MDX);
10122347Spst      i = memcmp(fkey, lastkey, sizeof(key));
10222347Spst    }
10322347Spst    break;
10422347Spst  case RESPONSE_WORD:
10522347Spst    i = 1;
10622347Spst
10722347Spst    if (opieetob(key, c) == 1) {
10822347Spst      memcpy(fkey, key, sizeof(key));
10922347Spst      opiehash(fkey, MDX);
11022347Spst      i = memcmp(fkey, lastkey, sizeof(key));
11122347Spst    }
11222347Spst    break;
11322347Spst  case RESPONSE_HEX:
11422347Spst    i = 1;
11522347Spst
11622347Spst    if (opieatob8(key, c)) {
11722347Spst      memcpy(fkey, key, sizeof(key));
11822347Spst      opiehash(fkey, MDX);
11922347Spst      i = memcmp(fkey, lastkey, sizeof(key));
12022347Spst    }
12122347Spst    break;
12222347Spst  case RESPONSE_INIT:
12322347Spst  case RESPONSE_INIT_WORD:
12422347Spst    {
12522347Spst      char *c2;
12622347Spst      char newkey[8], ckxor[8], ck[8], cv[8], cvc[8];
12722347Spst      char buf[OPIE_SEED_MAX + 48 + 1];
12822347Spst
12922347Spst      if (!(c2 = strchr(c, ':')))
13022347Spst	goto verret;
13122347Spst
13222347Spst      *(c2++) = 0;
13322347Spst
13422347Spst      if (i == RESPONSE_INIT) {
13522347Spst	if (!opieatob8(key, c))
13622347Spst	  goto verret;
13722347Spst      } else {
13822347Spst	if (opieetob(key, c) != 1)
13922347Spst	  goto verret;
14022347Spst      }
14122347Spst
14222347Spst      memcpy(fkey, key, sizeof(key));
14322347Spst      opiehash(fkey, MDX);
14422347Spst
14522347Spst      if (memcmp(fkey, lastkey, sizeof(key)))
14622347Spst	goto verret;
14722347Spst
14822347Spst      if (changed(opie))
14922347Spst	goto verret;
15022347Spst
15122347Spst      opie->opie_n--;
15222347Spst
15322347Spst      if (!opiebtoa8(opie->opie_val, key))
15422347Spst	goto verret;
15522347Spst
15622347Spst      if (__opiewriterec(opie))
15722347Spst	goto verret;
15822347Spst
15922347Spst      if (!(c2 = strchr(c = c2, ':')))
16022347Spst	goto verret;
16122347Spst
16222347Spst      *(c2++) = 0;
16322347Spst
16422347Spst      {
16522347Spst	int j;
16622347Spst
16722347Spst	if (_opieparsechallenge(c, &j, &(opie->opie_n), &(opie->opie_seed)) || (j != MDX))
16822347Spst	  goto verret;
16922347Spst      }
17022347Spst
17122347Spst      if (!(c2 = strchr(c = c2, ':')))
17222347Spst	goto verret;
17322347Spst
17422347Spst      *(c2++) = 0;
17522347Spst
17622347Spst      if (i == RESPONSE_INIT) {
17722347Spst	if (!opieatob8(newkey, c))
17822347Spst	  goto verret;
17922347Spst      } else {
18022347Spst	if (opieetob(newkey, c) != 1)
18122347Spst	  goto verret;
18222347Spst      }
18322347Spst
18422347Spst      if (!opie->opie_reinitkey || (opie->opie_reinitkey[0] == '*'))
18522347Spst	goto verwrt;
18622347Spst
18722347Spst      if (!(c2 = strchr(c = c2, ':')))
18822347Spst	goto verret;
18922347Spst
19022347Spst      *(c2++) = 0;
19122347Spst
19222347Spst      if (i == RESPONSE_INIT) {
19322347Spst	if (!opieatob8(ckxor, c))
19422347Spst	  goto verret;
19522347Spst	if (!opieatob8(cv, c2))
19622347Spst	  goto verret;
19722347Spst      } else {
19822347Spst	if (opieetob(ckxor, c) != 1)
19922347Spst	  goto verret;
20022347Spst	if (opieetob(cv, c2) != 1)
20122347Spst	  goto verret;
20222347Spst      }
20322347Spst
20422347Spst      if (!opieatob8(ck, opie->opie_reinitkey))
20522347Spst	goto verret;
20622347Spst
20722347Spst      c = buf;
20822347Spst      memcpy(c, ck, sizeof(ck)); c += sizeof(ck);
20922347Spst      memcpy(c, key, sizeof(key)); c += sizeof(key);
21022347Spst      c += sprintf(c, "%s 499 %s", algids[MDX], opie->opie_seed);
21122347Spst      memcpy(c, newkey, sizeof(newkey)); c += sizeof(newkey);
21222347Spst      memcpy(c, ckxor, sizeof(ckxor)); c += sizeof(ckxor);
21322347Spst      memcpy(c, ck, sizeof(ck)); c += sizeof(ck);
21422347Spst      opiehashlen(MDX, buf, cvc, (unsigned int)c - (unsigned int)buf);
21522347Spst
21622347Spst      if (memcmp(cv, cvc, sizeof(cv)))
21722347Spst	goto verret;
21822347Spst
21922347Spst      for (i = 0; i < 8; i++)
22022347Spst	ck[i] ^= ckxor[i];
22122347Spst
22222347Spst      if (!opiebtoa8(opie->opie_reinitkey, ck))
22322347Spst	goto verret;
22422347Spst
22522347Spst      memcpy(key, newkey, sizeof(key));
22622347Spst    }
22722347Spst    goto verwrt;
22822347Spst  case RESPONSE_UNKNOWN:
22922347Spst    rval = 1;
23022347Spst    goto verret;
23122347Spst  default:
23222347Spst    rval = -1;
23322347Spst    goto verret;
23422347Spst  }
23522347Spst
23622347Spst  if (i) {
23722347Spst    rval = 1;
23822347Spst    goto verret;
23922347Spst  }
24022347Spst
24122347Spst  if (changed(opie))
24222347Spst    goto verret;
24322347Spst
24422347Spst  opie->opie_n--;
24522347Spst
24622347Spstverwrt:
24722347Spst  if (!opiebtoa8(opie->opie_val, key))
24822347Spst    goto verret;
24922347Spst  rval = __opiewriterec(opie);
25022347Spst
25122347Spstverret:
25222347Spst  opieunlock();
25322347Spst  memset(opie, 0, sizeof(struct opie));
25422347Spst  return rval;
25522347Spst}
256