1/* readrec.c: The __opiereadrec() 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. Check that seed, sequence number, and 12 response values are valid. 13 Modified by cmetz for OPIE 2.31. Removed active attack protection 14 support. Fixed a debug message typo. Keep going after bogus 15 records. Set read flag. 16 Created by cmetz for OPIE 2.3. 17 18$FreeBSD: releng/10.3/contrib/opie/libopie/readrec.c 208586 2010-05-27 03:15:04Z cperciva $ 19*/ 20#include "opie_cfg.h" 21 22#include <stdio.h> 23#include <sys/types.h> 24#include <errno.h> 25#if HAVE_UNISTD_H 26#include <unistd.h> 27#endif /* HAVE_UNISTD_H */ 28#if HAVE_STRING_H 29#include <string.h> 30#endif /* HAVE_STRING_H */ 31#if HAVE_STDLIB_H 32#include <stdlib.h> 33#endif /* HAVE_STDLIB_H */ 34#if HAVE_FCNTL_H 35#include <fcntl.h> 36#endif /* HAVE_FCNTL_H */ 37#include <ctype.h> 38#include <errno.h> 39#if DEBUG 40#include <syslog.h> 41#endif /* DEBUG */ 42#include "opie.h" 43 44static int parserec FUNCTION((opie), struct opie *opie) 45{ 46 char *c, *c2; 47 48 if (!(c2 = strchr(opie->opie_principal = opie->opie_buf, ' '))) 49 return -1; 50 51 while(*c2 == ' ') c2++; 52 *(c2 - 1) = 0; 53 54 if (!(c2 = strchr(c = c2, ' '))) 55 return -1; 56 57 *(c2++) = 0; 58 59 { 60 char *c3; 61 62 opie->opie_n = strtoul(c, &c3, 10); 63 64 if (*c3 || (opie->opie_n <= 0) || (opie->opie_n > 9999)) 65 return -1; 66 }; 67 68 if (!(c2 = strchr(opie->opie_seed = c2, ' '))) 69 return -1; 70 71 *(c2++) = 0; 72 73 for (c = opie->opie_seed; *c; c++) 74 if (!isalnum(*c)) 75 return -1; 76 77 while(*c2 == ' ') c2++; 78 79 if (!(c2 = strchr(opie->opie_val = c2, ' '))) 80 return -1; 81 82 *(c2++) = 0; 83 84 { 85 struct opie_otpkey otpkey; 86 87 if (!opieatob8(&otpkey, opie->opie_val)) 88 return -1; 89 } 90 91 return 0; 92} 93 94int __opiereadrec FUNCTION((opie), struct opie *opie) 95{ 96 FILE *f = NULL; 97 int rval = -1; 98 99 if (!(f = __opieopen(KEY_FILE, 0, 0600))) { 100#if DEBUG 101 syslog(LOG_DEBUG, "__opiereadrec: __opieopen(KEY_FILE..) failed!"); 102#endif /* DEBUG */ 103 goto ret; 104 } 105 106 { 107 int i; 108 109 if ((i = open(KEY_FILE, O_RDWR)) < 0) { 110 opie->opie_flags &= ~__OPIE_FLAGS_RW; 111#if DEBUG 112 syslog(LOG_DEBUG, "__opiereadrec: open(KEY_FILE, O_RDWR) failed: %s", strerror(errno)); 113#endif /* DEBUG */ 114 } else { 115 close(i); 116 opie->opie_flags |= __OPIE_FLAGS_RW; 117 } 118 } 119 120 if (opie->opie_buf[0]) { 121 if (fseek(f, opie->opie_recstart, SEEK_SET)) 122 goto ret; 123 124 if (fgets(opie->opie_buf, sizeof(opie->opie_buf), f)) 125 goto ret; 126 127 if (parserec(opie)) 128 goto ret; 129 130 opie->opie_flags |= __OPIE_FLAGS_READ; 131 rval = 0; 132 goto ret; 133 } 134 135 if (!opie->opie_principal) 136 goto ret; 137 138 { 139 char *c, principal[OPIE_PRINCIPAL_MAX]; 140 int i; 141 142 if (c = strchr(opie->opie_principal, ':')) 143 *c = 0; 144 145 strlcpy(principal, opie->opie_principal, sizeof(principal)); 146 147 do { 148 if ((opie->opie_recstart = ftell(f)) < 0) 149 goto ret; 150 151 if (!fgets(opie->opie_buf, sizeof(opie->opie_buf), f)) { 152 rval = 1; 153 goto ret; 154 } 155 156 if (parserec(opie)) 157 continue; 158 } while (strcmp(principal, opie->opie_principal)); 159 160 rval = 0; 161 } 162 163ret: 164 if (f) 165 fclose(f); 166 return rval; 167} 168