Postfix3.3.1
smtpd_milter.c
[詳解]
1 /*++
2 /* NAME
3 /* smtpd_milter 3
4 /* SUMMARY
5 /* SMTP server milter glue
6 /* SYNOPSIS
7 /* #include <smtpd.h>
8 /* #include <smtpd_milter.h>
9 /*
10 /* const char *smtpd_milter_eval(name, context)
11 /* const char *name;
12 /* void *context;
13 /* DESCRIPTION
14 /* smtpd_milter_eval() is a milter(3) call-back routine to
15 /* expand Sendmail macros before they are sent to filters.
16 /* DIAGNOSTICS
17 /* Panic: interface violations. Fatal errors: out of memory.
18 /* internal protocol errors.
19 /* LICENSE
20 /* .ad
21 /* .fi
22 /* The Secure Mailer license must be distributed with this software.
23 /* AUTHOR(S)
24 /* Wietse Venema
25 /* IBM T.J. Watson Research
26 /* P.O. Box 704
27 /* Yorktown Heights, NY 10598, USA
28 /*
29 /* Wietse Venema
30 /* Google, Inc.
31 /* 111 8th Avenue
32 /* New York, NY 10011, USA
33 /*--*/
34 
35 /* System library. */
36 
37 #include <sys_defs.h>
38 
39 /* Utility library. */
40 
41 #include <split_at.h>
42 #include <stringops.h>
43 
44 /* Global library. */
45 
46 #include <mail_params.h>
47 #include <quote_821_local.h>
48 
49 /* Milter library. */
50 
51 #include <milter.h>
52 
53 /* Application-specific. */
54 
55 #include <smtpd.h>
56 #include <smtpd_sasl_glue.h>
57 #include <smtpd_resolve.h>
58 #include <smtpd_milter.h>
59 
60  /*
61  * SLMs.
62  */
63 #define STR(x) vstring_str(x)
64 
65 /* smtpd_milter_eval - evaluate milter macro */
66 
67 const char *smtpd_milter_eval(const char *name, void *ptr)
68 {
69  SMTPD_STATE *state = (SMTPD_STATE *) ptr;
70  const RESOLVE_REPLY *reply;
71  char *cp;
72 
73  /*
74  * On-the-fly initialization.
75  */
76  if (state->expand_buf == 0)
77  state->expand_buf = vstring_alloc(10);
78 
79  /*
80  * System macros.
81  */
82  if (strcmp(name, S8_MAC_DAEMON_NAME) == 0)
83  return (var_milt_daemon_name);
84  if (strcmp(name, S8_MAC_V) == 0)
85  return (var_milt_v);
86 
87  /*
88  * Connect macros.
89  */
90  if (strcmp(name, S8_MAC__) == 0) {
91  vstring_sprintf(state->expand_buf, "%s [%s]",
92  state->reverse_name, state->addr);
93  if (strcasecmp_utf8(state->name, state->reverse_name) != 0)
94  vstring_strcat(state->expand_buf, " (may be forged)");
95  return (STR(state->expand_buf));
96  }
97  if (strcmp(name, S8_MAC_J) == 0)
98  return (var_myhostname);
99  if (strcmp(name, S8_MAC_CLIENT_ADDR) == 0)
100  return (state->rfc_addr);
101  if (strcmp(name, S8_MAC_CLIENT_PORT) == 0)
102  return (strcmp(state->port, CLIENT_PORT_UNKNOWN) ? state->port : "0");
103  if (strcmp(name, S8_MAC_CLIENT_CONN) == 0) {
104  vstring_sprintf(state->expand_buf, "%d", state->conn_count);
105  return (STR(state->expand_buf));
106  }
107  if (strcmp(name, S8_MAC_CLIENT_NAME) == 0)
108  return (state->name);
109  if (strcmp(name, S8_MAC_CLIENT_PTR) == 0)
110  return (state->reverse_name);
111  if (strcmp(name, S8_MAC_CLIENT_RES) == 0)
112  return (state->name_status == SMTPD_PEER_CODE_OK ? "OK" :
113  state->name_status == SMTPD_PEER_CODE_FORGED ? "FORGED" :
114  state->name_status == SMTPD_PEER_CODE_TEMP ? "TEMP" : "FAIL");
115 
116  if (strcmp(name, S8_MAC_DAEMON_ADDR) == 0)
117  return (state->dest_addr);
118  if (strcmp(name, S8_MAC_DAEMON_PORT) == 0)
119  return (state->dest_port);
120 
121  /*
122  * HELO macros.
123  */
124 #ifdef USE_TLS
125 #define IF_ENCRYPTED(x) (state->tls_context ? (x) : 0)
126 #define IF_TRUSTED(x) (TLS_CERT_IS_TRUSTED(state->tls_context) ? (x) : 0)
127 
128  if (strcmp(name, S8_MAC_TLS_VERSION) == 0)
129  return (IF_ENCRYPTED(state->tls_context->protocol));
130  if (strcmp(name, S8_MAC_CIPHER) == 0)
131  return (IF_ENCRYPTED(state->tls_context->cipher_name));
132  if (strcmp(name, S8_MAC_CIPHER_BITS) == 0) {
133  if (state->tls_context == 0)
134  return (0);
135  vstring_sprintf(state->expand_buf, "%d",
136  IF_ENCRYPTED(state->tls_context->cipher_usebits));
137  return (STR(state->expand_buf));
138  }
139  if (strcmp(name, S8_MAC_CERT_SUBJECT) == 0)
140  return (IF_TRUSTED(state->tls_context->peer_CN));
141  if (strcmp(name, S8_MAC_CERT_ISSUER) == 0)
142  return (IF_TRUSTED(state->tls_context->issuer_CN));
143 #endif
144 
145  /*
146  * MAIL FROM macros.
147  */
148 #define IF_SASL_ENABLED(s) ((s) ? (s) : 0)
149 
150  if (strcmp(name, S8_MAC_I) == 0)
151  return (state->queue_id);
152 #ifdef USE_SASL_AUTH
153  if (strcmp(name, S8_MAC_AUTH_TYPE) == 0)
154  return (IF_SASL_ENABLED(state->sasl_method));
155  if (strcmp(name, S8_MAC_AUTH_AUTHEN) == 0)
156  return (IF_SASL_ENABLED(state->sasl_username));
157  if (strcmp(name, S8_MAC_AUTH_AUTHOR) == 0)
158  return (IF_SASL_ENABLED(state->sasl_sender));
159 #endif
160  if (strcmp(name, S8_MAC_MAIL_ADDR) == 0) {
161  if (state->sender == 0)
162  return (0);
163  if (state->sender[0] == 0)
164  return ("");
165  reply = smtpd_resolve_addr(state->recipient, state->sender);
166  /* Sendmail 8.13 does not externalize the null string. */
167  if (STR(reply->recipient)[0])
168  quote_821_local(state->expand_buf, STR(reply->recipient));
169  else
170  vstring_strcpy(state->expand_buf, STR(reply->recipient));
171  return (STR(state->expand_buf));
172  }
173  if (strcmp(name, S8_MAC_MAIL_HOST) == 0) {
174  if (state->sender == 0)
175  return (0);
176  reply = smtpd_resolve_addr(state->recipient, state->sender);
177  return (STR(reply->nexthop));
178  }
179  if (strcmp(name, S8_MAC_MAIL_MAILER) == 0) {
180  if (state->sender == 0)
181  return (0);
182  reply = smtpd_resolve_addr(state->recipient, state->sender);
183  return (STR(reply->transport));
184  }
185 
186  /*
187  * RCPT TO macros.
188  */
189  if (strcmp(name, S8_MAC_RCPT_ADDR) == 0) {
190  if (state->recipient == 0)
191  return (0);
192  if (state->recipient[0] == 0)
193  return ("");
194  if (state->milter_reject_text) {
195  /* 554 5.7.1 <user@example.com>: Relay access denied */
196  vstring_strcpy(state->expand_buf, state->milter_reject_text + 4);
197  cp = split_at(STR(state->expand_buf), ' ');
198  return (cp ? split_at(cp, ' ') : cp);
199  }
200  reply = smtpd_resolve_addr(state->sender, state->recipient);
201  /* Sendmail 8.13 does not externalize the null string. */
202  if (STR(reply->recipient)[0])
203  quote_821_local(state->expand_buf, STR(reply->recipient));
204  else
205  vstring_strcpy(state->expand_buf, STR(reply->recipient));
206  return (STR(state->expand_buf));
207  }
208  if (strcmp(name, S8_MAC_RCPT_HOST) == 0) {
209  if (state->recipient == 0)
210  return (0);
211  if (state->milter_reject_text) {
212  /* 554 5.7.1 <user@example.com>: Relay access denied */
213  vstring_strcpy(state->expand_buf, state->milter_reject_text + 4);
214  (void) split_at(STR(state->expand_buf), ' ');
215  return (STR(state->expand_buf));
216  }
217  reply = smtpd_resolve_addr(state->sender, state->recipient);
218  return (STR(reply->nexthop));
219  }
220  if (strcmp(name, S8_MAC_RCPT_MAILER) == 0) {
221  if (state->recipient == 0)
222  return (0);
223  if (state->milter_reject_text)
224  return (S8_RCPT_MAILER_ERROR);
225  reply = smtpd_resolve_addr(state->sender, state->recipient);
226  return (STR(reply->transport));
227  }
228  return (0);
229 }
#define S8_MAC_DAEMON_ADDR
Definition: milter.h:182
#define S8_MAC_CIPHER
Definition: milter.h:186
char * dest_port
Definition: smtpd.h:83
#define S8_MAC_CLIENT_ADDR
Definition: milter.h:175
#define SMTPD_PEER_CODE_FORGED
Definition: smtpd.h:334
char * queue_id
Definition: smtpd.h:96
char * name
Definition: smtpd.h:75
#define S8_MAC_MAIL_MAILER
Definition: milter.h:196
#define S8_MAC_AUTH_AUTHOR
Definition: milter.h:194
#define strcasecmp_utf8(s1, s2)
Definition: stringops.h:75
#define S8_MAC_CLIENT_CONN
Definition: milter.h:176
#define IF_SASL_ENABLED(s)
const char * smtpd_milter_eval(const char *name, void *ptr)
Definition: smtpd_milter.c:67
VSTRING * expand_buf
Definition: smtpd.h:148
#define S8_MAC_DAEMON_NAME
Definition: milter.h:171
char * var_milt_v
Definition: cleanup_init.c:159
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
Definition: vstring.c:431
#define S8_RCPT_MAILER_ERROR
Definition: milter.h:204
#define S8_MAC_V
Definition: milter.h:169
#define S8_MAC__
Definition: milter.h:167
#define S8_MAC_CLIENT_PTR
Definition: milter.h:179
const char * milter_reject_text
Definition: smtpd.h:184
char * port
Definition: smtpd.h:78
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
#define S8_MAC_I
Definition: milter.h:191
char * sender
Definition: smtpd.h:103
const RESOLVE_REPLY * smtpd_resolve_addr(const char *sender, const char *addr)
#define S8_MAC_AUTH_TYPE
Definition: milter.h:192
#define S8_MAC_RCPT_HOST
Definition: milter.h:201
#define S8_MAC_MAIL_HOST
Definition: milter.h:197
VSTRING * vstring_sprintf(VSTRING *vp, const char *format,...)
Definition: vstring.c:602
char * var_milt_daemon_name
Definition: cleanup_init.c:158
#define STR(x)
Definition: smtpd_milter.c:63
VSTRING * recipient
Definition: resolve_clnt.h:46
#define S8_MAC_J
Definition: milter.h:168
#define quote_821_local(dst, src)
#define S8_MAC_DAEMON_PORT
Definition: milter.h:183
char * reverse_name
Definition: smtpd.h:76
int name_status
Definition: smtpd.h:88
#define S8_MAC_CLIENT_RES
Definition: milter.h:180
char * dest_addr
Definition: smtpd.h:82
char * addr
Definition: smtpd.h:77
#define S8_MAC_CERT_ISSUER
Definition: milter.h:189
VSTRING * nexthop
Definition: resolve_clnt.h:45
#define S8_MAC_AUTH_AUTHEN
Definition: milter.h:193
VSTRING * transport
Definition: resolve_clnt.h:44
char * split_at(char *string, int delimiter)
Definition: split_at.c:53
#define S8_MAC_CIPHER_BITS
Definition: milter.h:187
char * recipient
Definition: smtpd.h:106
#define S8_MAC_CLIENT_PORT
Definition: milter.h:178
#define S8_MAC_CLIENT_NAME
Definition: milter.h:177
int conn_count
Definition: smtpd.h:90
char * var_myhostname
Definition: mail_params.c:223
#define SMTPD_PEER_CODE_TEMP
Definition: smtpd.h:332
#define CLIENT_PORT_UNKNOWN
Definition: qmqpd.h:64
#define S8_MAC_RCPT_ADDR
Definition: milter.h:202
char * protocol
Definition: smtpd.h:108
char * rfc_addr
Definition: smtpd.h:80
#define S8_MAC_CERT_SUBJECT
Definition: milter.h:188
#define S8_MAC_RCPT_MAILER
Definition: milter.h:200
VSTRING * vstring_strcat(VSTRING *vp, const char *src)
Definition: vstring.c:459
#define S8_MAC_TLS_VERSION
Definition: milter.h:185
#define SMTPD_PEER_CODE_OK
Definition: smtpd.h:331
#define S8_MAC_MAIL_ADDR
Definition: milter.h:198