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