1 /*        $NetBSD: cleanup.h,v 1.11 2025/02/25 19:15:44 christos Exp $          */
2 
3 /*++
4 /* NAME
5 /*        cleanup 3h
6 /* SUMMARY
7 /*        canonicalize and enqueue message
8 /* SYNOPSIS
9 /*        #include "cleanup.h"
10 /* DESCRIPTION
11 /* .nf
12 
13  /*
14   * System library.
15   */
16 #include <sys/time.h>
17 #include <stdint.h>                     /* C99 uint64_t */
18 
19  /*
20   * Utility library.
21   */
22 #include <vstring.h>
23 #include <vstream.h>
24 #include <argv.h>
25 #include <nvtable.h>
26 
27  /*
28   * Global library.
29   */
30 #include <maps.h>
31 #include <tok822.h>
32 #include <been_here.h>
33 #include <mail_stream.h>
34 #include <mail_conf.h>
35 #include <mime_state.h>
36 #include <string_list.h>
37 #include <cleanup_user.h>
38 #include <header_body_checks.h>
39 #include <dsn_mask.h>
40 
41  /*
42   * Milter library.
43   */
44 #include <milter.h>
45 
46  /*
47   * These state variables are accessed by many functions, and there is only
48   * one instance of each per message.
49   */
50 typedef struct CLEANUP_STATE {
51     VSTRING *attr_buf;                            /* storage for named attribute */
52     VSTRING *temp1;                     /* scratch buffer, local use only */
53     VSTRING *temp2;                     /* scratch buffer, local use only */
54     VSTRING *temp3;                     /* scratch buffer, local use only */
55     VSTRING *stripped_buf;              /* character stripped input */
56     VSTREAM *src;                       /* current input stream */
57     VSTREAM *dst;                       /* current output stream */
58     MAIL_STREAM *handle;                /* mail stream handle */
59     char   *queue_name;                           /* queue name */
60     char   *queue_id;                             /* queue file basename */
61     struct timeval arrival_time;        /* arrival time */
62     char   *fullname;                             /* envelope sender full name */
63     char   *sender;                     /* envelope sender address */
64     char   *recip;                      /* envelope recipient address */
65     char   *orig_rcpt;                            /* original recipient address */
66     char   *return_receipt;             /* return-receipt address */
67     char   *errors_to;                            /* errors-to address */
68     ARGV   *auto_hdrs;                            /* MTA's own header(s) */
69     ARGV   *hbc_rcpt;                             /* header/body checks BCC addresses */
70     int     flags;                      /* processing options, status flags */
71     int     tflags;                     /* User- or MTA-requested tracing */
72     int     qmgr_opts;                            /* qmgr processing options */
73     int     errs;                       /* any badness experienced */
74     int     err_mask;                             /* allowed badness */
75     uint64_t headers_seen;              /* which headers were seen */
76     int     hop_count;                            /* count of received: headers */
77     char   *resent;                     /* any resent- header seen */
78     BH_TABLE *dups;                     /* recipient dup filter */
79     void    (*action) (struct CLEANUP_STATE *, int, const char *, ssize_t);
80     off_t   data_offset;                /* start of message content */
81     off_t   body_offset;                /* start of body content */
82     off_t   xtra_offset;                /* start of extra segment */
83     off_t   cont_length;                /* length including Milter edits */
84     off_t   sender_pt_offset;           /* replace sender here */
85     off_t   sender_pt_target;           /* record after sender address */
86     off_t   append_rcpt_pt_offset;      /* append recipient here */
87     off_t   append_rcpt_pt_target;      /* target of above record */
88     off_t   append_hdr_pt_offset;       /* append header here */
89     off_t   append_hdr_pt_target;       /* target of above record */
90     off_t   append_meta_pt_offset;      /* append meta record here */
91     off_t   append_meta_pt_target;      /* target of above record */
92     ssize_t rcpt_count;                           /* recipient count */
93     char   *reason;                     /* failure reason */
94     char   *smtp_reply;                           /* failure reason, SMTP-style */
95     NVTABLE *attr;                      /* queue file attribute list */
96     MIME_STATE *mime_state;             /* MIME state engine */
97     int     mime_errs;                            /* MIME error flags */
98     char   *hdr_rewrite_context;        /* header rewrite context */
99     char   *filter;                     /* from header/body patterns */
100     char   *redirect;                             /* from header/body patterns */
101     char   *message_id;                           /* from Message-ID header */
102     char   *dsn_envid;                            /* DSN envelope ID */
103     int     dsn_ret;                              /* DSN full/hdrs */
104     int     dsn_notify;                           /* DSN never/delay/fail/success */
105     char   *dsn_orcpt;                            /* DSN original recipient */
106     char   *verp_delims;                /* VERP delimiters (optional) */
107 #ifdef DELAY_ACTION
108     int     defer_delay;                /* deferred delivery */
109 #endif
110 
111     /*
112      * Miscellaneous Milter support.
113      */
114     MILTERS *milters;                             /* mail filters */
115     const char *client_name;            /* real or ersatz client */
116     const char *reverse_name;           /* real or ersatz client */
117     const char *client_addr;            /* real or ersatz client */
118     int     client_af;                            /* real or ersatz client */
119     const char *client_port;            /* real or ersatz client */
120     const char *server_addr;            /* real or ersatz server */
121     const char *server_port;            /* real or ersatz server */
122     VSTRING *milter_ext_from;           /* externalized sender */
123     VSTRING *milter_ext_rcpt;           /* externalized recipient */
124     VSTRING *milter_err_text;           /* milter call-back reply */
125     VSTRING *milter_dsn_buf;            /* Milter DSN parsing buffer */
126 
127     /*
128      * Support for Milter body replacement requests.
129      */
130     struct CLEANUP_REGION *free_regions;/* unused regions */
131     struct CLEANUP_REGION *body_regions;/* regions with body content */
132     struct CLEANUP_REGION *curr_body_region;
133 
134     /*
135      * Internationalization, RequireTLS, etc.
136      */
137     int     sendopts;                             /* what support is desired */
138 } CLEANUP_STATE;
139 
140  /*
141   * Status flags. Flags 0-15 are reserved for cleanup_user.h.
142   */
143 #define CLEANUP_FLAG_INRCPT   (1<<16)   /* Processing recipient records */
144 #define CLEANUP_FLAG_WARN_SEEN          (1<<17)   /* REC_TYPE_WARN record seen */
145 #define CLEANUP_FLAG_END_SEEN (1<<18)   /* REC_TYPE_END record seen */
146 
147  /*
148   * Bit mask for the CLEANUP_STATE.headers_seen member.
149   */
150 #define HDRS_SEEN_MASK(hval)            ((uint64_t) 1 << (hval))
151 
152  /*
153   * Mappings.
154   */
155 extern MAPS *cleanup_comm_canon_maps;
156 extern MAPS *cleanup_send_canon_maps;
157 extern MAPS *cleanup_rcpt_canon_maps;
158 extern int cleanup_comm_canon_flags;
159 extern int cleanup_send_canon_flags;
160 extern int cleanup_rcpt_canon_flags;
161 extern MAPS *cleanup_header_checks;
162 extern MAPS *cleanup_mimehdr_checks;
163 extern MAPS *cleanup_nesthdr_checks;
164 extern MAPS *cleanup_body_checks;
165 extern MAPS *cleanup_virt_alias_maps;
166 extern ARGV *cleanup_masq_domains;
167 extern STRING_LIST *cleanup_masq_exceptions;
168 extern int cleanup_masq_flags;
169 extern MAPS *cleanup_send_bcc_maps;
170 extern MAPS *cleanup_rcpt_bcc_maps;
171 
172  /*
173   * Character filters.
174   */
175 extern VSTRING *cleanup_reject_chars;
176 extern VSTRING *cleanup_strip_chars;
177 
178  /*
179   * Milters.
180   */
181 extern MILTERS *cleanup_milters;
182 
183  /*
184   * Address canonicalization fine control.
185   */
186 #define CLEANUP_CANON_FLAG_ENV_FROM     (1<<0)    /* envelope sender */
187 #define CLEANUP_CANON_FLAG_ENV_RCPT     (1<<1)    /* envelope recipient */
188 #define CLEANUP_CANON_FLAG_HDR_FROM     (1<<2)    /* header sender */
189 #define CLEANUP_CANON_FLAG_HDR_RCPT     (1<<3)    /* header recipient */
190 
191  /*
192   * Address masquerading fine control.
193   */
194 #define CLEANUP_MASQ_FLAG_ENV_FROM      (1<<0)    /* envelope sender */
195 #define CLEANUP_MASQ_FLAG_ENV_RCPT      (1<<1)    /* envelope recipient */
196 #define CLEANUP_MASQ_FLAG_HDR_FROM      (1<<2)    /* header sender */
197 #define CLEANUP_MASQ_FLAG_HDR_RCPT      (1<<3)    /* header recipient */
198 
199  /*
200   * Restrictions on extension propagation.
201   */
202 extern int cleanup_ext_prop_mask;
203 
204  /*
205   * Saved queue file names, so the files can be removed in case of a fatal
206   * run-time error.
207   */
208 extern char *cleanup_path;
209 extern VSTRING *cleanup_trace_path;
210 extern VSTRING *cleanup_bounce_path;
211 
212  /*
213   * cleanup_state.c
214   */
215 extern CLEANUP_STATE *cleanup_state_alloc(VSTREAM *);
216 extern void cleanup_state_free(CLEANUP_STATE *);
217 
218  /*
219   * cleanup_api.c
220   */
221 extern CLEANUP_STATE *cleanup_open(VSTREAM *);
222 extern void cleanup_control(CLEANUP_STATE *, int);
223 extern int cleanup_flush(CLEANUP_STATE *);
224 extern void cleanup_free(CLEANUP_STATE *);
225 extern void cleanup_all(void);
226 extern void cleanup_sig(int);
227 extern void cleanup_pre_jail(char *, char **);
228 extern void cleanup_post_jail(char *, char **);
229 extern const CONFIG_INT_TABLE cleanup_int_table[];
230 extern const CONFIG_BOOL_TABLE cleanup_bool_table[];
231 extern const CONFIG_STR_TABLE cleanup_str_table[];
232 extern const CONFIG_TIME_TABLE cleanup_time_table[];
233 
234 #define CLEANUP_RECORD(s, t, b, l)      ((s)->action((s), (t), (b), (l)))
235 
236  /*
237   * cleanup_out.c
238   */
239 extern void cleanup_out(CLEANUP_STATE *, int, const char *, ssize_t);
240 extern void cleanup_out_string(CLEANUP_STATE *, int, const char *);
241 extern void PRINTFLIKE(3, 4) cleanup_out_format(CLEANUP_STATE *, int, const char *,...);
242 extern void cleanup_out_header(CLEANUP_STATE *, VSTRING *);
243 
244 #define CLEANUP_OUT_BUF(s, t, b) \
245           cleanup_out((s), (t), vstring_str((b)), VSTRING_LEN((b)))
246 
247 #define CLEANUP_OUT_OK(s) \
248           (!((s)->errs & (s)->err_mask) && !((s)->flags & CLEANUP_FLAG_DISCARD))
249 
250  /*
251   * cleanup_envelope.c
252   */
253 extern void cleanup_envelope(CLEANUP_STATE *, int, const char *, ssize_t);
254 
255  /*
256   * cleanup_message.c
257   */
258 extern void cleanup_message(CLEANUP_STATE *, int, const char *, ssize_t);
259 
260  /*
261   * cleanup_extracted.c
262   */
263 extern void cleanup_extracted(CLEANUP_STATE *, int, const char *, ssize_t);
264 
265  /*
266   * cleanup_final.c
267   */
268 extern void cleanup_final(CLEANUP_STATE *);
269 
270  /*
271   * cleanup_rewrite.c
272   */
273 extern int cleanup_rewrite_external(const char *, VSTRING *, const char *);
274 extern int cleanup_rewrite_internal(const char *, VSTRING *, const char *);
275 extern int cleanup_rewrite_tree(const char *, TOK822 *);
276 
277  /*
278   * cleanup_map11.c
279   */
280 extern int cleanup_map11_external(CLEANUP_STATE *, VSTRING *, MAPS *, int);
281 extern int cleanup_map11_internal(CLEANUP_STATE *, VSTRING *, MAPS *, int);
282 extern int cleanup_map11_tree(CLEANUP_STATE *, TOK822 *, MAPS *, int);
283 
284  /*
285   * cleanup_map1n.c
286   */
287 ARGV   *cleanup_map1n_internal(CLEANUP_STATE *, const char *, MAPS *, int);
288 
289  /*
290   * cleanup_masquerade.c
291   */
292 extern int cleanup_masquerade_external(CLEANUP_STATE *, VSTRING *, ARGV *);
293 extern int cleanup_masquerade_internal(CLEANUP_STATE *, VSTRING *, ARGV *);
294 extern int cleanup_masquerade_tree(CLEANUP_STATE *, TOK822 *, ARGV *);
295 
296  /*
297   * cleanup_recipient.c
298   */
299 extern void cleanup_out_recipient(CLEANUP_STATE *, const char *, int, const char *, const char *);
300 
301  /*
302   * cleanup_addr.c.
303   */
304 extern off_t cleanup_addr_sender(CLEANUP_STATE *, const char *);
305 extern void cleanup_addr_recipient(CLEANUP_STATE *, const char *);
306 extern void cleanup_addr_bcc_dsn(CLEANUP_STATE *, const char *, const char *, int);
307 
308 #define NO_DSN_ORCPT          ((char *) 0)
309 #define NO_DSN_NOTIFY         DSN_NOTIFY_NEVER
310 #define DEF_DSN_NOTIFY        (0)
311 
312 #define cleanup_addr_bcc(state, addr) \
313     cleanup_addr_bcc_dsn((state), (addr), NO_DSN_ORCPT, NO_DSN_NOTIFY)
314 
315  /*
316   * cleanup_bounce.c.
317   */
318 extern int cleanup_bounce(CLEANUP_STATE *);
319 
320  /*
321   * MSG_STATS compatibility.
322   */
323 #define CLEANUP_MSG_STATS(stats, state) \
324     MSG_STATS_INIT1(stats, incoming_arrival, state->arrival_time)
325 
326  /*
327   * cleanup_milter.c.
328   */
329 extern void cleanup_milter_header_checks_init(void);
330 extern void cleanup_milter_receive(CLEANUP_STATE *, int);
331 extern void cleanup_milter_inspect(CLEANUP_STATE *, MILTERS *);
332 extern void cleanup_milter_emul_mail(CLEANUP_STATE *, MILTERS *, const char *);
333 extern void cleanup_milter_emul_rcpt(CLEANUP_STATE *, MILTERS *, const char *);
334 extern void cleanup_milter_emul_data(CLEANUP_STATE *, MILTERS *);
335 
336 #define CLEANUP_MILTER_OK(s) \
337     (((s)->flags & CLEANUP_FLAG_MILTER) != 0 \
338           && (s)->errs == 0 && ((s)->flags & CLEANUP_FLAG_DISCARD) == 0)
339 
340  /*
341   * cleanup_body_edit.c
342   */
343 typedef struct CLEANUP_REGION {
344     off_t   start;                      /* start of region */
345     off_t   len;                        /* length or zero (open-ended) */
346     off_t   write_offs;                           /* write offset */
347     struct CLEANUP_REGION *next;        /* linkage */
348 } CLEANUP_REGION;
349 
350 extern void cleanup_region_init(CLEANUP_STATE *);
351 extern CLEANUP_REGION *cleanup_region_open(CLEANUP_STATE *, ssize_t);
352 extern void cleanup_region_close(CLEANUP_STATE *, CLEANUP_REGION *);
353 extern CLEANUP_REGION *cleanup_region_return(CLEANUP_STATE *, CLEANUP_REGION *);
354 extern void cleanup_region_done(CLEANUP_STATE *);
355 
356 extern int cleanup_body_edit_start(CLEANUP_STATE *);
357 extern int cleanup_body_edit_write(CLEANUP_STATE *, int, VSTRING *);
358 extern int cleanup_body_edit_finish(CLEANUP_STATE *);
359 extern void cleanup_body_edit_free(CLEANUP_STATE *);
360 
361  /*
362   * From: header formatting.
363   */
364 extern int cleanup_hfrom_format;
365 
366 /* LICENSE
367 /* .ad
368 /* .fi
369 /*        The Secure Mailer license must be distributed with this software.
370 /* AUTHOR(S)
371 /*        Wietse Venema
372 /*        IBM T.J. Watson Research
373 /*        P.O. Box 704
374 /*        Yorktown Heights, NY 10598, USA
375 /*
376 /*        Wietse Venema
377 /*        Google, Inc.
378 /*        111 8th Avenue
379 /*        New York, NY 10011, USA
380 /*
381 /*        Wietse Venema
382 /*        porcupine.org
383 /*--*/
384