]>
Commit | Line | Data |
---|---|---|
7ac48069 | 1 | /* $Id$ |
02cd9ede | 2 | * |
3 | * This program will verify signatures on user records in the database. | |
7ac48069 | 4 | * |
5 | * Copyright (C) 1993-1998 by the Massachusetts Institute of Technology | |
6 | * For copying and distribution information, please see the file | |
7 | * <mit-copyright.h>. | |
02cd9ede | 8 | */ |
9 | ||
7ac48069 | 10 | #include <mit-copyright.h> |
02cd9ede | 11 | #include <moira.h> |
12 | #include <moira_site.h> | |
7ac48069 | 13 | |
14 | #include <ctype.h> | |
15 | #include <stdio.h> | |
16 | #include <string.h> | |
17 | #include <unistd.h> | |
18 | ||
02cd9ede | 19 | #include <krb.h> |
20 | #include <gdss.h> | |
7ac48069 | 21 | |
8da3291e | 22 | EXEC SQL INCLUDE sqlca; |
02cd9ede | 23 | |
7ac48069 | 24 | RCSID("$Header$"); |
25 | ||
26 | void hex_dump(unsigned char *p); | |
02cd9ede | 27 | |
28 | char *program; | |
29 | ||
5eaef520 | 30 | int main(int argc, char **argv) |
8da3291e | 31 | { |
5eaef520 | 32 | char buf[BUFSIZ], *usercheck[100], sigbuf[256], *data, *db = "moira"; |
33 | SigInfo si; | |
34 | struct save_queue *sq; | |
35 | int status, i, wait, check, debug, fix; | |
36 | EXEC SQL BEGIN DECLARE SECTION; | |
37 | char login[10], mid[32], rawsig[256], who[257]; | |
38 | EXEC SQL VAR rawsig IS STRING(256); | |
7ac48069 | 39 | int timestamp, sms; |
5eaef520 | 40 | EXEC SQL END DECLARE SECTION; |
02cd9ede | 41 | |
5eaef520 | 42 | initialize_sms_error_table(); |
43 | initialize_krb_error_table(); | |
44 | initialize_gdss_error_table(); | |
02cd9ede | 45 | |
5eaef520 | 46 | program = "sign"; |
47 | check = debug = fix = 0; | |
02cd9ede | 48 | |
5eaef520 | 49 | for (i = 1; i < argc; i++) |
50 | { | |
51 | if (!strcmp(argv[i], "-w")) | |
52 | wait++; | |
53 | else if (!strcmp(argv[i], "-d")) | |
54 | debug++; | |
5eaef520 | 55 | else if (!strcmp(argv[i], "-fix")) |
56 | fix++; | |
57 | else if (argv[i][0] == '-') | |
58 | fprintf(stderr, "Usage: %s [-w] [-D] [-fix]\n", argv[0]); | |
59 | else usercheck[check++] = argv[i]; | |
02cd9ede | 60 | } |
61 | ||
5eaef520 | 62 | EXEC SQL CONNECT :db IDENTIFIED BY :db; |
8da3291e | 63 | |
5eaef520 | 64 | if (fix) |
65 | { | |
66 | /* Set the name of our kerberos ticket file */ | |
67 | krb_set_tkt_string("/tmp/tkt_sign"); | |
68 | status = 1; | |
69 | while (status) | |
70 | { | |
71 | printf("Authenticating as moira.extra:\n"); | |
72 | status = krb_get_pw_in_tkt("moira", "extra", "ATHENA.MIT.EDU", | |
73 | "krbtgt", "ATHENA.MIT.EDU", | |
74 | DEFAULT_TKT_LIFE, 0); | |
75 | if (status != 0) | |
76 | com_err(program, status + krb_err_base, " in krb_get_pw_in_tkt"); | |
8da3291e | 77 | } |
5eaef520 | 78 | com_err(program, 0, "authenticated OK"); |
02cd9ede | 79 | |
5eaef520 | 80 | sms = 0; |
81 | EXEC SQL SELECT string_id INTO :sms FROM strings | |
82 | WHERE string = 'moira.extra@ATHENA.MIT.EDU'; | |
83 | if (sms == 0) | |
84 | { | |
85 | com_err(program, 0, " failed to find string " | |
86 | "moira.extra@ATHENA.MIT.EDU in database"); | |
87 | dest_tkt(); | |
88 | exit(1); | |
8da3291e | 89 | } |
ebacc4d8 | 90 | |
5eaef520 | 91 | sq = sq_create(); |
8da3291e | 92 | } |
93 | ||
5eaef520 | 94 | if (check == 0) |
95 | { | |
96 | EXEC SQL DECLARE c CURSOR FOR | |
97 | SELECT login, clearid, signature, string, sigdate | |
98 | FROM users, strings | |
99 | WHERE signature != CHR(0) and sigwho = string_id; | |
100 | EXEC SQL OPEN c; | |
101 | while (1) | |
102 | { | |
103 | EXEC SQL FETCH c INTO :login, :mid, :rawsig, :who, :timestamp; | |
104 | if (sqlca.sqlcode) | |
105 | break; | |
106 | sprintf(buf, "%s:%s", strtrim(login), strtrim(mid)); | |
107 | si.timestamp = timestamp; | |
108 | si.SigInfoVersion = 0; | |
109 | kname_parse(si.pname, si.pinst, si.prealm, strtrim(who)); | |
110 | si.rawsig = (unsigned char *) &rawsig[0]; | |
111 | status = GDSS_Recompose(&si, sigbuf); | |
112 | if (status) | |
113 | { | |
114 | com_err(program, gdss2et(status), "recomposing for user %s", | |
115 | login); | |
116 | continue; | |
02cd9ede | 117 | } |
5eaef520 | 118 | si.rawsig = NULL; |
119 | status = GDSS_Verify(buf, strlen(buf), sigbuf, &si); | |
120 | if (status) | |
121 | com_err(program, gdss2et(status), "verifying user %s", login); | |
122 | if (fix && status == GDSS_E_BADSIG) | |
7ac48069 | 123 | sq_save_data(sq, strdup(buf)); |
5eaef520 | 124 | if (wait) |
125 | { | |
126 | printf("Next"); | |
127 | fflush(stdout); | |
128 | gets(buf); | |
ebacc4d8 | 129 | } |
130 | } | |
5eaef520 | 131 | if (fix) |
132 | { | |
133 | while (sq_get_data(sq, &data)) | |
134 | { | |
135 | strncpy(login, data, 8); | |
136 | if (strchr(login, ':')) | |
137 | *strchr(login, ':') = '\0'; | |
8da3291e | 138 | again: |
5eaef520 | 139 | com_err(program, 0, "fixing sig for %s", login); |
7ac48069 | 140 | status = GDSS_Sign(data, strlen(data), sigbuf); |
5eaef520 | 141 | if (status) |
142 | { | |
143 | com_err(program, gdss2et(status), "signing data"); | |
144 | continue; | |
8da3291e | 145 | } |
5eaef520 | 146 | si.rawsig = (unsigned char *)rawsig; |
147 | status = GDSS_Verify(data, strlen(data), sigbuf, &si); | |
148 | if (status) | |
149 | { | |
150 | com_err(program, gdss2et(status), "verifying data"); | |
151 | continue; | |
8da3291e | 152 | } |
5eaef520 | 153 | if (strlen(rawsig) > 68) |
154 | { | |
155 | sleep(1); | |
156 | goto again; | |
8da3291e | 157 | } |
158 | ||
5eaef520 | 159 | timestamp = si.timestamp; |
160 | EXEC SQL UPDATE users | |
161 | SET signature = :rawsig, sigwho = :sms, sigdate = :timestamp | |
162 | WHERE login = :login; | |
163 | if (sqlca.sqlcode) | |
164 | { | |
165 | com_err(program, 0, "dbms error %d", sqlca.sqlcode); | |
166 | dest_tkt(); | |
167 | exit(1); | |
8da3291e | 168 | } |
5eaef520 | 169 | EXEC SQL COMMIT WORK; |
8da3291e | 170 | } |
8da3291e | 171 | } |
5eaef520 | 172 | } |
173 | else | |
174 | { | |
175 | for (i = check - 1; i >= 0; i--) | |
176 | { | |
177 | strcpy(login, usercheck[i]); | |
178 | EXEC SQL DECLARE s CURSOR FOR | |
179 | SELECT clearid, signature, string, sigdate | |
180 | FROM users, strings | |
181 | WHERE sigwho = string_id and login = :login; | |
182 | EXEC SQL OPEN s; | |
183 | while (1) | |
184 | { | |
185 | EXEC SQL FETCH s INTO :mid, :rawsig, :who, :timestamp; | |
186 | if (sqlca.sqlcode) | |
187 | break; | |
188 | sprintf(buf, "%s:%s", strtrim(login), strtrim(mid)); | |
189 | if (debug) | |
190 | printf("Verifying \"%s\"\n", buf); | |
191 | si.timestamp = timestamp; | |
192 | si.SigInfoVersion = 0; | |
193 | kname_parse(si.pname, si.pinst, si.prealm, strtrim(who)); | |
194 | si.rawsig = (unsigned char *) &rawsig[0]; | |
195 | status = GDSS_Recompose(&si, sigbuf); | |
196 | if (status) | |
197 | { | |
198 | com_err(program, gdss2et(status), "recomposing for user %s", | |
199 | login); | |
200 | continue; | |
02cd9ede | 201 | } |
5eaef520 | 202 | si.rawsig = NULL; |
203 | status = GDSS_Verify(buf, strlen(buf), sigbuf, &si); | |
204 | if (fix && status == GDSS_E_BADSIG) | |
205 | { | |
206 | com_err(program, 0, "fixing signature for %s", login); | |
ebacc4d8 | 207 | againagain: |
5eaef520 | 208 | status = GDSS_Sign(buf, strlen(buf), sigbuf); |
209 | if (status) | |
210 | { | |
211 | com_err(program, gdss2et(status), "signing data"); | |
212 | continue; | |
8da3291e | 213 | } |
5eaef520 | 214 | si.rawsig = (unsigned char *) rawsig; |
215 | status = GDSS_Verify(buf, strlen(buf), sigbuf, &si); | |
216 | if (status) | |
217 | { | |
218 | com_err(program, gdss2et(status), "verifying data"); | |
219 | continue; | |
8da3291e | 220 | } |
5eaef520 | 221 | if (strlen(rawsig) > 68) |
222 | { | |
223 | sleep(1); | |
224 | goto againagain; | |
8da3291e | 225 | } |
226 | ||
5eaef520 | 227 | timestamp = si.timestamp; |
228 | EXEC SQL UPDATE users | |
229 | SET signature = :rawsig, sigwho = :sms, | |
230 | sigdate = :timestamp | |
231 | WHERE login = :login; | |
232 | if (sqlca.sqlcode != 0) | |
233 | { | |
234 | com_err(program, 0, "dbms error %d", sqlca.sqlcode); | |
235 | dest_tkt(); | |
236 | exit(1); | |
ebacc4d8 | 237 | } |
5eaef520 | 238 | EXEC SQL COMMIT WORK; |
239 | } | |
240 | else if (status) | |
241 | com_err(program, gdss2et(status), "verifying user %s", login); | |
242 | else | |
243 | { | |
244 | com_err(program, 0, "signature verified %s", buf); | |
245 | if (debug == 2) | |
246 | hex_dump(sigbuf); | |
8da3291e | 247 | } |
5eaef520 | 248 | if (wait) |
249 | { | |
250 | printf("Next"); | |
251 | fflush(stdout); | |
252 | gets(buf); | |
02cd9ede | 253 | } |
8da3291e | 254 | } |
02cd9ede | 255 | } |
256 | } | |
257 | ||
5eaef520 | 258 | dest_tkt(); |
259 | exit(0); | |
8da3291e | 260 | } |
02cd9ede | 261 | |
262 | ||
7ac48069 | 263 | void hex_dump(unsigned char *p) |
02cd9ede | 264 | { |
5eaef520 | 265 | printf("Size: %d\n", strlen(p)); |
266 | while (strlen(p) >= 8) | |
267 | { | |
268 | printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", | |
269 | p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); | |
270 | p += 8; | |
02cd9ede | 271 | } |
5eaef520 | 272 | switch (strlen(p)) |
273 | { | |
02cd9ede | 274 | case 7: |
5eaef520 | 275 | printf("%02x %02x %02x %02x %02x %02x %02x\n", |
276 | p[0], p[1], p[2], p[3], p[4], p[5], p[6]); | |
277 | break; | |
02cd9ede | 278 | case 6: |
5eaef520 | 279 | printf("%02x %02x %02x %02x %02x %02x\n", |
280 | p[0], p[1], p[2], p[3], p[4], p[5]); | |
281 | break; | |
02cd9ede | 282 | case 5: |
5eaef520 | 283 | printf("%02x %02x %02x %02x %02x\n", |
284 | p[0], p[1], p[2], p[3], p[4]); | |
285 | break; | |
02cd9ede | 286 | case 4: |
5eaef520 | 287 | printf("%02x %02x %02x %02x\n", |
288 | p[0], p[1], p[2], p[3]); | |
289 | break; | |
02cd9ede | 290 | case 3: |
5eaef520 | 291 | printf("%02x %02x %02x\n", |
292 | p[0], p[1], p[2]); | |
293 | break; | |
02cd9ede | 294 | case 2: |
5eaef520 | 295 | printf("%02x %02x\n", |
296 | p[0], p[1]); | |
297 | break; | |
02cd9ede | 298 | case 1: |
5eaef520 | 299 | printf("%02x\n", |
300 | p[0]); | |
301 | break; | |
02cd9ede | 302 | default: |
5eaef520 | 303 | return; |
02cd9ede | 304 | } |
305 | } |