No empty .Rs/.Re
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / smtpd / smtpd_milter.c
blob99753345cd9d3d9c4aab9079c0c086c127bb5a9d
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* smtpd_milter 3
6 /* SUMMARY
7 /* SMTP server milter glue
8 /* SYNOPSIS
9 /* #include <smtpd.h>
10 /* #include <smtpd_milter.h>
12 /* const char *smtpd_milter_eval(name, context)
13 /* const char *name;
14 /* void *context;
15 /* DESCRIPTION
16 /* smtpd_milter_eval() is a milter(3) call-back routine to
17 /* expand Sendmail macros before they are sent to filters.
18 /* DIAGNOSTICS
19 /* Panic: interface violations. Fatal errors: out of memory.
20 /* internal protocol errors.
21 /* LICENSE
22 /* .ad
23 /* .fi
24 /* The Secure Mailer license must be distributed with this software.
25 /* AUTHOR(S)
26 /* Wietse Venema
27 /* IBM T.J. Watson Research
28 /* P.O. Box 704
29 /* Yorktown Heights, NY 10598, USA
30 /*--*/
32 /* System library. */
34 #include <sys_defs.h>
36 /* Utility library. */
38 #include <split_at.h>
40 /* Global library. */
42 #include <mail_params.h>
43 #include <quote_821_local.h>
45 /* Milter library. */
47 #include <milter.h>
49 /* Application-specific. */
51 #include <smtpd.h>
52 #include <smtpd_sasl_glue.h>
53 #include <smtpd_resolve.h>
54 #include <smtpd_milter.h>
57 * SLMs.
59 #define STR(x) vstring_str(x)
61 /* smtpd_milter_eval - evaluate milter macro */
63 const char *smtpd_milter_eval(const char *name, void *ptr)
65 SMTPD_STATE *state = (SMTPD_STATE *) ptr;
66 const RESOLVE_REPLY *reply;
67 char *cp;
70 * On-the-fly initialization.
72 if (state->expand_buf == 0)
73 state->expand_buf = vstring_alloc(10);
76 * Canonicalize the name.
78 if (*name != '{') { /* } */
79 vstring_sprintf(state->expand_buf, "{%s}", name);
80 name = STR(state->expand_buf);
84 * System macros.
86 if (strcmp(name, S8_MAC_DAEMON_NAME) == 0)
87 return (var_milt_daemon_name);
88 if (strcmp(name, S8_MAC_V) == 0)
89 return (var_milt_v);
92 * Connect macros.
94 if (strcmp(name, S8_MAC__) == 0) {
95 vstring_sprintf(state->expand_buf, "%s [%s]",
96 state->reverse_name, state->addr);
97 if (strcasecmp(state->name, state->reverse_name) != 0)
98 vstring_strcat(state->expand_buf, " (may be forged)");
99 return (STR(state->expand_buf));
101 if (strcmp(name, S8_MAC_J) == 0)
102 return (var_myhostname);
103 if (strcmp(name, S8_MAC_CLIENT_ADDR) == 0)
104 return (state->rfc_addr);
105 if (strcmp(name, S8_MAC_CLIENT_PORT) == 0)
106 return (strcmp(state->port, CLIENT_PORT_UNKNOWN) ? state->port : "0");
107 if (strcmp(name, S8_MAC_CLIENT_CONN) == 0) {
108 vstring_sprintf(state->expand_buf, "%d", state->conn_count);
109 return (STR(state->expand_buf));
111 if (strcmp(name, S8_MAC_CLIENT_NAME) == 0)
112 return (state->name);
113 if (strcmp(name, S8_MAC_CLIENT_PTR) == 0)
114 return (state->reverse_name);
115 if (strcmp(name, S8_MAC_CLIENT_RES) == 0)
116 return (state->name_status == SMTPD_PEER_CODE_OK ? "OK" :
117 state->name_status == SMTPD_PEER_CODE_FORGED ? "FORGED" :
118 state->name_status == SMTPD_PEER_CODE_TEMP ? "TEMP" : "FAIL");
121 * HELO macros.
123 #ifdef USE_TLS
124 #define IF_ENCRYPTED(x) (state->tls_context ? (x) : 0)
125 #define IF_TRUSTED(x) (TLS_CERT_IS_TRUSTED(state->tls_context) ? (x) : 0)
127 if (strcmp(name, S8_MAC_TLS_VERSION) == 0)
128 return (IF_ENCRYPTED(state->tls_context->protocol));
129 if (strcmp(name, S8_MAC_CIPHER) == 0)
130 return (IF_ENCRYPTED(state->tls_context->cipher_name));
131 if (strcmp(name, S8_MAC_CIPHER_BITS) == 0) {
132 if (state->tls_context == 0)
133 return (0);
134 vstring_sprintf(state->expand_buf, "%d",
135 IF_ENCRYPTED(state->tls_context->cipher_usebits));
136 return (STR(state->expand_buf));
138 if (strcmp(name, S8_MAC_CERT_SUBJECT) == 0)
139 return (IF_TRUSTED(state->tls_context->peer_CN));
140 if (strcmp(name, S8_MAC_CERT_ISSUER) == 0)
141 return (IF_TRUSTED(state->tls_context->issuer_CN));
142 #endif
145 * MAIL FROM macros.
147 #define IF_SASL_ENABLED(s) (smtpd_sasl_is_active(state) && (s) ? (s) : 0)
149 if (strcmp(name, S8_MAC_I) == 0)
150 return (state->queue_id);
151 #ifdef USE_SASL_AUTH
152 if (strcmp(name, S8_MAC_AUTH_TYPE) == 0)
153 return (IF_SASL_ENABLED(state->sasl_method));
154 if (strcmp(name, S8_MAC_AUTH_AUTHEN) == 0)
155 return (IF_SASL_ENABLED(state->sasl_username));
156 if (strcmp(name, S8_MAC_AUTH_AUTHOR) == 0)
157 return (IF_SASL_ENABLED(state->sasl_sender));
158 #endif
159 if (strcmp(name, S8_MAC_MAIL_ADDR) == 0) {
160 if (state->sender == 0)
161 return (0);
162 if (state->sender[0] == 0)
163 return ("");
164 reply = smtpd_resolve_addr(state->sender);
165 /* Sendmail 8.13 does not externalize the null string. */
166 if (STR(reply->recipient)[0])
167 quote_821_local(state->expand_buf, STR(reply->recipient));
168 else
169 vstring_strcpy(state->expand_buf, STR(reply->recipient));
170 return (STR(state->expand_buf));
172 if (strcmp(name, S8_MAC_MAIL_HOST) == 0) {
173 if (state->sender == 0)
174 return (0);
175 reply = smtpd_resolve_addr(state->sender);
176 return (STR(reply->nexthop));
178 if (strcmp(name, S8_MAC_MAIL_MAILER) == 0) {
179 if (state->sender == 0)
180 return (0);
181 reply = smtpd_resolve_addr(state->sender);
182 return (STR(reply->transport));
186 * RCPT TO macros.
188 if (strcmp(name, S8_MAC_RCPT_ADDR) == 0) {
189 if (state->recipient == 0)
190 return (0);
191 if (state->recipient[0] == 0)
192 return ("");
193 if (state->milter_reject_text) {
194 /* 554 5.7.1 <user@example.com>: Relay access denied */
195 vstring_strcpy(state->expand_buf, state->milter_reject_text + 4);
196 cp = split_at(STR(state->expand_buf), ' ');
197 return (cp ? split_at(cp, ' ') : cp);
199 reply = smtpd_resolve_addr(state->recipient);
200 /* Sendmail 8.13 does not externalize the null string. */
201 if (STR(reply->recipient)[0])
202 quote_821_local(state->expand_buf, STR(reply->recipient));
203 else
204 vstring_strcpy(state->expand_buf, STR(reply->recipient));
205 return (STR(state->expand_buf));
207 if (strcmp(name, S8_MAC_RCPT_HOST) == 0) {
208 if (state->recipient == 0)
209 return (0);
210 if (state->milter_reject_text) {
211 /* 554 5.7.1 <user@example.com>: Relay access denied */
212 vstring_strcpy(state->expand_buf, state->milter_reject_text + 4);
213 (void) split_at(STR(state->expand_buf), ' ');
214 return (STR(state->expand_buf));
216 reply = smtpd_resolve_addr(state->recipient);
217 return (STR(reply->nexthop));
219 if (strcmp(name, S8_MAC_RCPT_MAILER) == 0) {
220 if (state->recipient == 0)
221 return (0);
222 if (state->milter_reject_text)
223 return (S8_RCPT_MAILER_ERROR);
224 reply = smtpd_resolve_addr(state->recipient);
225 return (STR(reply->transport));
227 return (0);