122347Spst/* verify.c: The opieverify() library function. 222347Spst 329964Sache%%% copyright-cmetz-96 492906SmarkmThis software is Copyright 1996-2001 by Craig Metz, All Rights Reserved. 592906SmarkmThe Inner Net License Version 3 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 1192906Smarkm Modified by cmetz for OPIE 2.4. Use struct opie_otpkey for keys. 1292906Smarkm Check that seed and sequence number are valid. 1359118Skris Modified by cmetz for OPIE 2.32. Renamed _opieparsechallenge() to 1459118Skris __opieparsechallenge() and handle new argument. Fixed init 1559118Skris response parsing bug. 1659118Skris Modified by cmetz for OPIE 2.31. Renamed "init" to "init-hex". 1729964Sache Modified by cmetz for OPIE 2.31. Renamed "init" and "RESPONSE_INIT" 1829964Sache to "init-hex" and "RESPONSE_INIT_HEX". Removed active attack 1929964Sache protection support. 2022347Spst Created by cmetz for OPIE 2.3 using the old verify.c as a guide. 2122347Spst*/ 2222347Spst 2322347Spst#include "opie_cfg.h" 2422347Spst#ifdef HAVE_STRING_H 2522347Spst#include <string.h> 2622347Spst#endif /* HAVE_STRING_H */ 2722347Spst#include "opie.h" 2822347Spst 2922347Spst#define RESPONSE_STANDARD 0 3022347Spst#define RESPONSE_WORD 1 3122347Spst#define RESPONSE_HEX 2 3229964Sache#define RESPONSE_INIT_HEX 3 3322347Spst#define RESPONSE_INIT_WORD 4 3422347Spst#define RESPONSE_UNKNOWN 5 3522347Spst 3622347Spststruct _rtrans { 3722347Spst int type; 3822347Spst char *name; 3922347Spst}; 4022347Spst 4122347Spststatic struct _rtrans rtrans[] = { 4222347Spst { RESPONSE_WORD, "word" }, 4322347Spst { RESPONSE_HEX, "hex" }, 4429964Sache { RESPONSE_INIT_HEX, "init-hex" }, 4522347Spst { RESPONSE_INIT_WORD, "init-word" }, 4622347Spst { RESPONSE_STANDARD, "" }, 4722347Spst { RESPONSE_UNKNOWN, NULL } 4822347Spst}; 4922347Spst 5022347Spststatic char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" }; 5122347Spst 5222347Spststatic int changed FUNCTION((opie), struct opie *opie) 5322347Spst{ 5422347Spst struct opie opie2; 5522347Spst 5622347Spst memset(&opie2, 0, sizeof(struct opie)); 5722347Spst opie2.opie_principal = opie->opie_principal; 5822347Spst if (__opiereadrec(&opie2)) 5922347Spst return 1; 6022347Spst 6122347Spst if ((opie2.opie_n != opie->opie_n) || strcmp(opie2.opie_val, opie->opie_val) || strcmp(opie2.opie_seed, opie->opie_seed)) 6222347Spst return 1; 6322347Spst 6422347Spst memset(&opie2, 0, sizeof(struct opie)); 6522347Spst return 0; 6622347Spst} 6722347Spst 6822347Spstint opieverify FUNCTION((opie, response), struct opie *opie AND char *response) 6922347Spst{ 7022347Spst int i, rval = -1; 7122347Spst char *c; 7292906Smarkm struct opie_otpkey key, fkey, lastkey; 7322347Spst struct opie nopie; 7422347Spst 7522347Spst if (!opie || !response) 7622347Spst goto verret; 7722347Spst 7822347Spst if (!opie->opie_principal) 7922347Spst#if DEBUG 8022347Spst abort(); 8122347Spst#else /* DEBUG */ 8222347Spst goto verret; 8322347Spst#endif /* DEBUG */ 8422347Spst 8592906Smarkm if (!opieatob8(&lastkey, opie->opie_val)) 8622347Spst goto verret; 8722347Spst 8892906Smarkm for (c = opie->opie_seed; *c; c++) 8992906Smarkm if (!isalnum(*c)) 9092906Smarkm goto verret; 9192906Smarkm 9292906Smarkm if (opie->opie_n <= 0) 9392906Smarkm goto verret; 9492906Smarkm 9522347Spst if (c = strchr(response, ':')) { 9622347Spst *(c++) = 0; 9722347Spst { 9822347Spst struct _rtrans *r; 9922347Spst for (r = rtrans; r->name && strcmp(r->name, response); r++); 10022347Spst i = r->type; 10122347Spst } 10222347Spst } else 10322347Spst i = RESPONSE_STANDARD; 10422347Spst 10522347Spst switch(i) { 10622347Spst case RESPONSE_STANDARD: 10722347Spst i = 1; 10822347Spst 10992906Smarkm if (opieetob(&key, response) == 1) { 11092906Smarkm memcpy(&fkey, &key, sizeof(struct opie_otpkey)); 11192906Smarkm opiehash(&fkey, MDX); 11292906Smarkm i = memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey)); 11322347Spst } 11492906Smarkm if (i && opieatob8(&key, response)) { 11592906Smarkm memcpy(&fkey, &key, sizeof(struct opie_otpkey)); 11692906Smarkm opiehash(&fkey, MDX); 11792906Smarkm i = memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey)); 11822347Spst } 11922347Spst break; 12022347Spst case RESPONSE_WORD: 12122347Spst i = 1; 12222347Spst 12392906Smarkm if (opieetob(&key, c) == 1) { 12492906Smarkm memcpy(&fkey, &key, sizeof(struct opie_otpkey)); 12592906Smarkm opiehash(&fkey, MDX); 12692906Smarkm i = memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey)); 12722347Spst } 12822347Spst break; 12922347Spst case RESPONSE_HEX: 13022347Spst i = 1; 13122347Spst 13292906Smarkm if (opieatob8(&key, c)) { 13392906Smarkm memcpy(&fkey, &key, sizeof(struct opie_otpkey)); 13492906Smarkm opiehash(&fkey, MDX); 13592906Smarkm i = memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey)); 13622347Spst } 13722347Spst break; 13829964Sache case RESPONSE_INIT_HEX: 13922347Spst case RESPONSE_INIT_WORD: 14022347Spst { 14122347Spst char *c2; 14222347Spst 14322347Spst if (!(c2 = strchr(c, ':'))) 14422347Spst goto verret; 14522347Spst 14622347Spst *(c2++) = 0; 14722347Spst 14829964Sache if (i == RESPONSE_INIT_HEX) { 14992906Smarkm if (!opieatob8(&key, c)) 15022347Spst goto verret; 15122347Spst } else { 15292906Smarkm if (opieetob(&key, c) != 1) 15322347Spst goto verret; 15422347Spst } 15522347Spst 15692906Smarkm memcpy(&fkey, &key, sizeof(struct opie_otpkey)); 15792906Smarkm opiehash(&fkey, MDX); 15822347Spst 15992906Smarkm if (memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey))) 16022347Spst goto verret; 16122347Spst 16222347Spst if (changed(opie)) 16322347Spst goto verret; 16422347Spst 16522347Spst opie->opie_n--; 16622347Spst 16792906Smarkm if (!opiebtoa8(opie->opie_val, &key)) 16822347Spst goto verret; 16922347Spst 17022347Spst if (__opiewriterec(opie)) 17122347Spst goto verret; 17222347Spst 17322347Spst if (!(c2 = strchr(c = c2, ':'))) 17422347Spst goto verret; 17522347Spst 17622347Spst *(c2++) = 0; 17722347Spst 17822347Spst { 17959118Skris int j, k; 18022347Spst 18159118Skris if (__opieparsechallenge(c, &j, &(opie->opie_n), &(opie->opie_seed), &k) || (j != MDX) || k) 18222347Spst goto verret; 18322347Spst } 18422347Spst 18529964Sache if (i == RESPONSE_INIT_HEX) { 18692906Smarkm if (!opieatob8(&key, c2)) 18722347Spst goto verret; 18822347Spst } else { 18992906Smarkm if (opieetob(&key, c2) != 1) 19022347Spst goto verret; 19122347Spst } 19222347Spst } 19322347Spst goto verwrt; 19422347Spst case RESPONSE_UNKNOWN: 19522347Spst rval = 1; 19622347Spst goto verret; 19722347Spst default: 19822347Spst rval = -1; 19922347Spst goto verret; 20022347Spst } 20122347Spst 20222347Spst if (i) { 20322347Spst rval = 1; 20422347Spst goto verret; 20522347Spst } 20622347Spst 20722347Spst if (changed(opie)) 20822347Spst goto verret; 20922347Spst 21022347Spst opie->opie_n--; 21122347Spst 21222347Spstverwrt: 21392906Smarkm if (!opiebtoa8(opie->opie_val, &key)) 21422347Spst goto verret; 21522347Spst rval = __opiewriterec(opie); 21622347Spst 21722347Spstverret: 21822347Spst opieunlock(); 21922347Spst memset(opie, 0, sizeof(struct opie)); 22022347Spst return rval; 22122347Spst} 222