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