1 /*        $NetBSD: milter.h,v 1.4 2022/10/08 16:12:46 christos Exp $  */
2 
3 #ifndef _MILTER_H_INCLUDED_
4 #define _MILTER_H_INCLUDED_
5 
6 /*++
7 /* NAME
8 /*        milter 3h
9 /* SUMMARY
10 /*        smtp server
11 /* SYNOPSIS
12 /*        Postfix MTA-side Milter implementation
13 /* DESCRIPTION
14 /* .nf
15 
16  /*
17   * Utility library.
18   */
19 #include <vstring.h>
20 #include <vstream.h>
21 #include <argv.h>
22 
23  /*
24   * Global library.
25   */
26 #include <attr.h>
27 
28  /*
29   * Each Milter handle is an element of a null-terminated linked list. The
30   * functions are virtual so that we can support multiple MTA-side Milter
31   * implementations. The Sendmail 8 and Sendmail X Milter-side APIs are too
32   * different to implement the MTA side as a single hybrid.
33   */
34 typedef struct MILTER {
35     char   *name;                       /* full name including transport */
36     int     flags;                      /* see below */
37     struct MILTER *next;                /* linkage */
38     struct MILTERS *parent;             /* parent information */
39     struct MILTER_MACROS *macros;       /* private macros */
40     void    (*connect_on_demand) (struct MILTER *);
41     const char *(*conn_event) (struct MILTER *, const char *, const char *, const char *, unsigned, ARGV *);
42     const char *(*helo_event) (struct MILTER *, const char *, int, ARGV *);
43     const char *(*mail_event) (struct MILTER *, const char **, ARGV *);
44     const char *(*rcpt_event) (struct MILTER *, const char **, ARGV *);
45     const char *(*data_event) (struct MILTER *, ARGV *);
46     const char *(*message) (struct MILTER *, VSTREAM *, off_t, ARGV *, ARGV *, ARGV *);
47     const char *(*unknown_event) (struct MILTER *, const char *, ARGV *);
48     const char *(*other_event) (struct MILTER *);
49     void    (*abort) (struct MILTER *);
50     void    (*disc_event) (struct MILTER *);
51     int     (*active) (struct MILTER *);
52     int     (*send) (struct MILTER *, VSTREAM *);
53     void    (*free) (struct MILTER *);
54 } MILTER;
55 
56 #define MILTER_FLAG_NONE                (0)
57 #define MILTER_FLAG_WANT_RCPT_REJ       (1<<0)    /* see S8_RCPT_MAILER_ERROR */
58 
59 extern MILTER *milter8_create(const char *, int, int, int, const char *, const char *, struct MILTERS *);
60 extern MILTER *milter8_receive(VSTREAM *, struct MILTERS *);
61 
62  /*
63   * As of Sendmail 8.14 each milter can override the default macro list. If a
64   * Milter has its own macro list, a null member means use the global
65   * definition.
66   */
67 typedef struct MILTER_MACROS {
68     char   *conn_macros;                /* macros for connect event */
69     char   *helo_macros;                /* macros for HELO/EHLO command */
70     char   *mail_macros;                /* macros for MAIL FROM command */
71     char   *rcpt_macros;                /* macros for RCPT TO command */
72     char   *data_macros;                /* macros for DATA command */
73     char   *eoh_macros;                           /* macros for end-of-headers */
74     char   *eod_macros;                           /* macros for END-OF-DATA command */
75     char   *unk_macros;                           /* macros for unknown command */
76 } MILTER_MACROS;
77 
78 extern MILTER_MACROS *milter_macros_create(const char *, const char *,
79                                                            const char *, const char *,
80                                                            const char *, const char *,
81                                                           const char *, const char *);
82 extern MILTER_MACROS *milter_macros_alloc(int);
83 extern void milter_macros_free(MILTER_MACROS *);
84 extern int milter_macros_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
85 extern int milter_macros_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);
86 
87 #define MILTER_MACROS_ALLOC_ZERO        1         /* null pointer */
88 #define MILTER_MACROS_ALLOC_EMPTY       2         /* mystrdup(""); */
89 
90  /*
91   * Helper to parse list of name=value default macro settings.
92   */
93 extern struct HTABLE *milter_macro_defaults_create(const char *);
94 
95  /*
96   * A bunch of Milters.
97   */
98 typedef const char *(*MILTER_MAC_LOOKUP_FN) (const char *, void *);
99 typedef const char *(*MILTER_ADD_HEADER_FN) (void *, const char *, const char *, const char *);
100 typedef const char *(*MILTER_EDIT_HEADER_FN) (void *, ssize_t, const char *, const char *, const char *);
101 typedef const char *(*MILTER_DEL_HEADER_FN) (void *, ssize_t, const char *);
102 typedef const char *(*MILTER_EDIT_FROM_FN) (void *, const char *, const char *);
103 typedef const char *(*MILTER_EDIT_RCPT_FN) (void *, const char *);
104 typedef const char *(*MILTER_EDIT_RCPT_PAR_FN) (void *, const char *, const char *);
105 typedef const char *(*MILTER_EDIT_BODY_FN) (void *, int, int, VSTRING *);
106 
107 typedef struct MILTERS {
108     MILTER *milter_list;                /* linked list of Milters */
109     MILTER_MAC_LOOKUP_FN mac_lookup;
110     void   *mac_context;                /* macro lookup context */
111     struct MILTER_MACROS *macros;
112     struct HTABLE *macro_defaults;
113     void   *chg_context;                /* context for queue file changes */
114     MILTER_ADD_HEADER_FN add_header;
115     MILTER_EDIT_HEADER_FN upd_header;
116     MILTER_DEL_HEADER_FN del_header;
117     MILTER_EDIT_HEADER_FN ins_header;
118     MILTER_EDIT_FROM_FN chg_from;
119     MILTER_EDIT_RCPT_FN add_rcpt;
120     MILTER_EDIT_RCPT_PAR_FN add_rcpt_par;
121     MILTER_EDIT_RCPT_FN del_rcpt;
122     MILTER_EDIT_BODY_FN repl_body;
123 } MILTERS;
124 
125 #define milter_create(milter_names, conn_timeout, cmd_timeout, msg_timeout, \
126                               protocol, def_action, conn_macros, helo_macros, \
127                               mail_macros, rcpt_macros, data_macros, eoh_macros, \
128                               eod_macros, unk_macros, macro_deflts) \
129           milter_new(milter_names, conn_timeout, cmd_timeout, msg_timeout, \
130                         protocol, def_action, milter_macros_create(conn_macros, \
131                         helo_macros, mail_macros, rcpt_macros, data_macros, \
132                         eoh_macros, eod_macros, unk_macros), \
133                         milter_macro_defaults_create(macro_deflts))
134 
135 extern MILTERS *milter_new(const char *, int, int, int, const char *,
136                                          const char *, MILTER_MACROS *,
137                                          struct HTABLE *);
138 extern void milter_macro_callback(MILTERS *, MILTER_MAC_LOOKUP_FN, void *);
139 extern void milter_edit_callback(MILTERS *milters, MILTER_ADD_HEADER_FN,
140                                    MILTER_EDIT_HEADER_FN, MILTER_EDIT_HEADER_FN,
141                                         MILTER_DEL_HEADER_FN, MILTER_EDIT_FROM_FN,
142                                    MILTER_EDIT_RCPT_FN, MILTER_EDIT_RCPT_PAR_FN,
143                                          MILTER_EDIT_RCPT_FN, MILTER_EDIT_BODY_FN,
144                                                  void *);
145 extern const char *milter_conn_event(MILTERS *, const char *, const char *, const char *, unsigned);
146 extern const char *milter_helo_event(MILTERS *, const char *, int);
147 extern const char *milter_mail_event(MILTERS *, const char **);
148 extern const char *milter_rcpt_event(MILTERS *, int, const char **);
149 extern const char *milter_data_event(MILTERS *);
150 extern const char *milter_message(MILTERS *, VSTREAM *, off_t, ARGV *);
151 extern const char *milter_unknown_event(MILTERS *, const char *);
152 extern const char *milter_other_event(MILTERS *);
153 extern void milter_abort(MILTERS *);
154 extern void milter_disc_event(MILTERS *);
155 extern int milter_dummy(MILTERS *, VSTREAM *);
156 extern int milter_send(MILTERS *, VSTREAM *);
157 extern MILTERS *milter_receive(VSTREAM *, int);
158 extern void milter_free(MILTERS *);
159 
160  /*
161   * Milter body edit commands.
162   */
163 #define MILTER_BODY_START     1         /* start message body */
164 #define MILTER_BODY_LINE      2         /* message body line */
165 #define MILTER_BODY_END                 3         /* end message body */
166 
167  /*
168   * Sendmail 8 macro names. We support forms with and without the {}.
169   */
170 #define S8_MAC__              "{_}"     /* sender host, see client_resolve */
171 #define S8_MAC_J              "{j}"     /* myhostname */
172 #define S8_MAC_V              "{v}"     /* mail_name + mail_version */
173 
174 #define S8_MAC_DAEMON_NAME    "{daemon_name}"
175 #define S8_MAC_IF_NAME                  "{if_name}"
176 #define S8_MAC_IF_ADDR                  "{if_addr}"
177 
178 #define S8_MAC_CLIENT_ADDR    "{client_addr}"
179 #define S8_MAC_CLIENT_CONN    "{client_connections}"
180 #define S8_MAC_CLIENT_NAME    "{client_name}"
181 #define S8_MAC_CLIENT_PORT    "{client_port}"
182 #define S8_MAC_CLIENT_PTR     "{client_ptr}"
183 #define S8_MAC_CLIENT_RES     "{client_resolve}"
184 
185 #define S8_MAC_DAEMON_ADDR    "{daemon_addr}"
186 #define S8_MAC_DAEMON_PORT    "{daemon_port}"
187 
188 #define S8_MAC_TLS_VERSION    "{tls_version}"
189 #define S8_MAC_CIPHER                   "{cipher}"
190 #define S8_MAC_CIPHER_BITS    "{cipher_bits}"
191 #define S8_MAC_CERT_SUBJECT   "{cert_subject}"
192 #define S8_MAC_CERT_ISSUER    "{cert_issuer}"
193 
194 #define S8_MAC_I              "{i}"     /* queue ID */
195 #define S8_MAC_AUTH_TYPE      "{auth_type}"       /* SASL method */
196 #define S8_MAC_AUTH_AUTHEN    "{auth_authen}"     /* SASL username */
197 #define S8_MAC_AUTH_AUTHOR    "{auth_author}"     /* SASL sender */
198 
199 #define S8_MAC_MAIL_MAILER    "{mail_mailer}"     /* sender transport */
200 #define S8_MAC_MAIL_HOST      "{mail_host}"       /* sender nexthop */
201 #define S8_MAC_MAIL_ADDR      "{mail_addr}"       /* sender address */
202 
203 #define S8_MAC_RCPT_MAILER    "{rcpt_mailer}"     /* recip transport */
204 #define S8_MAC_RCPT_HOST      "{rcpt_host}"       /* recip nexthop */
205 #define S8_MAC_RCPT_ADDR      "{rcpt_addr}"       /* recip address */
206 
207 #define S8_RCPT_MAILER_ERROR  "error"   /* see MILTER_FLAG_WANT_RCPT_REJ */
208 
209 /* LICENSE
210 /* .ad
211 /* .fi
212 /*        The Secure Mailer license must be distributed with this software.
213 /* AUTHOR(S)
214 /*        Wietse Venema
215 /*        IBM T.J. Watson Research
216 /*        P.O. Box 704
217 /*        Yorktown Heights, NY 10598, USA
218 /*
219 /*        Wietse Venema
220 /*        Google, Inc.
221 /*        111 8th Avenue
222 /*        New York, NY 10011, USA
223 /*--*/
224 
225 #endif
226