verify.c revision 59118
122347Spst/* verify.c: The opieverify() library function.
222347Spst
329964Sache%%% copyright-cmetz-96
459118SkrisThis software is Copyright 1996-1998 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
1159118Skris	Modified by cmetz for OPIE 2.32. Renamed _opieparsechallenge() to
1259118Skris		__opieparsechallenge() and handle new argument. Fixed init
1359118Skris		response parsing bug.
1459118Skris	Modified by cmetz for OPIE 2.31. Renamed "init" to "init-hex".
1529964Sache	Modified by cmetz for OPIE 2.31. Renamed "init" and "RESPONSE_INIT"
1629964Sache		to "init-hex" and "RESPONSE_INIT_HEX". Removed active attack
1729964Sache		protection support.
1822347Spst	Created by cmetz for OPIE 2.3 using the old verify.c as a guide.
1922347Spst*/
2022347Spst
2122347Spst#include "opie_cfg.h"
2222347Spst#ifdef HAVE_STRING_H
2322347Spst#include <string.h>
2422347Spst#endif /* HAVE_STRING_H */
2522347Spst#include "opie.h"
2622347Spst
2722347Spst#define RESPONSE_STANDARD  0
2822347Spst#define RESPONSE_WORD      1
2922347Spst#define RESPONSE_HEX       2
3029964Sache#define RESPONSE_INIT_HEX  3
3122347Spst#define RESPONSE_INIT_WORD 4
3222347Spst#define RESPONSE_UNKNOWN   5
3322347Spst
3422347Spststruct _rtrans {
3522347Spst  int type;
3622347Spst  char *name;
3722347Spst};
3822347Spst
3922347Spststatic struct _rtrans rtrans[] = {
4022347Spst  { RESPONSE_WORD, "word" },
4122347Spst  { RESPONSE_HEX, "hex" },
4229964Sache  { RESPONSE_INIT_HEX, "init-hex" },
4322347Spst  { RESPONSE_INIT_WORD, "init-word" },
4422347Spst  { RESPONSE_STANDARD, "" },
4522347Spst  { RESPONSE_UNKNOWN, NULL }
4622347Spst};
4722347Spst
4822347Spststatic char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
4922347Spst
5022347Spststatic int changed FUNCTION((opie), struct opie *opie)
5122347Spst{
5222347Spst  struct opie opie2;
5322347Spst
5422347Spst  memset(&opie2, 0, sizeof(struct opie));
5522347Spst  opie2.opie_principal = opie->opie_principal;
5622347Spst  if (__opiereadrec(&opie2))
5722347Spst    return 1;
5822347Spst
5922347Spst  if ((opie2.opie_n != opie->opie_n) || strcmp(opie2.opie_val, opie->opie_val) || strcmp(opie2.opie_seed, opie->opie_seed))
6022347Spst    return 1;
6122347Spst
6222347Spst  memset(&opie2, 0, sizeof(struct opie));
6322347Spst  return 0;
6422347Spst}
6522347Spst
6622347Spstint opieverify FUNCTION((opie, response), struct opie *opie AND char *response)
6722347Spst{
6822347Spst  int i, rval = -1;
6922347Spst  char *c;
7022347Spst  char key[8], fkey[8], lastkey[8];
7122347Spst  struct opie nopie;
7222347Spst
7322347Spst  if (!opie || !response)
7422347Spst    goto verret;
7522347Spst
7622347Spst  if (!opie->opie_principal)
7722347Spst#if DEBUG
7822347Spst    abort();
7922347Spst#else /* DEBUG */
8022347Spst    goto verret;
8122347Spst#endif /* DEBUG */
8222347Spst
8322347Spst  if (!opieatob8(lastkey, opie->opie_val))
8422347Spst    goto verret;
8522347Spst
8622347Spst  if (c = strchr(response, ':')) {
8722347Spst    *(c++) = 0;
8822347Spst    {
8922347Spst      struct _rtrans *r;
9022347Spst      for (r = rtrans; r->name && strcmp(r->name, response); r++);
9122347Spst      i = r->type;
9222347Spst    }
9322347Spst  } else
9422347Spst    i = RESPONSE_STANDARD;
9522347Spst
9622347Spst  switch(i) {
9722347Spst  case RESPONSE_STANDARD:
9822347Spst    i = 1;
9922347Spst
10022347Spst    if (opieetob(key, response) == 1) {
10122347Spst      memcpy(fkey, key, sizeof(key));
10222347Spst      opiehash(fkey, MDX);
10322347Spst      i = memcmp(fkey, lastkey, sizeof(key));
10422347Spst    }
10522347Spst    if (i && opieatob8(key, response)) {
10622347Spst      memcpy(fkey, key, sizeof(key));
10722347Spst      opiehash(fkey, MDX);
10822347Spst      i = memcmp(fkey, lastkey, sizeof(key));
10922347Spst    }
11022347Spst    break;
11122347Spst  case RESPONSE_WORD:
11222347Spst    i = 1;
11322347Spst
11422347Spst    if (opieetob(key, c) == 1) {
11522347Spst      memcpy(fkey, key, sizeof(key));
11622347Spst      opiehash(fkey, MDX);
11722347Spst      i = memcmp(fkey, lastkey, sizeof(key));
11822347Spst    }
11922347Spst    break;
12022347Spst  case RESPONSE_HEX:
12122347Spst    i = 1;
12222347Spst
12322347Spst    if (opieatob8(key, c)) {
12422347Spst      memcpy(fkey, key, sizeof(key));
12522347Spst      opiehash(fkey, MDX);
12622347Spst      i = memcmp(fkey, lastkey, sizeof(key));
12722347Spst    }
12822347Spst    break;
12929964Sache  case RESPONSE_INIT_HEX:
13022347Spst  case RESPONSE_INIT_WORD:
13122347Spst    {
13222347Spst      char *c2;
13322347Spst
13422347Spst      if (!(c2 = strchr(c, ':')))
13522347Spst	goto verret;
13622347Spst
13722347Spst      *(c2++) = 0;
13822347Spst
13929964Sache      if (i == RESPONSE_INIT_HEX) {
14022347Spst	if (!opieatob8(key, c))
14122347Spst	  goto verret;
14222347Spst      } else {
14322347Spst	if (opieetob(key, c) != 1)
14422347Spst	  goto verret;
14522347Spst      }
14622347Spst
14722347Spst      memcpy(fkey, key, sizeof(key));
14822347Spst      opiehash(fkey, MDX);
14922347Spst
15022347Spst      if (memcmp(fkey, lastkey, sizeof(key)))
15122347Spst	goto verret;
15222347Spst
15322347Spst      if (changed(opie))
15422347Spst	goto verret;
15522347Spst
15622347Spst      opie->opie_n--;
15722347Spst
15822347Spst      if (!opiebtoa8(opie->opie_val, key))
15922347Spst	goto verret;
16022347Spst
16122347Spst      if (__opiewriterec(opie))
16222347Spst	goto verret;
16322347Spst
16422347Spst      if (!(c2 = strchr(c = c2, ':')))
16522347Spst	goto verret;
16622347Spst
16722347Spst      *(c2++) = 0;
16822347Spst
16922347Spst      {
17059118Skris	int j, k;
17122347Spst
17259118Skris	if (__opieparsechallenge(c, &j, &(opie->opie_n), &(opie->opie_seed), &k) || (j != MDX) || k)
17322347Spst	  goto verret;
17422347Spst      }
17522347Spst
17629964Sache      if (i == RESPONSE_INIT_HEX) {
17759118Skris	if (!opieatob8(key, c2))
17822347Spst	  goto verret;
17922347Spst      } else {
18059118Skris	if (opieetob(key, c2) != 1)
18122347Spst	  goto verret;
18222347Spst      }
18322347Spst    }
18422347Spst    goto verwrt;
18522347Spst  case RESPONSE_UNKNOWN:
18622347Spst    rval = 1;
18722347Spst    goto verret;
18822347Spst  default:
18922347Spst    rval = -1;
19022347Spst    goto verret;
19122347Spst  }
19222347Spst
19322347Spst  if (i) {
19422347Spst    rval = 1;
19522347Spst    goto verret;
19622347Spst  }
19722347Spst
19822347Spst  if (changed(opie))
19922347Spst    goto verret;
20022347Spst
20122347Spst  opie->opie_n--;
20222347Spst
20322347Spstverwrt:
20422347Spst  if (!opiebtoa8(opie->opie_val, key))
20522347Spst    goto verret;
20622347Spst  rval = __opiewriterec(opie);
20722347Spst
20822347Spstverret:
20922347Spst  opieunlock();
21022347Spst  memset(opie, 0, sizeof(struct opie));
21122347Spst  return rval;
21222347Spst}
213