verify.c revision 22347
122347Spst/* verify.c: The opieverify() library function. 222347Spst 322347Spst%%% copyright-cmetz 422347SpstThis software is Copyright 1996 by Craig Metz, All Rights Reserved. 522347SpstThe Inner Net License Version 2 applies to this software. 622347SpstYou should have received a copy of the license with this software. If 722347Spstyou didn't get a copy, you may request one from <license@inner.net>. 822347Spst 922347Spst History: 1022347Spst 1122347Spst Created by cmetz for OPIE 2.3 using the old verify.c as a guide. 1222347Spst*/ 1322347Spst 1422347Spst#include "opie_cfg.h" 1522347Spst#ifdef HAVE_STRING_H 1622347Spst#include <string.h> 1722347Spst#endif /* HAVE_STRING_H */ 1822347Spst#include "opie.h" 1922347Spst 2022347Spst#define RESPONSE_STANDARD 0 2122347Spst#define RESPONSE_WORD 1 2222347Spst#define RESPONSE_HEX 2 2322347Spst#define RESPONSE_INIT 3 2422347Spst#define RESPONSE_INIT_WORD 4 2522347Spst#define RESPONSE_UNKNOWN 5 2622347Spst 2722347Spststruct _rtrans { 2822347Spst int type; 2922347Spst char *name; 3022347Spst}; 3122347Spst 3222347Spststatic struct _rtrans rtrans[] = { 3322347Spst { RESPONSE_WORD, "word" }, 3422347Spst { RESPONSE_HEX, "hex" }, 3522347Spst { RESPONSE_INIT, "init" }, 3622347Spst { RESPONSE_INIT_WORD, "init-word" }, 3722347Spst { RESPONSE_STANDARD, "" }, 3822347Spst { RESPONSE_UNKNOWN, NULL } 3922347Spst}; 4022347Spst 4122347Spststatic char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" }; 4222347Spst 4322347Spststatic int changed FUNCTION((opie), struct opie *opie) 4422347Spst{ 4522347Spst struct opie opie2; 4622347Spst 4722347Spst memset(&opie2, 0, sizeof(struct opie)); 4822347Spst opie2.opie_principal = opie->opie_principal; 4922347Spst if (__opiereadrec(&opie2)) 5022347Spst return 1; 5122347Spst 5222347Spst if ((opie2.opie_n != opie->opie_n) || strcmp(opie2.opie_val, opie->opie_val) || strcmp(opie2.opie_seed, opie->opie_seed)) 5322347Spst return 1; 5422347Spst 5522347Spst memset(&opie2, 0, sizeof(struct opie)); 5622347Spst return 0; 5722347Spst} 5822347Spst 5922347Spstint opieverify FUNCTION((opie, response), struct opie *opie AND char *response) 6022347Spst{ 6122347Spst int i, rval = -1; 6222347Spst char *c; 6322347Spst char key[8], fkey[8], lastkey[8]; 6422347Spst struct opie nopie; 6522347Spst 6622347Spst if (!opie || !response) 6722347Spst goto verret; 6822347Spst 6922347Spst if (!opie->opie_principal) 7022347Spst#if DEBUG 7122347Spst abort(); 7222347Spst#else /* DEBUG */ 7322347Spst goto verret; 7422347Spst#endif /* DEBUG */ 7522347Spst 7622347Spst if (!opieatob8(lastkey, opie->opie_val)) 7722347Spst goto verret; 7822347Spst 7922347Spst if (c = strchr(response, ':')) { 8022347Spst *(c++) = 0; 8122347Spst { 8222347Spst struct _rtrans *r; 8322347Spst for (r = rtrans; r->name && strcmp(r->name, response); r++); 8422347Spst i = r->type; 8522347Spst } 8622347Spst } else 8722347Spst i = RESPONSE_STANDARD; 8822347Spst 8922347Spst switch(i) { 9022347Spst case RESPONSE_STANDARD: 9122347Spst i = 1; 9222347Spst 9322347Spst if (opieetob(key, response) == 1) { 9422347Spst memcpy(fkey, key, sizeof(key)); 9522347Spst opiehash(fkey, MDX); 9622347Spst i = memcmp(fkey, lastkey, sizeof(key)); 9722347Spst } 9822347Spst if (i && opieatob8(key, response)) { 9922347Spst memcpy(fkey, key, sizeof(key)); 10022347Spst opiehash(fkey, MDX); 10122347Spst i = memcmp(fkey, lastkey, sizeof(key)); 10222347Spst } 10322347Spst break; 10422347Spst case RESPONSE_WORD: 10522347Spst i = 1; 10622347Spst 10722347Spst if (opieetob(key, c) == 1) { 10822347Spst memcpy(fkey, key, sizeof(key)); 10922347Spst opiehash(fkey, MDX); 11022347Spst i = memcmp(fkey, lastkey, sizeof(key)); 11122347Spst } 11222347Spst break; 11322347Spst case RESPONSE_HEX: 11422347Spst i = 1; 11522347Spst 11622347Spst if (opieatob8(key, c)) { 11722347Spst memcpy(fkey, key, sizeof(key)); 11822347Spst opiehash(fkey, MDX); 11922347Spst i = memcmp(fkey, lastkey, sizeof(key)); 12022347Spst } 12122347Spst break; 12222347Spst case RESPONSE_INIT: 12322347Spst case RESPONSE_INIT_WORD: 12422347Spst { 12522347Spst char *c2; 12622347Spst char newkey[8], ckxor[8], ck[8], cv[8], cvc[8]; 12722347Spst char buf[OPIE_SEED_MAX + 48 + 1]; 12822347Spst 12922347Spst if (!(c2 = strchr(c, ':'))) 13022347Spst goto verret; 13122347Spst 13222347Spst *(c2++) = 0; 13322347Spst 13422347Spst if (i == RESPONSE_INIT) { 13522347Spst if (!opieatob8(key, c)) 13622347Spst goto verret; 13722347Spst } else { 13822347Spst if (opieetob(key, c) != 1) 13922347Spst goto verret; 14022347Spst } 14122347Spst 14222347Spst memcpy(fkey, key, sizeof(key)); 14322347Spst opiehash(fkey, MDX); 14422347Spst 14522347Spst if (memcmp(fkey, lastkey, sizeof(key))) 14622347Spst goto verret; 14722347Spst 14822347Spst if (changed(opie)) 14922347Spst goto verret; 15022347Spst 15122347Spst opie->opie_n--; 15222347Spst 15322347Spst if (!opiebtoa8(opie->opie_val, key)) 15422347Spst goto verret; 15522347Spst 15622347Spst if (__opiewriterec(opie)) 15722347Spst goto verret; 15822347Spst 15922347Spst if (!(c2 = strchr(c = c2, ':'))) 16022347Spst goto verret; 16122347Spst 16222347Spst *(c2++) = 0; 16322347Spst 16422347Spst { 16522347Spst int j; 16622347Spst 16722347Spst if (_opieparsechallenge(c, &j, &(opie->opie_n), &(opie->opie_seed)) || (j != MDX)) 16822347Spst goto verret; 16922347Spst } 17022347Spst 17122347Spst if (!(c2 = strchr(c = c2, ':'))) 17222347Spst goto verret; 17322347Spst 17422347Spst *(c2++) = 0; 17522347Spst 17622347Spst if (i == RESPONSE_INIT) { 17722347Spst if (!opieatob8(newkey, c)) 17822347Spst goto verret; 17922347Spst } else { 18022347Spst if (opieetob(newkey, c) != 1) 18122347Spst goto verret; 18222347Spst } 18322347Spst 18422347Spst if (!opie->opie_reinitkey || (opie->opie_reinitkey[0] == '*')) 18522347Spst goto verwrt; 18622347Spst 18722347Spst if (!(c2 = strchr(c = c2, ':'))) 18822347Spst goto verret; 18922347Spst 19022347Spst *(c2++) = 0; 19122347Spst 19222347Spst if (i == RESPONSE_INIT) { 19322347Spst if (!opieatob8(ckxor, c)) 19422347Spst goto verret; 19522347Spst if (!opieatob8(cv, c2)) 19622347Spst goto verret; 19722347Spst } else { 19822347Spst if (opieetob(ckxor, c) != 1) 19922347Spst goto verret; 20022347Spst if (opieetob(cv, c2) != 1) 20122347Spst goto verret; 20222347Spst } 20322347Spst 20422347Spst if (!opieatob8(ck, opie->opie_reinitkey)) 20522347Spst goto verret; 20622347Spst 20722347Spst c = buf; 20822347Spst memcpy(c, ck, sizeof(ck)); c += sizeof(ck); 20922347Spst memcpy(c, key, sizeof(key)); c += sizeof(key); 21022347Spst c += sprintf(c, "%s 499 %s", algids[MDX], opie->opie_seed); 21122347Spst memcpy(c, newkey, sizeof(newkey)); c += sizeof(newkey); 21222347Spst memcpy(c, ckxor, sizeof(ckxor)); c += sizeof(ckxor); 21322347Spst memcpy(c, ck, sizeof(ck)); c += sizeof(ck); 21422347Spst opiehashlen(MDX, buf, cvc, (unsigned int)c - (unsigned int)buf); 21522347Spst 21622347Spst if (memcmp(cv, cvc, sizeof(cv))) 21722347Spst goto verret; 21822347Spst 21922347Spst for (i = 0; i < 8; i++) 22022347Spst ck[i] ^= ckxor[i]; 22122347Spst 22222347Spst if (!opiebtoa8(opie->opie_reinitkey, ck)) 22322347Spst goto verret; 22422347Spst 22522347Spst memcpy(key, newkey, sizeof(key)); 22622347Spst } 22722347Spst goto verwrt; 22822347Spst case RESPONSE_UNKNOWN: 22922347Spst rval = 1; 23022347Spst goto verret; 23122347Spst default: 23222347Spst rval = -1; 23322347Spst goto verret; 23422347Spst } 23522347Spst 23622347Spst if (i) { 23722347Spst rval = 1; 23822347Spst goto verret; 23922347Spst } 24022347Spst 24122347Spst if (changed(opie)) 24222347Spst goto verret; 24322347Spst 24422347Spst opie->opie_n--; 24522347Spst 24622347Spstverwrt: 24722347Spst if (!opiebtoa8(opie->opie_val, key)) 24822347Spst goto verret; 24922347Spst rval = __opiewriterec(opie); 25022347Spst 25122347Spstverret: 25222347Spst opieunlock(); 25322347Spst memset(opie, 0, sizeof(struct opie)); 25422347Spst return rval; 25522347Spst} 256