verify.c revision 29964
1/* verify.c: The opieverify() library function.
2
3%%% copyright-cmetz-96
4This software is Copyright 1996-1997 by Craig Metz, All Rights Reserved.
5The Inner Net License Version 2 applies to this software.
6You should have received a copy of the license with this software. If
7you didn't get a copy, you may request one from <license@inner.net>.
8
9	History:
10
11	Modified by cmetz for OPIE 2.31. Renamed "init" and "RESPONSE_INIT"
12		to "init-hex" and "RESPONSE_INIT_HEX". Removed active attack
13		protection support.
14	Created by cmetz for OPIE 2.3 using the old verify.c as a guide.
15*/
16
17#include "opie_cfg.h"
18#ifdef HAVE_STRING_H
19#include <string.h>
20#endif /* HAVE_STRING_H */
21#include "opie.h"
22
23#define RESPONSE_STANDARD  0
24#define RESPONSE_WORD      1
25#define RESPONSE_HEX       2
26#define RESPONSE_INIT_HEX  3
27#define RESPONSE_INIT_WORD 4
28#define RESPONSE_UNKNOWN   5
29
30struct _rtrans {
31  int type;
32  char *name;
33};
34
35static struct _rtrans rtrans[] = {
36  { RESPONSE_WORD, "word" },
37  { RESPONSE_HEX, "hex" },
38  { RESPONSE_INIT_HEX, "init-hex" },
39  { RESPONSE_INIT_WORD, "init-word" },
40  { RESPONSE_STANDARD, "" },
41  { RESPONSE_UNKNOWN, NULL }
42};
43
44static char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
45
46static int changed FUNCTION((opie), struct opie *opie)
47{
48  struct opie opie2;
49
50  memset(&opie2, 0, sizeof(struct opie));
51  opie2.opie_principal = opie->opie_principal;
52  if (__opiereadrec(&opie2))
53    return 1;
54
55  if ((opie2.opie_n != opie->opie_n) || strcmp(opie2.opie_val, opie->opie_val) || strcmp(opie2.opie_seed, opie->opie_seed))
56    return 1;
57
58  memset(&opie2, 0, sizeof(struct opie));
59  return 0;
60}
61
62int opieverify FUNCTION((opie, response), struct opie *opie AND char *response)
63{
64  int i, rval = -1;
65  char *c;
66  char key[8], fkey[8], lastkey[8];
67  struct opie nopie;
68
69  if (!opie || !response)
70    goto verret;
71
72  if (!opie->opie_principal)
73#if DEBUG
74    abort();
75#else /* DEBUG */
76    goto verret;
77#endif /* DEBUG */
78
79  if (!opieatob8(lastkey, opie->opie_val))
80    goto verret;
81
82  if (c = strchr(response, ':')) {
83    *(c++) = 0;
84    {
85      struct _rtrans *r;
86      for (r = rtrans; r->name && strcmp(r->name, response); r++);
87      i = r->type;
88    }
89  } else
90    i = RESPONSE_STANDARD;
91
92  switch(i) {
93  case RESPONSE_STANDARD:
94    i = 1;
95
96    if (opieetob(key, response) == 1) {
97      memcpy(fkey, key, sizeof(key));
98      opiehash(fkey, MDX);
99      i = memcmp(fkey, lastkey, sizeof(key));
100    }
101    if (i && opieatob8(key, response)) {
102      memcpy(fkey, key, sizeof(key));
103      opiehash(fkey, MDX);
104      i = memcmp(fkey, lastkey, sizeof(key));
105    }
106    break;
107  case RESPONSE_WORD:
108    i = 1;
109
110    if (opieetob(key, c) == 1) {
111      memcpy(fkey, key, sizeof(key));
112      opiehash(fkey, MDX);
113      i = memcmp(fkey, lastkey, sizeof(key));
114    }
115    break;
116  case RESPONSE_HEX:
117    i = 1;
118
119    if (opieatob8(key, c)) {
120      memcpy(fkey, key, sizeof(key));
121      opiehash(fkey, MDX);
122      i = memcmp(fkey, lastkey, sizeof(key));
123    }
124    break;
125  case RESPONSE_INIT_HEX:
126  case RESPONSE_INIT_WORD:
127    {
128      char *c2;
129      char newkey[8];
130      char buf[OPIE_SEED_MAX + 48 + 1];
131
132      if (!(c2 = strchr(c, ':')))
133	goto verret;
134
135      *(c2++) = 0;
136
137      if (i == RESPONSE_INIT_HEX) {
138	if (!opieatob8(key, c))
139	  goto verret;
140      } else {
141	if (opieetob(key, c) != 1)
142	  goto verret;
143      }
144
145      memcpy(fkey, key, sizeof(key));
146      opiehash(fkey, MDX);
147
148      if (memcmp(fkey, lastkey, sizeof(key)))
149	goto verret;
150
151      if (changed(opie))
152	goto verret;
153
154      opie->opie_n--;
155
156      if (!opiebtoa8(opie->opie_val, key))
157	goto verret;
158
159      if (__opiewriterec(opie))
160	goto verret;
161
162      if (!(c2 = strchr(c = c2, ':')))
163	goto verret;
164
165      *(c2++) = 0;
166
167      {
168	int j;
169
170	if (_opieparsechallenge(c, &j, &(opie->opie_n), &(opie->opie_seed)) || (j != MDX))
171	  goto verret;
172      }
173
174      if (!(c2 = strchr(c = c2, ':')))
175	goto verret;
176
177      *(c2++) = 0;
178
179      if (i == RESPONSE_INIT_HEX) {
180	if (!opieatob8(newkey, c))
181	  goto verret;
182      } else {
183	if (opieetob(newkey, c) != 1)
184	  goto verret;
185      }
186    }
187    goto verwrt;
188  case RESPONSE_UNKNOWN:
189    rval = 1;
190    goto verret;
191  default:
192    rval = -1;
193    goto verret;
194  }
195
196  if (i) {
197    rval = 1;
198    goto verret;
199  }
200
201  if (changed(opie))
202    goto verret;
203
204  opie->opie_n--;
205
206verwrt:
207  if (!opiebtoa8(opie->opie_val, key))
208    goto verret;
209  rval = __opiewriterec(opie);
210
211verret:
212  opieunlock();
213  memset(opie, 0, sizeof(struct opie));
214  return rval;
215}
216