Initial import from FreeBSD RELENG_4:
[games.git] / contrib / opie / libopie / readrec.c
1 /* readrec.c: The __opiereadrec() library function.
2
3 %%% copyright-cmetz-96
4 This software is Copyright 1996-2001 by Craig Metz, All Rights Reserved.
5 The Inner Net License Version 3 applies to this software.
6 You should have received a copy of the license with this software. If
7 you 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 #include "opie_cfg.h"
19
20 #include <stdio.h>
21 #include <sys/types.h>
22 #include <errno.h>
23 #if HAVE_UNISTD_H
24 #include <unistd.h>
25 #endif /* HAVE_UNISTD_H */
26 #if HAVE_STRING_H
27 #include <string.h>
28 #endif /* HAVE_STRING_H */
29 #if HAVE_STDLIB_H
30 #include <stdlib.h>
31 #endif /* HAVE_STDLIB_H */
32 #if HAVE_FCNTL_H
33 #include <fcntl.h>
34 #endif /* HAVE_FCNTL_H */
35 #include <ctype.h>
36 #include <errno.h>
37 #if DEBUG
38 #include <syslog.h>
39 #endif /* DEBUG */
40 #include "opie.h"
41
42 static int parserec FUNCTION((opie), struct opie *opie)
43 {
44   char *c, *c2;
45
46   if (!(c2 = strchr(opie->opie_principal = opie->opie_buf, ' ')))
47     return -1;
48
49   while(*c2 == ' ') c2++;
50   *(c2 - 1) = 0;
51
52   if (!(c2 = strchr(c = c2, ' ')))
53     return -1;
54
55   *(c2++) = 0;
56
57   {
58   char *c3;
59
60   opie->opie_n = strtoul(c, &c3, 10);
61
62   if (*c3 || (opie->opie_n <= 0) || (opie->opie_n > 9999))
63     return -1;
64   };
65
66   if (!(c2 = strchr(opie->opie_seed = c2, ' ')))
67     return -1;
68
69   *(c2++) = 0;
70
71   for (c = opie->opie_seed; *c; c++)
72     if (!isalnum(*c))
73       return -1;
74
75   while(*c2 == ' ') c2++;
76
77   if (!(c2 = strchr(opie->opie_val = c2, ' ')))
78     return -1;
79
80   *(c2++) = 0;
81
82   {
83   struct opie_otpkey otpkey;
84
85   if (!opieatob8(&otpkey, opie->opie_val))
86     return -1;
87   }
88
89   return 0;
90 }
91
92 int __opiereadrec FUNCTION((opie), struct opie *opie)
93 {
94   FILE *f = NULL;
95   int rval = -1;
96
97   if (!(f = __opieopen(KEY_FILE, 0, 0644))) {
98 #if DEBUG
99     syslog(LOG_DEBUG, "__opiereadrec: __opieopen(KEY_FILE..) failed!");
100 #endif /* DEBUG */
101     goto ret;
102   }
103
104   {
105   int i;
106
107   if ((i = open(KEY_FILE, O_RDWR)) < 0) {
108     opie->opie_flags &= ~__OPIE_FLAGS_RW;
109 #if DEBUG
110     syslog(LOG_DEBUG, "__opiereadrec: open(KEY_FILE, O_RDWR) failed: %s", strerror(errno));
111 #endif /* DEBUG */
112   } else {
113     close(i);
114     opie->opie_flags |= __OPIE_FLAGS_RW;
115   }
116   }
117
118   if (opie->opie_buf[0]) {
119     if (fseek(f, opie->opie_recstart, SEEK_SET))
120       goto ret;
121
122     if (fgets(opie->opie_buf, sizeof(opie->opie_buf), f))
123       goto ret;
124
125     if (parserec(opie))
126       goto ret;
127
128     opie->opie_flags |= __OPIE_FLAGS_READ;
129     rval = 0;
130     goto ret;
131   }
132
133   if (!opie->opie_principal)
134     goto ret;
135
136   {
137     char *c, principal[OPIE_PRINCIPAL_MAX];
138     int i;
139     
140     if (c = strchr(opie->opie_principal, ':'))
141       *c = 0;
142     if (strlen(opie->opie_principal) > OPIE_PRINCIPAL_MAX)
143       (opie->opie_principal)[OPIE_PRINCIPAL_MAX] = 0;
144     
145     strcpy(principal, opie->opie_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
163 ret:
164   if (f)
165     fclose(f);
166   return rval;
167 }