Improve the algorithm for URL look up in wickets.
The new algorithm always returns the best match, i.e. the one with the smallest number of wildcard comparisons. * include/mailutils/auth.h (mu_wicket_stream_match_url) (mu_wicket_file_match_url): New protos. Remove unnecessary 'extern' qualifiers. * include/mailutils/url.h (mu_url_is_ticket): Remove. (mu_url_matches_ticket): New proto. * libmailutils/base/url.c (mu_url_parse): Fix name corruption during password obfuscation. (defined): Remove static function. (mu_url_is_ticket): Remove function. (mu_url_matches_ticket): New function. * libmailutils/base/wicket.c (get_ticket_url): Remove. (mu_wicket_stream_match_url) (mu_wicket_file_match_url): New functions. (file_ticket_get_cred): Use mu_wicket_file_match_url. * libmailutils/tests/wicket.c: New file. * libmailutils/tests/Wicketfile: New file. * libmailutils/tests/wicket.at: New file. * libmailutils/tests/Makefile.am (noinst_PROGRAMS): Add wicket. (EXTRA_DIST): Add Wicketfile (TESTSUITE_AT): Add wicket.at * libmailutils/tests/testsuite.at: Include wicket.at * libmailutils/tests/.gitignore: Update.
Showing
10 changed files
with
336 additions
and
114 deletions
... | @@ -25,56 +25,64 @@ | ... | @@ -25,56 +25,64 @@ |
25 | extern "C" { | 25 | extern "C" { |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | extern int mu_ticket_create (mu_ticket_t *, void *); | 28 | int mu_ticket_create (mu_ticket_t *, void *); |
29 | extern int mu_ticket_ref (mu_ticket_t); | 29 | int mu_ticket_ref (mu_ticket_t); |
30 | extern int mu_ticket_unref (mu_ticket_t); | 30 | int mu_ticket_unref (mu_ticket_t); |
31 | extern void mu_ticket_destroy (mu_ticket_t *); | 31 | void mu_ticket_destroy (mu_ticket_t *); |
32 | extern int mu_ticket_set_destroy (mu_ticket_t, | 32 | int mu_ticket_set_destroy (mu_ticket_t, |
33 | void (*) (mu_ticket_t), void *); | 33 | void (*) (mu_ticket_t), void *); |
34 | extern void *mu_ticket_get_owner (mu_ticket_t); | 34 | void *mu_ticket_get_owner (mu_ticket_t); |
35 | 35 | ||
36 | extern int mu_ticket_get_cred (mu_ticket_t ticket, | 36 | int mu_ticket_get_cred (mu_ticket_t ticket, |
37 | mu_url_t url, const char *challenge, | 37 | mu_url_t url, const char *challenge, |
38 | char **pplain, mu_secret_t *psec); | 38 | char **pplain, mu_secret_t *psec); |
39 | 39 | ||
40 | extern int mu_ticket_set_get_cred (mu_ticket_t, | 40 | int mu_ticket_set_get_cred (mu_ticket_t, |
41 | int (*) (mu_ticket_t, mu_url_t, | 41 | int (*) (mu_ticket_t, mu_url_t, |
42 | const char *, | 42 | const char *, |
43 | char **, mu_secret_t *), | 43 | char **, mu_secret_t *), |
44 | void *); | 44 | void *); |
45 | 45 | ||
46 | extern int mu_ticket_set_data (mu_ticket_t, void *, void *owner); | 46 | int mu_ticket_set_data (mu_ticket_t, void *, void *owner); |
47 | extern void *mu_ticket_get_data (mu_ticket_t); | 47 | void *mu_ticket_get_data (mu_ticket_t); |
48 | 48 | ||
49 | extern int mu_ticket_set_secret (mu_ticket_t ticket, mu_secret_t secret); | 49 | int mu_ticket_set_secret (mu_ticket_t ticket, mu_secret_t secret); |
50 | int mu_ticket_set_plain (mu_ticket_t ticket, const char *text); | 50 | int mu_ticket_set_plain (mu_ticket_t ticket, const char *text); |
51 | 51 | ||
52 | extern int mu_authority_create (mu_authority_t *, mu_ticket_t, void *); | 52 | int mu_authority_create (mu_authority_t *, mu_ticket_t, void *); |
53 | extern void mu_authority_destroy (mu_authority_t *, void *); | 53 | void mu_authority_destroy (mu_authority_t *, void *); |
54 | extern void *mu_authority_get_owner (mu_authority_t); | 54 | void *mu_authority_get_owner (mu_authority_t); |
55 | extern int mu_authority_set_ticket (mu_authority_t, mu_ticket_t); | 55 | int mu_authority_set_ticket (mu_authority_t, mu_ticket_t); |
56 | extern int mu_authority_get_ticket (mu_authority_t, mu_ticket_t *); | 56 | int mu_authority_get_ticket (mu_authority_t, mu_ticket_t *); |
57 | extern int mu_authority_authenticate (mu_authority_t); | 57 | int mu_authority_authenticate (mu_authority_t); |
58 | extern int mu_authority_set_authenticate (mu_authority_t, | 58 | int mu_authority_set_authenticate (mu_authority_t, |
59 | int (*_authenticate) (mu_authority_t), void *); | 59 | int (*_authenticate) (mu_authority_t), |
60 | void *); | ||
60 | 61 | ||
61 | extern int mu_authority_create_null (mu_authority_t *pauthority, void *owner); | 62 | int mu_authority_create_null (mu_authority_t *pauthority, void *owner); |
62 | 63 | ||
63 | extern int mu_wicket_create (mu_wicket_t *); | 64 | int mu_wicket_create (mu_wicket_t *); |
64 | extern int mu_wicket_get_ticket (mu_wicket_t wicket, const char *user, | 65 | int mu_wicket_get_ticket (mu_wicket_t wicket, const char *user, |
65 | mu_ticket_t *pticket); | 66 | mu_ticket_t *pticket); |
66 | extern int mu_wicket_ref (mu_wicket_t wicket); | 67 | int mu_wicket_ref (mu_wicket_t wicket); |
67 | extern int mu_wicket_unref (mu_wicket_t wicket); | 68 | int mu_wicket_unref (mu_wicket_t wicket); |
68 | extern void mu_wicket_destroy (mu_wicket_t *pwicket); | 69 | void mu_wicket_destroy (mu_wicket_t *pwicket); |
69 | extern int mu_wicket_set_destroy (mu_wicket_t wicket, | 70 | int mu_wicket_set_destroy (mu_wicket_t wicket, |
70 | void (*_destroy) (mu_wicket_t)); | 71 | void (*_destroy) (mu_wicket_t)); |
71 | extern int mu_wicket_set_data (mu_wicket_t wicket, void *data); | 72 | int mu_wicket_set_data (mu_wicket_t wicket, void *data); |
72 | extern void *mu_wicket_get_data (mu_wicket_t wicket); | 73 | void *mu_wicket_get_data (mu_wicket_t wicket); |
73 | extern int mu_wicket_set_get_ticket (mu_wicket_t wicket, | 74 | int mu_wicket_set_get_ticket (mu_wicket_t wicket, |
74 | int (*_get_ticket) (mu_wicket_t, void *, | 75 | int (*_get_ticket) (mu_wicket_t, void *, |
75 | const char *, mu_ticket_t *)); | 76 | const char *, mu_ticket_t *)); |
76 | extern int mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename); | 77 | int mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename); |
77 | 78 | ||
79 | struct mu_debug_locus; | ||
80 | int mu_wicket_stream_match_url (mu_stream_t stream, struct mu_debug_locus *loc, | ||
81 | mu_url_t url, mu_url_t *pticket_url); | ||
82 | int mu_wicket_file_match_url (const char *name, mu_url_t url, | ||
83 | mu_url_t *pticket_url); | ||
84 | |||
85 | |||
78 | #ifdef __cplusplus | 86 | #ifdef __cplusplus |
79 | } | 87 | } |
80 | #endif | 88 | #endif | ... | ... |
... | @@ -104,7 +104,7 @@ int mu_url_is_same_port (mu_url_t, mu_url_t); | ... | @@ -104,7 +104,7 @@ int mu_url_is_same_port (mu_url_t, mu_url_t); |
104 | char *mu_url_decode_len (const char *s, size_t len); | 104 | char *mu_url_decode_len (const char *s, size_t len); |
105 | char *mu_url_decode (const char *s); | 105 | char *mu_url_decode (const char *s); |
106 | 106 | ||
107 | int mu_url_is_ticket (mu_url_t ticket, mu_url_t url); | 107 | int mu_url_matches_ticket (mu_url_t ticket, mu_url_t url, int *wcn); |
108 | int mu_url_init (mu_url_t url, int port, const char *scheme); | 108 | int mu_url_init (mu_url_t url, int port, const char *scheme); |
109 | 109 | ||
110 | #ifdef __cplusplus | 110 | #ifdef __cplusplus | ... | ... |
... | @@ -316,13 +316,18 @@ mu_url_parse (mu_url_t url) | ... | @@ -316,13 +316,18 @@ mu_url_parse (mu_url_t url) |
316 | char *newname; | 316 | char *newname; |
317 | 317 | ||
318 | memset (url->name + pstart, 0, plen); | 318 | memset (url->name + pstart, 0, plen); |
319 | newname = realloc (url->name, len); | 319 | if (len > nlen + 1) |
320 | if (!newname) | 320 | { |
321 | goto CLEANUP; | 321 | newname = realloc (url->name, len); |
322 | if (!newname) | ||
323 | goto CLEANUP; | ||
324 | url->name = newname; | ||
325 | } | ||
326 | else | ||
327 | newname = url->name; | ||
322 | memmove (newname + pstart + PASS_REPL_LEN, newname + pstart + plen, | 328 | memmove (newname + pstart + PASS_REPL_LEN, newname + pstart + plen, |
323 | nlen - (pstart + plen) + 1); | 329 | nlen - (pstart + plen) + 1); |
324 | memcpy (newname + pstart, PASS_REPL, PASS_REPL_LEN); | 330 | memcpy (newname + pstart, PASS_REPL, PASS_REPL_LEN); |
325 | url->name = newname; | ||
326 | } | 331 | } |
327 | 332 | ||
328 | /* Dup the strings we found. We wouldn't have to do this | 333 | /* Dup the strings we found. We wouldn't have to do this |
... | @@ -959,44 +964,68 @@ mu_url_decode (const char *s) | ... | @@ -959,44 +964,68 @@ mu_url_decode (const char *s) |
959 | return mu_url_decode_len (s, strlen (s)); | 964 | return mu_url_decode_len (s, strlen (s)); |
960 | } | 965 | } |
961 | 966 | ||
962 | static int | 967 | #define is_wildcard(s) ((s)[0] == '*' && s[1] == 0) |
963 | defined (const char *s) | ||
964 | { | ||
965 | if (s && strcmp ("*", s) != 0) | ||
966 | return 1; | ||
967 | return 0; | ||
968 | } | ||
969 | 968 | ||
970 | int | 969 | int |
971 | mu_url_is_ticket (mu_url_t ticket, mu_url_t url) | 970 | mu_url_matches_ticket (mu_url_t ticket, mu_url_t url, int *pwc) |
972 | { | 971 | { |
973 | if (!ticket || !url) | 972 | int wcnt = 0; |
973 | |||
974 | if (is_wildcard (ticket->scheme)) | ||
975 | wcnt++; | ||
976 | else if (mu_c_strcasecmp (ticket->scheme, url->scheme)) | ||
974 | return 0; | 977 | return 0; |
975 | 978 | ||
976 | /* If ticket has a scheme, host, port, or path, then the queries | 979 | if (ticket->flags & MU_URL_HOST) |
977 | equivalent must be defined and match. */ | ||
978 | if (defined (ticket->scheme)) | ||
979 | { | 980 | { |
980 | if (!url->scheme || mu_c_strcasecmp (ticket->scheme, url->scheme) != 0) | 981 | if (is_wildcard (ticket->host)) |
982 | wcnt++; | ||
983 | else if (url->flags & MU_URL_HOST) | ||
984 | { | ||
985 | if (mu_c_strcasecmp (ticket->host, url->host)) | ||
986 | /* FIXME: Compare IP addresses */ | ||
987 | return 0; | ||
988 | } | ||
989 | else | ||
981 | return 0; | 990 | return 0; |
982 | } | 991 | } |
983 | if (defined (ticket->host)) | 992 | else |
993 | wcnt++; | ||
994 | |||
995 | if (ticket->flags & MU_URL_PORT) | ||
984 | { | 996 | { |
985 | if (!url->host || mu_c_strcasecmp (ticket->host, url->host) != 0) | 997 | /* FIXME: No way to put a wildcard in the ticket file */ |
986 | return 0; | 998 | if (url->port & MU_URL_PORT) |
999 | { | ||
1000 | if (ticket->port != url->port) | ||
1001 | return 0; | ||
1002 | else | ||
1003 | wcnt++; | ||
1004 | } | ||
987 | } | 1005 | } |
988 | if (ticket->port && ticket->port != url->port) | 1006 | else |
989 | return 0; | 1007 | wcnt++; |
990 | /* If ticket has a user or pass, but url doesn't, that's OK, we were | 1008 | |
991 | urling for this info. But if url does have a user/pass, it | 1009 | if (ticket->flags & MU_URL_USER) |
992 | must match the ticket. */ | ||
993 | if (url->user) | ||
994 | { | 1010 | { |
995 | if (defined (ticket->user) && strcmp (ticket->user, url->user) != 0) | 1011 | if (is_wildcard (ticket->user)) |
996 | return 0; | 1012 | wcnt += 2; |
1013 | |||
1014 | /* If ticket has a user or pass, but url doesn't, that's OK, we were | ||
1015 | looking for this info. But if url does have a user/pass, it | ||
1016 | must match the ticket. */ | ||
1017 | else if (url->flags & MU_URL_USER) | ||
1018 | { | ||
1019 | if (strcmp (ticket->user, url->user)) | ||
1020 | return 0; | ||
1021 | } | ||
997 | } | 1022 | } |
998 | 1023 | else | |
1024 | wcnt++; | ||
1025 | |||
999 | /* Guess it matches. */ | 1026 | /* Guess it matches. */ |
1027 | if (pwc) | ||
1028 | *pwc = wcnt; | ||
1000 | return 1; | 1029 | return 1; |
1001 | } | 1030 | } |
1002 | 1031 | ... | ... |
... | @@ -34,6 +34,9 @@ | ... | @@ -34,6 +34,9 @@ |
34 | #include <mailutils/util.h> | 34 | #include <mailutils/util.h> |
35 | #include <mailutils/mu_auth.h> | 35 | #include <mailutils/mu_auth.h> |
36 | #include <mailutils/stream.h> | 36 | #include <mailutils/stream.h> |
37 | #include <mailutils/cstr.h> | ||
38 | #include <mailutils/nls.h> | ||
39 | #include <mailutils/errno.h> | ||
37 | 40 | ||
38 | #include <mailutils/sys/auth.h> | 41 | #include <mailutils/sys/auth.h> |
39 | #include <mailutils/sys/url.h> | 42 | #include <mailutils/sys/url.h> |
... | @@ -50,7 +53,8 @@ mu_wicket_create (mu_wicket_t *pwicket) | ... | @@ -50,7 +53,8 @@ mu_wicket_create (mu_wicket_t *pwicket) |
50 | } | 53 | } |
51 | 54 | ||
52 | int | 55 | int |
53 | mu_wicket_get_ticket (mu_wicket_t wicket, const char *user, mu_ticket_t *pticket) | 56 | mu_wicket_get_ticket (mu_wicket_t wicket, const char *user, |
57 | mu_ticket_t *pticket) | ||
54 | { | 58 | { |
55 | if (!wicket) | 59 | if (!wicket) |
56 | return EINVAL; | 60 | return EINVAL; |
... | @@ -168,8 +172,6 @@ file_ticket_destroy (mu_ticket_t ticket) | ... | @@ -168,8 +172,6 @@ file_ticket_destroy (mu_ticket_t ticket) |
168 | } | 172 | } |
169 | } | 173 | } |
170 | 174 | ||
171 | static int get_ticket_url (mu_ticket_t ticket, mu_url_t url, mu_url_t *pticket_url); | ||
172 | |||
173 | int | 175 | int |
174 | file_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge, | 176 | file_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge, |
175 | char **pplain, mu_secret_t *psec) | 177 | char **pplain, mu_secret_t *psec) |
... | @@ -178,7 +180,7 @@ file_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge, | ... | @@ -178,7 +180,7 @@ file_ticket_get_cred (mu_ticket_t ticket, mu_url_t url, const char *challenge, |
178 | 180 | ||
179 | if (!ft->tickurl) | 181 | if (!ft->tickurl) |
180 | { | 182 | { |
181 | int rc = get_ticket_url (ticket, url, &ft->tickurl); | 183 | int rc = mu_wicket_file_match_url (ft->filename, url, &ft->tickurl); |
182 | if (rc) | 184 | if (rc) |
183 | return rc; | 185 | return rc; |
184 | } | 186 | } |
... | @@ -241,37 +243,28 @@ _file_wicket_get_ticket (mu_wicket_t wicket, void *data, | ... | @@ -241,37 +243,28 @@ _file_wicket_get_ticket (mu_wicket_t wicket, void *data, |
241 | return 0; | 243 | return 0; |
242 | } | 244 | } |
243 | 245 | ||
244 | static int | 246 | int |
245 | get_ticket_url (mu_ticket_t ticket, mu_url_t url, mu_url_t *pticket_url) | 247 | mu_wicket_stream_match_url (mu_stream_t stream, struct mu_debug_locus *loc, |
248 | mu_url_t url, mu_url_t *pticket_url) | ||
246 | { | 249 | { |
247 | mu_stream_t stream; | ||
248 | struct file_ticket *ft = mu_ticket_get_data (ticket); | ||
249 | int rc; | 250 | int rc; |
250 | mu_url_t u = NULL; | 251 | mu_url_t u = NULL; |
251 | char *buf = NULL; | 252 | char *buf = NULL; |
252 | size_t bufsize = 0; | 253 | size_t bufsize = 0; |
253 | size_t len; | 254 | size_t len; |
254 | 255 | mu_url_t pret = NULL; | |
255 | rc = mu_file_stream_create (&stream, ft->filename, MU_STREAM_READ); | 256 | int weight = 0; |
256 | if (rc) | 257 | int line = loc->line; |
257 | return rc; | ||
258 | 258 | ||
259 | while ((rc = mu_stream_getline (stream, &buf, &bufsize, &len)) == 0 | 259 | while ((rc = mu_stream_getline (stream, &buf, &bufsize, &len)) == 0 |
260 | && len > 0) | 260 | && len > 0) |
261 | { | 261 | { |
262 | char *p; | 262 | char *p; |
263 | int err; | 263 | int err; |
264 | int n; | ||
264 | 265 | ||
265 | /* Truncate a trailing newline. */ | 266 | loc->line++; |
266 | if (len && buf[len - 1] == '\n') | 267 | p = mu_str_stripws (buf); |
267 | buf[--len] = 0; | ||
268 | |||
269 | /* Skip leading spaces */ | ||
270 | for (p = buf; *p == ' ' || *p == '\t'; p++) | ||
271 | ; | ||
272 | /* Skip trailing spaces */ | ||
273 | for (; len > 0 && (p[len-1] == ' ' || p[len-1] == '\t'); ) | ||
274 | p[--len] = 0; | ||
275 | 268 | ||
276 | /* Skip empty lines and comments. */ | 269 | /* Skip empty lines and comments. */ |
277 | if (*p == 0 || *p == '#') | 270 | if (*p == 0 || *p == '#') |
... | @@ -280,43 +273,42 @@ get_ticket_url (mu_ticket_t ticket, mu_url_t url, mu_url_t *pticket_url) | ... | @@ -280,43 +273,42 @@ get_ticket_url (mu_ticket_t ticket, mu_url_t url, mu_url_t *pticket_url) |
280 | if ((err = mu_url_create (&u, p)) != 0) | 273 | if ((err = mu_url_create (&u, p)) != 0) |
281 | { | 274 | { |
282 | /* Skip erroneous entry */ | 275 | /* Skip erroneous entry */ |
283 | /* FIXME: Error message */ | 276 | mu_error (_("%s:%u: cannot create URL: %s"), |
277 | loc->file, loc->line, mu_strerror (err)); | ||
284 | continue; | 278 | continue; |
285 | } | 279 | } |
286 | if ((err = mu_url_parse (u)) != 0) | 280 | if ((err = mu_url_parse (u)) != 0) |
287 | { | 281 | { |
288 | /* FIXME: See above */ | 282 | mu_error (_("%s:%u: cannot parse URL: %s"), |
283 | loc->file, loc->line, mu_strerror (err)); | ||
289 | mu_url_destroy (&u); | 284 | mu_url_destroy (&u); |
290 | continue; | 285 | continue; |
291 | } | 286 | } |
292 | 287 | ||
293 | if (!mu_url_is_ticket (u, url)) | 288 | if (!mu_url_matches_ticket (u, url, &n)) |
294 | { | 289 | { |
295 | mu_url_destroy (&u); | 290 | mu_url_destroy (&u); |
296 | continue; | 291 | continue; |
297 | } | 292 | } |
298 | 293 | ||
299 | if (ft->user) | 294 | if (!pret || n < weight) |
300 | { | 295 | { |
301 | if (u->name && strcmp (u->name, "*") != 0 | 296 | pret = u; |
302 | && strcmp (ft->user, u->name) != 0) | 297 | weight = n; |
303 | { | 298 | line = loc->line; |
304 | mu_url_destroy (&u); | 299 | if (weight == 0) |
305 | continue; | 300 | break; |
306 | } | ||
307 | } | 301 | } |
308 | |||
309 | break; | ||
310 | } | 302 | } |
311 | mu_stream_close (stream); | ||
312 | free (buf); | 303 | free (buf); |
313 | 304 | ||
314 | mu_stream_destroy (&stream); | ||
315 | |||
316 | if (rc == 0) | 305 | if (rc == 0) |
317 | { | 306 | { |
318 | if (u) | 307 | if (pret) |
319 | *pticket_url = u; | 308 | { |
309 | *pticket_url = pret; | ||
310 | loc->line = line; | ||
311 | } | ||
320 | else | 312 | else |
321 | rc = MU_ERR_NOENT; | 313 | rc = MU_ERR_NOENT; |
322 | } | 314 | } |
... | @@ -325,6 +317,25 @@ get_ticket_url (mu_ticket_t ticket, mu_url_t url, mu_url_t *pticket_url) | ... | @@ -325,6 +317,25 @@ get_ticket_url (mu_ticket_t ticket, mu_url_t url, mu_url_t *pticket_url) |
325 | } | 317 | } |
326 | 318 | ||
327 | int | 319 | int |
320 | mu_wicket_file_match_url (const char *name, mu_url_t url, | ||
321 | mu_url_t *pticket_url) | ||
322 | { | ||
323 | mu_stream_t stream; | ||
324 | int rc; | ||
325 | struct mu_debug_locus loc; | ||
326 | |||
327 | rc = mu_file_stream_create (&stream, name, MU_STREAM_READ); | ||
328 | if (rc) | ||
329 | return rc; | ||
330 | loc.file = name; | ||
331 | loc.line = 0; | ||
332 | rc = mu_wicket_stream_match_url (stream, &loc, url, pticket_url); | ||
333 | mu_stream_close (stream); | ||
334 | mu_stream_destroy (&stream); | ||
335 | return rc; | ||
336 | } | ||
337 | |||
338 | int | ||
328 | mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename) | 339 | mu_file_wicket_create (mu_wicket_t *pwicket, const char *filename) |
329 | { | 340 | { |
330 | mu_wicket_t wicket; | 341 | mu_wicket_t wicket; | ... | ... |
... | @@ -47,11 +47,12 @@ noinst_PROGRAMS = \ | ... | @@ -47,11 +47,12 @@ noinst_PROGRAMS = \ |
47 | fltst\ | 47 | fltst\ |
48 | listop\ | 48 | listop\ |
49 | mailcap\ | 49 | mailcap\ |
50 | url-parse | 50 | url-parse\ |
51 | wicket | ||
51 | 52 | ||
52 | LDADD = ${MU_LIB_MAILUTILS} | 53 | LDADD = ${MU_LIB_MAILUTILS} |
53 | 54 | ||
54 | EXTRA_DIST += Encode Decode | 55 | EXTRA_DIST += Encode Decode Wicketfile |
55 | 56 | ||
56 | ## ------------ ## | 57 | ## ------------ ## |
57 | ## Test suite. ## | 58 | ## Test suite. ## |
... | @@ -68,7 +69,8 @@ TESTSUITE_AT = \ | ... | @@ -68,7 +69,8 @@ TESTSUITE_AT = \ |
68 | list.at\ | 69 | list.at\ |
69 | mailcap.at\ | 70 | mailcap.at\ |
70 | testsuite.at\ | 71 | testsuite.at\ |
71 | url.at | 72 | url.at\ |
73 | wicket.at | ||
72 | 74 | ||
73 | TESTSUITE = $(srcdir)/testsuite | 75 | TESTSUITE = $(srcdir)/testsuite |
74 | M4=m4 | 76 | M4=m4 | ... | ... |
libmailutils/tests/Wicketfile
0 → 100644
... | @@ -63,4 +63,5 @@ m4_include([base64d.at]) | ... | @@ -63,4 +63,5 @@ m4_include([base64d.at]) |
63 | m4_include([decode2047.at]) | 63 | m4_include([decode2047.at]) |
64 | m4_include([encode2047.at]) | 64 | m4_include([encode2047.at]) |
65 | m4_include([fromflt.at]) | 65 | m4_include([fromflt.at]) |
66 | m4_include([wicket.at]) | ||
66 | 67 | ... | ... |
libmailutils/tests/wicket.at
0 → 100644
1 | # This file is part of GNU Mailutils. -*- Autotest -*- | ||
2 | # Copyright (C) 2010 Free Software Foundation, Inc. | ||
3 | # | ||
4 | # GNU Mailutils is free software; you can redistribute it and/or | ||
5 | # modify it under the terms of the GNU General Public License as | ||
6 | # published by the Free Software Foundation; either version 3, or (at | ||
7 | # your option) any later version. | ||
8 | # | ||
9 | # GNU Mailutils is distributed in the hope that it will be useful, but | ||
10 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | # General Public License for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License | ||
15 | # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | dnl ------------------------------------------------------------ | ||
18 | dnl TESTWICKET(URL, [KW = `'], [STDOUT = `'], | ||
19 | dnl [STDERR = `'], [RUN-IF-FAIL], [RUN-IF-PASS]) | ||
20 | dnl | ||
21 | m4_pushdef([TESTWICKET],[ | ||
22 | AT_SETUP([Wicket: [$1]]) | ||
23 | AT_KEYWORDS([wicket wicket-$2]) | ||
24 | AT_CHECK([wicket $abs_top_srcdir/libmailutils/tests/Wicketfile "$1" | \ | ||
25 | sed "s|$abs_top_srcdir/libmailutils/tests/Wicketfile|Wicketfile|"], | ||
26 | [0], | ||
27 | [$3],[$4],[$5],[$6]) | ||
28 | AT_CLEANUP]) | ||
29 | |||
30 | TESTWICKET([pop://localhost],[00], | ||
31 | [pop://localhost matches pop://gray:***@localhost at Wicketfile:4 | ||
32 | ]) | ||
33 | TESTWICKET([pop://smith@localhost],[01], | ||
34 | [pop://smith@localhost matches pop://*:***;AUTH=+APOP@localhost at Wicketfile:3 | ||
35 | ]) | ||
36 | TESTWICKET([pop://foo@localhost],[02], | ||
37 | [pop://foo@localhost matches *://foo:***@localhost at Wicketfile:2 | ||
38 | ]) | ||
39 | TESTWICKET([pop://gnu.org],[03], | ||
40 | [pop://gnu.org matches pop://gray:***@gnu.org at Wicketfile:7 | ||
41 | ]) | ||
42 | TESTWICKET([smtp://gnu.org],[04], | ||
43 | [smtp://gnu.org matches smtp://gray:***@gnu.org at Wicketfile:6 | ||
44 | ]) | ||
45 | TESTWICKET([smtp://gray@gnu.org],[05], | ||
46 | [smtp://gray@gnu.org matches smtp://gray:***@gnu.org at Wicketfile:6 | ||
47 | ]) | ||
48 | TESTWICKET([smtp://localhost],[06], | ||
49 | [smtp://localhost matches smtp://gray:***@localhost at Wicketfile:5 | ||
50 | ]) | ||
51 | |||
52 | |||
... | \ No newline at end of file | ... | \ No newline at end of file |
libmailutils/tests/wicket.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2002, 2005, 2007, 2010 Free Software | ||
3 | Foundation, Inc. | ||
4 | |||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 3, or (at your option) | ||
8 | any later version. | ||
9 | |||
10 | GNU Mailutils is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | #include <unistd.h> | ||
22 | #include <stdio.h> | ||
23 | #include <mailutils/mailutils.h> | ||
24 | |||
25 | const char *name; | ||
26 | mu_stream_t stream; | ||
27 | |||
28 | void | ||
29 | match_string (const char *str) | ||
30 | { | ||
31 | int rc; | ||
32 | mu_url_t u, url; | ||
33 | struct mu_debug_locus loc; | ||
34 | |||
35 | if ((rc = mu_url_create (&u, str)) != 0) | ||
36 | { | ||
37 | fprintf (stderr, "mu_url_create %s ERROR: [%d] %s", | ||
38 | str, rc, mu_strerror (rc)); | ||
39 | return; | ||
40 | } | ||
41 | if ((rc = mu_url_parse (u)) != 0) | ||
42 | { | ||
43 | fprintf (stderr, "%s\n", mu_errname (rc)); | ||
44 | return; | ||
45 | } | ||
46 | MU_ASSERT (mu_stream_seek (stream, 0, MU_SEEK_SET, NULL)); | ||
47 | loc.file = name; | ||
48 | loc.line = 0; | ||
49 | rc = mu_wicket_stream_match_url (stream, &loc, u, &url); | ||
50 | switch (rc) | ||
51 | { | ||
52 | case 0: | ||
53 | printf ("%s matches %s at %s:%d\n", | ||
54 | mu_url_to_string (u), mu_url_to_string (url), | ||
55 | loc.file, loc.line); | ||
56 | mu_url_destroy (&url); | ||
57 | break; | ||
58 | |||
59 | case MU_ERR_NOENT: | ||
60 | printf ("no matches for %s\n", mu_url_to_string (u)); | ||
61 | break; | ||
62 | |||
63 | default: | ||
64 | mu_error ("mu_wicket_stream_match_url: %s", mu_strerror (rc)); | ||
65 | exit (1); | ||
66 | } | ||
67 | mu_url_destroy (&u); | ||
68 | } | ||
69 | |||
70 | |||
71 | int | ||
72 | main (int argc, char **argv) | ||
73 | { | ||
74 | if (argc < 2) | ||
75 | { | ||
76 | fprintf (stderr, "usage: %s filename [url [url...]]\n", argv[0]); | ||
77 | return 1; | ||
78 | } | ||
79 | |||
80 | name = argv[1]; | ||
81 | MU_ASSERT (mu_file_stream_create (&stream, name, MU_STREAM_READ)); | ||
82 | |||
83 | if (argc > 2) | ||
84 | { | ||
85 | int i; | ||
86 | |||
87 | for (i = 2; i < argc; i++) | ||
88 | match_string (argv[i]); | ||
89 | } | ||
90 | else | ||
91 | { | ||
92 | mu_stream_t in; | ||
93 | char *buf = NULL; | ||
94 | size_t size = 0, n; | ||
95 | int rc; | ||
96 | |||
97 | MU_ASSERT (mu_stdio_stream_create (&in, MU_STDIN_FD, 0)); | ||
98 | |||
99 | while ((rc = mu_stream_getline (in, &buf, &size, &n)) == 0 | ||
100 | && n > 0) | ||
101 | match_string (mu_str_stripws (buf)); | ||
102 | free (buf); | ||
103 | mu_stream_destroy (&in); | ||
104 | } | ||
105 | mu_stream_destroy (&stream); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | |||
110 | |||
111 |
-
Please register or sign in to post a comment