Postfix3.3.1
cleanup_masquerade.c
[詳解]
1 /*++
2 /* NAME
3 /* cleanup_masquerade 3
4 /* SUMMARY
5 /* address masquerading
6 /* SYNOPSIS
7 /* #include <cleanup.h>
8 /*
9 /* int cleanup_masquerade_external(addr, masq_domains)
10 /* VSTRING *addr;
11 /* ARGV *masq_domains;
12 /*
13 /* int cleanup_masquerade_internal(addr, masq_domains)
14 /* VSTRING *addr;
15 /* ARGV *masq_domains;
16 /*
17 /* int cleanup_masquerade_tree(tree, masq_domains)
18 /* TOK822 *tree;
19 /* ARGV *masq_domains;
20 /* DESCRIPTION
21 /* This module masquerades addresses, that is, it strips subdomains
22 /* below domain names that are listed in the masquerade_domains
23 /* configuration parameter, except for user names listed in the
24 /* masquerade_exceptions configuration parameter.
25 /* These functions return non-zero when the address was changed.
26 /*
27 /* cleanup_masquerade_external() rewrites the external (quoted) string
28 /* form of an address.
29 /*
30 /* cleanup_masquerade_internal() is a wrapper around the
31 /* cleanup_masquerade_external() routine that transforms from
32 /* internal (quoted) string form to external form and back.
33 /*
34 /* cleanup_masquerade_tree() is a wrapper around the
35 /* cleanup_masquerade_external() routine that transforms from
36 /* internal parse tree form to external form and back.
37 /* DIAGNOSTICS
38 /* LICENSE
39 /* .ad
40 /* .fi
41 /* The Secure Mailer license must be distributed with this software.
42 /* AUTHOR(S)
43 /* Wietse Venema
44 /* IBM T.J. Watson Research
45 /* P.O. Box 704
46 /* Yorktown Heights, NY 10598, USA
47 /*--*/
48 
49 /* System library. */
50 
51 #include <sys_defs.h>
52 #include <string.h>
53 
54 /* Utility library. */
55 
56 #include <msg.h>
57 #include <vstring.h>
58 #include <argv.h>
59 #include <htable.h>
60 #include <mymalloc.h>
61 #include <stringops.h>
62 
63 /* Global library. */
64 
65 #include <mail_params.h>
66 #include <tok822.h>
67 #include <quote_822_local.h>
68 
69 /* Application-specific. */
70 
71 #include "cleanup.h"
72 
73 #define STR vstring_str
74 
75 /* cleanup_masquerade_external - masquerade address external form */
76 
78  ARGV *masq_domains)
79 {
80  char *domain;
81  ssize_t domain_len;
82  char **masqp;
83  char *masq;
84  ssize_t masq_len;
85  char *parent;
86  int truncate;
87  int did_rewrite = 0;
88 
89  /* Stuff for excluded names. */
90  char *name;
91  ssize_t name_len;
92  int excluded;
93 
94  /*
95  * Find the domain part.
96  */
97  if ((domain = strrchr(STR(addr), '@')) == 0)
98  return (0);
99  name_len = domain - STR(addr);
100  domain = casefold(state->temp2, domain + 1);
101  domain_len = strlen(domain);
102 
103  /*
104  * Don't masquerade excluded names (regardless of domain).
105  */
106  if (*var_masq_exceptions) {
107  name = mystrndup(STR(addr), name_len);
108  excluded = (string_list_match(cleanup_masq_exceptions, name) != 0);
109  myfree(name);
110  if (cleanup_masq_exceptions->error) {
111  msg_info("%s: %s map lookup problem -- "
112  "message not accepted, try again later",
113  state->queue_id, VAR_MASQ_EXCEPTIONS);
114  state->errs |= CLEANUP_STAT_WRITE;
115  }
116  if (excluded)
117  return (0);
118  }
119 
120  /*
121  * If any parent domain matches the list of masquerade domains, replace
122  * the domain in the address and terminate. If the domain matches a
123  * masquerade domain, leave it alone. Order of specification matters.
124  */
125  for (masqp = masq_domains->argv; (masq = *masqp) != 0; masqp++) {
126  for (truncate = 1; *masq == '!'; masq++)
127  truncate = !truncate;
128  masq = casefold(state->temp1, masq);
129  masq_len = strlen(masq);
130  if (masq_len == 0)
131  continue;
132  if (masq_len == domain_len) {
133  if (strcmp(masq, domain) == 0)
134  break;
135  } else if (masq_len < domain_len) {
136  parent = domain + domain_len - masq_len;
137  if (parent[-1] == '.' && strcmp(masq, parent) == 0) {
138  if (truncate) {
139  if (msg_verbose)
140  msg_info("masquerade: %s -> %s", domain, masq);
141  vstring_truncate(addr, name_len + 1);
142  vstring_strcat(addr, masq);
143  did_rewrite = 1;
144  }
145  break;
146  }
147  }
148  }
149  return (did_rewrite);
150 }
151 
152 /* cleanup_masquerade_tree - masquerade address node */
153 
155  ARGV *masq_domains)
156 {
157  VSTRING *temp = vstring_alloc(100);
158  int did_rewrite;
159 
161  did_rewrite = cleanup_masquerade_external(state, temp, masq_domains);
162  tok822_free_tree(tree->head);
163  tree->head = tok822_scan(STR(temp), &tree->tail);
164 
165  vstring_free(temp);
166  return (did_rewrite);
167 }
168 
169 /* cleanup_masquerade_internal - masquerade address internal form */
170 
172  ARGV *masq_domains)
173 {
174  VSTRING *temp = vstring_alloc(100);
175  int did_rewrite;
176 
177  quote_822_local(temp, STR(addr));
178  did_rewrite = cleanup_masquerade_external(state, temp, masq_domains);
179  unquote_822_local(addr, STR(temp));
180 
181  vstring_free(temp);
182  return (did_rewrite);
183 }
184 
185  /*
186  * Code for stand-alone testing. Instead of using main.cf, specify the strip
187  * list and the candidate domain on the command line. Specify null arguments
188  * for data that should be empty.
189  */
190 #ifdef TEST
191 
192 #include <vstream.h>
193 
194 char *var_masq_exceptions;
196 
197 int main(int argc, char **argv)
198 {
199  VSTRING *addr;
200  ARGV *masq_domains;
201  CLEANUP_STATE state;
202 
203  if (argc != 4)
204  msg_fatal("usage: %s exceptions masquerade_list address", argv[0]);
205 
206  var_masq_exceptions = argv[1];
210  masq_domains = argv_split(argv[2], CHARS_COMMA_SP);
211  addr = vstring_alloc(1);
212  if (strchr(argv[3], '@') == 0)
213  msg_fatal("address must be in user@domain form");
214  vstring_strcpy(addr, argv[3]);
215 
216  vstream_printf("----------\n");
217  vstream_printf("exceptions: %s\n", argv[1]);
218  vstream_printf("masq_list: %s\n", argv[2]);
219  vstream_printf("address: %s\n", argv[3]);
220 
221  state.errs = 0;
222  state.queue_id = "NOQUEUE";
223  state.temp1 = vstring_alloc(100);
224  state.temp2 = vstring_alloc(100);
225  cleanup_masquerade_external(&state, addr, masq_domains);
226 
227  vstream_printf("result: %s\n", STR(addr));
228  vstream_printf("errs: %d\n", state.errs);
230 
231  vstring_free(state.temp1);
232  vstring_free(state.temp2);
233  vstring_free(addr);
234  argv_free(masq_domains);
235 
236  return (0);
237 }
238 
239 #endif
int msg_verbose
Definition: msg.c:177
void myfree(void *ptr)
Definition: mymalloc.c:207
#define MATCH_FLAG_RETURN
Definition: match_list.h:40
ARGV * argv_free(ARGV *argvp)
Definition: argv.c:136
Definition: argv.h:17
#define VSTREAM_OUT
Definition: vstream.h:67
#define tok822_scan(cp, ptr)
Definition: tok822.h:83
#define STRING_LIST
Definition: string_list.h:22
int main(int argc, char **argv)
Definition: anvil.c:1010
Definition: tok822.h:27
char ** argv
Definition: argv.h:20
VSTRING * unquote_822_local(VSTRING *dst, const char *mbox)
VSTRING * vstring_truncate(VSTRING *vp, ssize_t len)
Definition: vstring.c:415
VSTRING * temp2
Definition: cleanup.h:50
STRING_LIST * cleanup_masq_exceptions
Definition: cleanup_init.c:260
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
Definition: vstring.c:431
TOK822 * tok822_free_tree(TOK822 *)
Definition: tok822_tree.c:262
#define casefold(dst, src)
Definition: stringops.h:67
#define string_list_init(o, f, p)
Definition: string_list.h:24
#define string_list_match
Definition: string_list.h:26
#define STR
int cleanup_masquerade_external(CLEANUP_STATE *state, VSTRING *addr, ARGV *masq_domains)
struct TOK822 * head
Definition: tok822.h:32
VSTREAM * vstream_printf(const char *fmt,...)
Definition: vstream.c:1335
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
VSTRING * tok822_externalize(VSTRING *, TOK822 *, int)
Definition: tok822_parse.c:270
char * queue_id
Definition: cleanup.h:56
int cleanup_masquerade_internal(CLEANUP_STATE *state, VSTRING *addr, ARGV *masq_domains)
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
#define CHARS_COMMA_SP
Definition: sys_defs.h:1761
int cleanup_masquerade_tree(CLEANUP_STATE *state, TOK822 *tree, ARGV *masq_domains)
int vstream_fflush(VSTREAM *stream)
Definition: vstream.c:1257
char * mystrndup(const char *str, ssize_t len)
Definition: mymalloc.c:242
char * var_masq_exceptions
Definition: cleanup_init.c:131
ARGV * argv_split(const char *, const char *)
Definition: argv_split.c:63
VSTRING * temp1
Definition: cleanup.h:49
#define TOK822_STR_DEFL
Definition: tok822.h:91
#define quote_822_local(dst, src)
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
#define VAR_MASQ_EXCEPTIONS
Definition: mail_params.h:193
#define CLEANUP_STAT_WRITE
Definition: cleanup_user.h:58
VSTRING * vstring_strcat(VSTRING *vp, const char *src)
Definition: vstring.c:459
void msg_info(const char *fmt,...)
Definition: msg.c:199
struct TOK822 * tail
Definition: tok822.h:33