summaryrefslogtreecommitdiffstats
path: root/src/milter/milter.h
blob: 3a1e3f94524dbe99745e24969413105d126cba38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#ifndef _MILTER_H_INCLUDED_
#define _MILTER_H_INCLUDED_

/*++
/* NAME
/*	milter 3h
/* SUMMARY
/*	smtp server
/* SYNOPSIS
/*	Postfix MTA-side Milter implementation
/* DESCRIPTION
/* .nf

 /*
  * Utility library.
  */
#include <vstring.h>
#include <vstream.h>
#include <argv.h>

 /*
  * Global library.
  */
#include <attr.h>

 /*
  * Each Milter handle is an element of a null-terminated linked list. The
  * functions are virtual so that we can support multiple MTA-side Milter
  * implementations. The Sendmail 8 and Sendmail X Milter-side APIs are too
  * different to implement the MTA side as a single hybrid.
  */
typedef struct MILTER {
    char   *name;			/* full name including transport */
    int     flags;			/* see below */
    struct MILTER *next;		/* linkage */
    struct MILTERS *parent;		/* parent information */
    struct MILTER_MACROS *macros;	/* private macros */
    void    (*connect_on_demand) (struct MILTER *);
    const char *(*conn_event) (struct MILTER *, const char *, const char *, const char *, unsigned, ARGV *);
    const char *(*helo_event) (struct MILTER *, const char *, int, ARGV *);
    const char *(*mail_event) (struct MILTER *, const char **, ARGV *);
    const char *(*rcpt_event) (struct MILTER *, const char **, ARGV *);
    const char *(*data_event) (struct MILTER *, ARGV *);
    const char *(*message) (struct MILTER *, VSTREAM *, off_t, ARGV *, ARGV *, ARGV *);
    const char *(*unknown_event) (struct MILTER *, const char *, ARGV *);
    const char *(*other_event) (struct MILTER *);
    void    (*abort) (struct MILTER *);
    void    (*disc_event) (struct MILTER *);
    int     (*active) (struct MILTER *);
    int     (*send) (struct MILTER *, VSTREAM *);
    void    (*free) (struct MILTER *);
} MILTER;

#define MILTER_FLAG_NONE		(0)
#define MILTER_FLAG_WANT_RCPT_REJ	(1<<0)	/* see S8_RCPT_MAILER_ERROR */

extern MILTER *milter8_create(const char *, int, int, int, const char *, const char *, struct MILTERS *);
extern MILTER *milter8_receive(VSTREAM *, struct MILTERS *);

 /*
  * As of Sendmail 8.14 each milter can override the default macro list. If a
  * Milter has its own macro list, a null member means use the global
  * definition.
  */
typedef struct MILTER_MACROS {
    char   *conn_macros;		/* macros for connect event */
    char   *helo_macros;		/* macros for HELO/EHLO command */
    char   *mail_macros;		/* macros for MAIL FROM command */
    char   *rcpt_macros;		/* macros for RCPT TO command */
    char   *data_macros;		/* macros for DATA command */
    char   *eoh_macros;			/* macros for end-of-headers */
    char   *eod_macros;			/* macros for END-OF-DATA command */
    char   *unk_macros;			/* macros for unknown command */
} MILTER_MACROS;

extern MILTER_MACROS *milter_macros_create(const char *, const char *,
					         const char *, const char *,
					         const char *, const char *,
					        const char *, const char *);
extern MILTER_MACROS *milter_macros_alloc(int);
extern void milter_macros_free(MILTER_MACROS *);
extern int milter_macros_print(ATTR_PRINT_COMMON_FN, VSTREAM *, int, const void *);
extern int milter_macros_scan(ATTR_SCAN_COMMON_FN, VSTREAM *, int, void *);

#define MILTER_MACROS_ALLOC_ZERO	1	/* null pointer */
#define MILTER_MACROS_ALLOC_EMPTY	2	/* mystrdup(""); */

 /*
  * Helper to parse list of name=value default macro settings.
  */
extern struct HTABLE *milter_macro_defaults_create(const char *);

 /*
  * A bunch of Milters.
  */
typedef const char *(*MILTER_MAC_LOOKUP_FN) (const char *, void *);
typedef const char *(*MILTER_ADD_HEADER_FN) (void *, const char *, const char *, const char *);
typedef const char *(*MILTER_EDIT_HEADER_FN) (void *, ssize_t, const char *, const char *, const char *);
typedef const char *(*MILTER_DEL_HEADER_FN) (void *, ssize_t, const char *);
typedef const char *(*MILTER_EDIT_FROM_FN) (void *, const char *, const char *);
typedef const char *(*MILTER_EDIT_RCPT_FN) (void *, const char *);
typedef const char *(*MILTER_EDIT_RCPT_PAR_FN) (void *, const char *, const char *);
typedef const char *(*MILTER_EDIT_BODY_FN) (void *, int, int, VSTRING *);

typedef struct MILTERS {
    MILTER *milter_list;		/* linked list of Milters */
    MILTER_MAC_LOOKUP_FN mac_lookup;
    void   *mac_context;		/* macro lookup context */
    struct MILTER_MACROS *macros;
    struct HTABLE *macro_defaults;
    void   *chg_context;		/* context for queue file changes */
    MILTER_ADD_HEADER_FN add_header;
    MILTER_EDIT_HEADER_FN upd_header;
    MILTER_DEL_HEADER_FN del_header;
    MILTER_EDIT_HEADER_FN ins_header;
    MILTER_EDIT_FROM_FN chg_from;
    MILTER_EDIT_RCPT_FN add_rcpt;
    MILTER_EDIT_RCPT_PAR_FN add_rcpt_par;
    MILTER_EDIT_RCPT_FN del_rcpt;
    MILTER_EDIT_BODY_FN repl_body;
} MILTERS;

#define milter_create(milter_names, conn_timeout, cmd_timeout, msg_timeout, \
			protocol, def_action, conn_macros, helo_macros, \
			mail_macros, rcpt_macros, data_macros, eoh_macros, \
			eod_macros, unk_macros, macro_deflts) \
	milter_new(milter_names, conn_timeout, cmd_timeout, msg_timeout, \
		    protocol, def_action, milter_macros_create(conn_macros, \
		    helo_macros, mail_macros, rcpt_macros, data_macros, \
		    eoh_macros, eod_macros, unk_macros), \
		    milter_macro_defaults_create(macro_deflts))

extern MILTERS *milter_new(const char *, int, int, int, const char *,
			           const char *, MILTER_MACROS *,
			           struct HTABLE *);
extern void milter_macro_callback(MILTERS *, MILTER_MAC_LOOKUP_FN, void *);
extern void milter_edit_callback(MILTERS *milters, MILTER_ADD_HEADER_FN,
		               MILTER_EDIT_HEADER_FN, MILTER_EDIT_HEADER_FN,
			          MILTER_DEL_HEADER_FN, MILTER_EDIT_FROM_FN,
		               MILTER_EDIT_RCPT_FN, MILTER_EDIT_RCPT_PAR_FN,
			           MILTER_EDIT_RCPT_FN, MILTER_EDIT_BODY_FN,
				         void *);
extern const char *milter_conn_event(MILTERS *, const char *, const char *, const char *, unsigned);
extern const char *milter_helo_event(MILTERS *, const char *, int);
extern const char *milter_mail_event(MILTERS *, const char **);
extern const char *milter_rcpt_event(MILTERS *, int, const char **);
extern const char *milter_data_event(MILTERS *);
extern const char *milter_message(MILTERS *, VSTREAM *, off_t, ARGV *);
extern const char *milter_unknown_event(MILTERS *, const char *);
extern const char *milter_other_event(MILTERS *);
extern void milter_abort(MILTERS *);
extern void milter_disc_event(MILTERS *);
extern int milter_dummy(MILTERS *, VSTREAM *);
extern int milter_send(MILTERS *, VSTREAM *);
extern MILTERS *milter_receive(VSTREAM *, int);
extern void milter_free(MILTERS *);

 /*
  * Milter body edit commands.
  */
#define MILTER_BODY_START	1	/* start message body */
#define MILTER_BODY_LINE	2	/* message body line */
#define MILTER_BODY_END		3	/* end message body */

 /*
  * Sendmail 8 macro names. We support forms with and without the {}.
  */
#define S8_MAC__		"{_}"	/* sender host, see client_resolve */
#define S8_MAC_J		"{j}"	/* myhostname */
#define S8_MAC_V		"{v}"	/* mail_name + mail_version */

#define S8_MAC_DAEMON_NAME	"{daemon_name}"
#define S8_MAC_IF_NAME		"{if_name}"
#define S8_MAC_IF_ADDR		"{if_addr}"

#define S8_MAC_CLIENT_ADDR	"{client_addr}"
#define S8_MAC_CLIENT_CONN	"{client_connections}"
#define S8_MAC_CLIENT_NAME	"{client_name}"
#define S8_MAC_CLIENT_PORT	"{client_port}"
#define S8_MAC_CLIENT_PTR	"{client_ptr}"
#define S8_MAC_CLIENT_RES	"{client_resolve}"

#define S8_MAC_DAEMON_ADDR	"{daemon_addr}"
#define S8_MAC_DAEMON_PORT	"{daemon_port}"

#define S8_MAC_TLS_VERSION	"{tls_version}"
#define S8_MAC_CIPHER		"{cipher}"
#define S8_MAC_CIPHER_BITS	"{cipher_bits}"
#define S8_MAC_CERT_SUBJECT	"{cert_subject}"
#define S8_MAC_CERT_ISSUER	"{cert_issuer}"

#define S8_MAC_I		"{i}"	/* queue ID */
#define S8_MAC_AUTH_TYPE	"{auth_type}"	/* SASL method */
#define S8_MAC_AUTH_AUTHEN	"{auth_authen}"	/* SASL username */
#define S8_MAC_AUTH_AUTHOR	"{auth_author}"	/* SASL sender */

#define S8_MAC_MAIL_MAILER	"{mail_mailer}"	/* sender transport */
#define S8_MAC_MAIL_HOST	"{mail_host}"	/* sender nexthop */
#define S8_MAC_MAIL_ADDR	"{mail_addr}"	/* sender address */

#define S8_MAC_RCPT_MAILER	"{rcpt_mailer}"	/* recip transport */
#define S8_MAC_RCPT_HOST	"{rcpt_host}"	/* recip nexthop */
#define S8_MAC_RCPT_ADDR	"{rcpt_addr}"	/* recip address */

#define S8_RCPT_MAILER_ERROR	"error"	/* see MILTER_FLAG_WANT_RCPT_REJ */

/* LICENSE
/* .ad
/* .fi
/*	The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/*	Wietse Venema
/*	IBM T.J. Watson Research
/*	P.O. Box 704
/*	Yorktown Heights, NY 10598, USA
/*
/*	Wietse Venema
/*	Google, Inc.
/*	111 8th Avenue
/*	New York, NY 10011, USA
/*--*/

#endif