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