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