wicket: a ticket file now can contain multiple urls, when looking for
a ticket, the first one which contains authentication information for the incomplete url is returned. wildcards are ok, so you can do: pop://sam:pass@pop.uniserve.com *://sroberts:gnuless@mail.certicom.com imap://;AUTH=anon@* Actually, the last doesn't work, but it SHOULD. Another day.
Showing
1 changed file
with
207 additions
and
100 deletions
... | @@ -30,6 +30,7 @@ | ... | @@ -30,6 +30,7 @@ |
30 | 30 | ||
31 | #include <mailutils/mutil.h> | 31 | #include <mailutils/mutil.h> |
32 | #include <auth0.h> | 32 | #include <auth0.h> |
33 | #include <url0.h> | ||
33 | 34 | ||
34 | struct myticket_data | 35 | struct myticket_data |
35 | { | 36 | { |
... | @@ -38,12 +39,11 @@ struct myticket_data | ... | @@ -38,12 +39,11 @@ struct myticket_data |
38 | char *filename; | 39 | char *filename; |
39 | }; | 40 | }; |
40 | 41 | ||
41 | static char * stripwhite __P ((char *)); | ||
42 | static int myticket_create __P ((ticket_t *, const char *, const char *, const char *)); | 42 | static int myticket_create __P ((ticket_t *, const char *, const char *, const char *)); |
43 | static void myticket_destroy __P ((ticket_t)); | 43 | static void myticket_destroy __P ((ticket_t)); |
44 | static int myticket_pop __P ((ticket_t, url_t, const char *, char **)); | 44 | static int myticket_pop __P ((ticket_t, url_t, const char *, char **)); |
45 | static char * get_pass __P ((url_t, const char *, const char *)); | 45 | static int get_pass __P ((url_t, const char *, const char *, char**)); |
46 | static char * get_user __P ((url_t, const char *)); | 46 | static int get_user __P ((url_t, const char *, char **)); |
47 | 47 | ||
48 | int | 48 | int |
49 | wicket_create (wicket_t *pwicket, const char *filename) | 49 | wicket_create (wicket_t *pwicket, const char *filename) |
... | @@ -164,8 +164,6 @@ myticket_create (ticket_t *pticket, const char *user, const char *pass, const ch | ... | @@ -164,8 +164,6 @@ myticket_create (ticket_t *pticket, const char *user, const char *pass, const ch |
164 | status = ENOMEM; | 164 | status = ENOMEM; |
165 | return status; | 165 | return status; |
166 | } | 166 | } |
167 | if (!pass) | ||
168 | mdata->pass = get_pass (NULL, user, filename); | ||
169 | } | 167 | } |
170 | 168 | ||
171 | if (pass) | 169 | if (pass) |
... | @@ -186,13 +184,41 @@ static int | ... | @@ -186,13 +184,41 @@ static int |
186 | myticket_pop (ticket_t ticket, url_t url, const char *challenge, char **parg) | 184 | myticket_pop (ticket_t ticket, url_t url, const char *challenge, char **parg) |
187 | { | 185 | { |
188 | struct myticket_data *mdata = NULL; | 186 | struct myticket_data *mdata = NULL; |
187 | int e = 0; | ||
188 | |||
189 | ticket_get_data (ticket, (void **)&mdata); | 189 | ticket_get_data (ticket, (void **)&mdata); |
190 | if (challenge && (strstr (challenge, "ass") != NULL | 190 | if (challenge && |
191 | || strstr (challenge, "ASS") != NULL)) | 191 | ( |
192 | *parg = (mdata->pass) ? strdup (mdata->pass) : get_pass (url, mdata->user, mdata->filename); | 192 | strstr (challenge, "ass") != NULL || |
193 | strstr (challenge, "ASS") != NULL | ||
194 | ) | ||
195 | ) | ||
196 | { | ||
197 | if(mdata->pass) | ||
198 | { | ||
199 | *parg = strdup(mdata->pass); | ||
200 | if(!*parg) | ||
201 | e = ENOMEM; | ||
202 | } | ||
193 | else | 203 | else |
194 | *parg = (mdata->user) ? strdup (mdata->user) : get_user (url, mdata->filename); | 204 | { |
195 | return 0; | 205 | e = get_pass (url, mdata->user, mdata->filename, parg); |
206 | } | ||
207 | } | ||
208 | else | ||
209 | { | ||
210 | if(mdata->user) | ||
211 | { | ||
212 | *parg = strdup(mdata->user); | ||
213 | if(!*parg) | ||
214 | e = ENOMEM; | ||
215 | } | ||
216 | else | ||
217 | { | ||
218 | e = get_user (url, mdata->filename, parg); | ||
219 | } | ||
220 | } | ||
221 | return e; | ||
196 | } | 222 | } |
197 | 223 | ||
198 | static void | 224 | static void |
... | @@ -212,132 +238,213 @@ myticket_destroy (ticket_t ticket) | ... | @@ -212,132 +238,213 @@ myticket_destroy (ticket_t ticket) |
212 | } | 238 | } |
213 | } | 239 | } |
214 | 240 | ||
215 | /* Strip whitespace from the start and end of STRING. Return a pointer | 241 | static int |
216 | into STRING. */ | 242 | get_ticket (url_t url, const char *user, const char *filename, url_t * ticket) |
217 | static char * | ||
218 | stripwhite (char *string) | ||
219 | { | 243 | { |
220 | register char *s, *t; | 244 | int err = 0; |
245 | FILE *fp = NULL; | ||
246 | size_t buflen = 128; | ||
247 | char *buf = NULL; | ||
221 | 248 | ||
222 | for (s = string; isspace (*s); s++) | ||
223 | ; | ||
224 | 249 | ||
225 | if (*s == 0) | 250 | if (!filename || !url) |
226 | return (s); | 251 | return EINVAL; |
227 | 252 | ||
228 | t = s + strlen (s) - 1; | 253 | fp = fopen (filename, "r"); |
229 | while (t > s && isspace (*t)) | ||
230 | t--; | ||
231 | *++t = '\0'; | ||
232 | 254 | ||
233 | return s; | 255 | if (!fp) |
234 | } | 256 | return errno; |
235 | 257 | ||
236 | static char * | 258 | buf = malloc (buflen); |
237 | get_user (url_t url, const char *filename) | ||
238 | { | ||
239 | struct passwd *pw; | ||
240 | char *u = (char *)""; | ||
241 | if (url) | ||
242 | { | ||
243 | size_t n = 0; | ||
244 | url_get_user (url, NULL, 0, &n); | ||
245 | u = calloc (1, n + 1); | ||
246 | url_get_user (url, u, n + 1, NULL); | ||
247 | return u; | ||
248 | } | ||
249 | else if (filename) | ||
250 | { | ||
251 | /* do something. */ | ||
252 | } | ||
253 | pw = getpwuid (getuid ()); | ||
254 | if (pw) | ||
255 | u = pw->pw_name; | ||
256 | return strdup (u); | ||
257 | } | ||
258 | |||
259 | static char * | ||
260 | get_pass (url_t url, const char *u, const char *filename) | ||
261 | { | ||
262 | char *user = NULL; | ||
263 | char *pass = NULL; | ||
264 | 259 | ||
265 | if (u) | 260 | if (!buf) |
266 | user = strdup (u); | ||
267 | else if (url) | ||
268 | { | 261 | { |
269 | size_t n = 0; | 262 | fclose (fp); |
270 | url_get_user (url, NULL, 0, &n); | 263 | return ENOMEM; |
271 | user = calloc (1, n + 1); | ||
272 | url_get_user (url, user, n + 1, NULL); | ||
273 | } | 264 | } |
274 | else | ||
275 | user = get_user (NULL, filename); | ||
276 | 265 | ||
277 | if (filename && user) | 266 | while (!feof (fp) && !ferror (fp)) |
278 | { | ||
279 | FILE *fp; | ||
280 | fp = fopen (filename, "r"); | ||
281 | if (fp) | ||
282 | { | ||
283 | char *buf; | ||
284 | size_t buflen; | ||
285 | |||
286 | buflen = 128; | ||
287 | buf = malloc (buflen); | ||
288 | if (buf) | ||
289 | { | 267 | { |
290 | char *ptr = buf; | 268 | char *ptr = buf; |
269 | int len = 0; | ||
270 | url_t u = NULL; | ||
271 | |||
272 | /* fgets: | ||
273 | 1) return true, read some data | ||
274 | 1a) read a newline, so break | ||
275 | 1b) didn't read newline, so realloc & continue | ||
276 | 2) returned NULL, so no more data | ||
277 | */ | ||
291 | while (fgets (ptr, buflen, fp) != NULL) | 278 | while (fgets (ptr, buflen, fp) != NULL) |
292 | { | 279 | { |
293 | size_t len = strlen (buf); | 280 | char *tmp = NULL; |
294 | char *sep; | 281 | len = strlen (buf); |
295 | /* Check if a complete line. */ | 282 | /* Check if a complete line. */ |
296 | if (len && buf[len - 1] != '\n') | 283 | if (len && buf[len - 1] == '\n') |
297 | { | ||
298 | char *tmp = realloc (buf, 2*buflen); | ||
299 | if (tmp == NULL) | ||
300 | break; | 284 | break; |
285 | |||
286 | buflen *= 2; | ||
287 | tmp = realloc (buf, buflen); | ||
288 | if (tmp == NULL) | ||
289 | { | ||
290 | free (buf); | ||
291 | fclose (fp); | ||
292 | return ENOMEM; | ||
293 | } | ||
301 | buf = tmp; | 294 | buf = tmp; |
302 | ptr = buf + len; | 295 | ptr = buf + len; |
303 | continue; | ||
304 | } | 296 | } |
305 | 297 | ||
298 | len = strlen (buf); | ||
299 | |||
300 | /* Truncate a trailing newline. */ | ||
301 | if (len && buf[len - 1] == '\n') | ||
302 | buf[len - 1] = 0; | ||
303 | |||
304 | /* Skip leading spaces. */ | ||
306 | ptr = buf; | 305 | ptr = buf; |
306 | while (isspace (*ptr)) | ||
307 | ptr++; | ||
307 | 308 | ||
308 | /* Comments. */ | 309 | /* Skip comments. */ |
309 | if (*ptr == '#') | 310 | if (*ptr == '#') |
310 | continue; | 311 | continue; |
311 | 312 | ||
312 | /* Skip leading spaces. */ | 313 | /* Skip empty lines. */ |
313 | while (isspace (*ptr)) | 314 | if ((len = strlen (ptr)) == 0) |
315 | continue; | ||
316 | |||
317 | if ((err = url_create (&u, ptr)) != 0) | ||
314 | { | 318 | { |
315 | ptr++; | 319 | free (buf); |
316 | len--; | 320 | fclose (fp); |
321 | return err; | ||
322 | } | ||
323 | if ((err = url_parse (u)) != 0) | ||
324 | { | ||
325 | /* TODO: send output to the debug stream */ | ||
326 | /* | ||
327 | printf ("url_parse %s failed: [%d] %s\n", str, err, strerror (err)); | ||
328 | */ | ||
329 | url_destroy (&u); | ||
330 | continue; | ||
317 | } | 331 | } |
318 | 332 | ||
319 | /* user:passwd. Separator maybe ": \t" */ | 333 | |
320 | if (len && ((sep = memchr (ptr, ':', len)) != NULL | 334 | if (!url_is_ticket (u, url)) |
321 | || (sep = memchr (ptr, ' ', len)) != NULL | ||
322 | || (sep = memchr (ptr, '\t', len)) != NULL)) | ||
323 | { | 335 | { |
324 | *sep++ = '\0'; | 336 | url_destroy (&u); |
325 | ptr = stripwhite (ptr); | 337 | continue; |
326 | if (strcmp (ptr, user) == 0) | 338 | } |
339 | /* Also needs to be for name, if we required. */ | ||
340 | if (user) | ||
327 | { | 341 | { |
328 | pass = strdup (stripwhite (sep)); | 342 | if (u->name && strcmp (u->name, "*") != 0 |
343 | && strcmp (user, u->name) != 0) | ||
344 | { | ||
345 | url_destroy (&u); | ||
346 | continue; | ||
347 | } | ||
348 | } | ||
349 | |||
350 | /* Looks like a match! */ | ||
351 | *ticket = u; | ||
352 | u = NULL; | ||
329 | break; | 353 | break; |
330 | } | 354 | } |
355 | |||
356 | fclose (fp); | ||
357 | free (buf); | ||
358 | |||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static int | ||
363 | get_user (url_t url, const char *filename, char **user) | ||
364 | { | ||
365 | char *u = 0; | ||
366 | |||
367 | if (url) | ||
368 | { | ||
369 | size_t n = 0; | ||
370 | url_get_user (url, NULL, 0, &n); | ||
371 | |||
372 | if (n) | ||
373 | { | ||
374 | u = calloc (1, n + 1); | ||
375 | url_get_user (url, u, n + 1, NULL); | ||
376 | } | ||
377 | } | ||
378 | if (!u && filename) | ||
379 | { | ||
380 | url_t ticket = 0; | ||
381 | int e = get_ticket (url, NULL, filename, &ticket); | ||
382 | if (e) | ||
383 | return e; | ||
384 | |||
385 | if (ticket) | ||
386 | { | ||
387 | size_t n = 0; | ||
388 | url_get_user (ticket, NULL, 0, &n); | ||
389 | |||
390 | if (n) | ||
391 | { | ||
392 | u = calloc (1, n + 1); | ||
393 | url_get_user (ticket, u, n + 1, NULL); | ||
394 | } | ||
395 | url_destroy (&ticket); | ||
331 | } | 396 | } |
332 | ptr = buf; | ||
333 | } | 397 | } |
398 | else | ||
399 | { | ||
400 | struct passwd *pw = getpwuid (getuid ()); | ||
401 | if (pw && pw->pw_name) | ||
402 | { | ||
403 | u = strdup (pw->pw_name); | ||
404 | if (!u) | ||
405 | return ENOMEM; | ||
334 | } | 406 | } |
407 | } | ||
408 | *user = u; | ||
409 | return 0; | ||
410 | } | ||
335 | 411 | ||
336 | if (buf) | 412 | static int |
337 | free (buf); | 413 | get_pass (url_t url, const char *user, const char *filename, char **pass) |
338 | fclose (fp); | 414 | { |
415 | char *u = 0; | ||
416 | |||
417 | if (url) | ||
418 | { | ||
419 | size_t n = 0; | ||
420 | url_get_passwd (url, NULL, 0, &n); | ||
421 | |||
422 | if (n) | ||
423 | { | ||
424 | u = calloc (1, n + 1); | ||
425 | url_get_passwd (url, u, n + 1, NULL); | ||
339 | } | 426 | } |
340 | } | 427 | } |
341 | free (user); | 428 | if (!u && filename) |
342 | return pass; | 429 | { |
430 | url_t ticket = 0; | ||
431 | int e = get_ticket (url, user, filename, &ticket); | ||
432 | if (e) | ||
433 | return e; | ||
434 | |||
435 | if (ticket) | ||
436 | { | ||
437 | size_t n = 0; | ||
438 | url_get_passwd (ticket, NULL, 0, &n); | ||
439 | |||
440 | if (n) | ||
441 | { | ||
442 | u = calloc (1, n + 1); | ||
443 | url_get_passwd (ticket, u, n + 1, NULL); | ||
444 | } | ||
445 | url_destroy (&ticket); | ||
446 | } | ||
447 | } | ||
448 | *pass = u; | ||
449 | return 0; | ||
343 | } | 450 | } | ... | ... |
-
Please register or sign in to post a comment