Add expansion variable $headers_added returning newline-sep list of headers
[exim.git] / src / src / expand.c
1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2012 */
6 /* See the file NOTICE for conditions of use and distribution. */
7
8
9 /* Functions for handling string expansion. */
10
11
12 #include "exim.h"
13
14 /* Recursively called function */
15
16 static uschar *expand_string_internal(uschar *, BOOL, uschar **, BOOL, BOOL);
17
18 #ifdef STAND_ALONE
19 #ifndef SUPPORT_CRYPTEQ
20 #define SUPPORT_CRYPTEQ
21 #endif
22 #endif
23
24 #ifdef LOOKUP_LDAP
25 #include "lookups/ldap.h"
26 #endif
27
28 #ifdef SUPPORT_CRYPTEQ
29 #ifdef CRYPT_H
30 #include <crypt.h>
31 #endif
32 #ifndef HAVE_CRYPT16
33 extern char* crypt16(char*, char*);
34 #endif
35 #endif
36
37 /* The handling of crypt16() is a mess. I will record below the analysis of the
38 mess that was sent to me. We decided, however, to make changing this very low
39 priority, because in practice people are moving away from the crypt()
40 algorithms nowadays, so it doesn't seem worth it.
41
42 <quote>
43 There is an algorithm named "crypt16" in Ultrix and Tru64. It crypts
44 the first 8 characters of the password using a 20-round version of crypt
45 (standard crypt does 25 rounds). It then crypts the next 8 characters,
46 or an empty block if the password is less than 9 characters, using a
47 20-round version of crypt and the same salt as was used for the first
48 block. Charaters after the first 16 are ignored. It always generates
49 a 16-byte hash, which is expressed together with the salt as a string
50 of 24 base 64 digits. Here are some links to peruse:
51
52 http://cvs.pld.org.pl/pam/pamcrypt/crypt16.c?rev=1.2
53 http://seclists.org/bugtraq/1999/Mar/0076.html
54
55 There's a different algorithm named "bigcrypt" in HP-UX, Digital Unix,
56 and OSF/1. This is the same as the standard crypt if given a password
57 of 8 characters or less. If given more, it first does the same as crypt
58 using the first 8 characters, then crypts the next 8 (the 9th to 16th)
59 using as salt the first two base 64 digits from the first hash block.
60 If the password is more than 16 characters then it crypts the 17th to 24th
61 characters using as salt the first two base 64 digits from the second hash
62 block. And so on: I've seen references to it cutting off the password at
63 40 characters (5 blocks), 80 (10 blocks), or 128 (16 blocks). Some links:
64
65 http://cvs.pld.org.pl/pam/pamcrypt/bigcrypt.c?rev=1.2
66 http://seclists.org/bugtraq/1999/Mar/0109.html
67 http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-Q0R2D-
68 TET1_html/sec.c222.html#no_id_208
69
70 Exim has something it calls "crypt16". It will either use a native
71 crypt16 or its own implementation. A native crypt16 will presumably
72 be the one that I called "crypt16" above. The internal "crypt16"
73 function, however, is a two-block-maximum implementation of what I called
74 "bigcrypt". The documentation matches the internal code.
75
76 I suspect that whoever did the "crypt16" stuff for Exim didn't realise
77 that crypt16 and bigcrypt were different things.
78
79 Exim uses the LDAP-style scheme identifier "{crypt16}" to refer
80 to whatever it is using under that name. This unfortunately sets a
81 precedent for using "{crypt16}" to identify two incompatible algorithms
82 whose output can't be distinguished. With "{crypt16}" thus rendered
83 ambiguous, I suggest you deprecate it and invent two new identifiers
84 for the two algorithms.
85
86 Both crypt16 and bigcrypt are very poor algorithms, btw. Hashing parts
87 of the password separately means they can be cracked separately, so
88 the double-length hash only doubles the cracking effort instead of
89 squaring it. I recommend salted SHA-1 ({SSHA}), or the Blowfish-based
90 bcrypt ({CRYPT}$2a$).
91 </quote>
92 */
93
94
95
96
97 /*************************************************
98 * Local statics and tables *
99 *************************************************/
100
101 /* Table of item names, and corresponding switch numbers. The names must be in
102 alphabetical order. */
103
104 static uschar *item_table[] = {
105 US"acl",
106 US"dlfunc",
107 US"extract",
108 US"filter",
109 US"hash",
110 US"hmac",
111 US"if",
112 US"length",
113 US"lookup",
114 US"map",
115 US"nhash",
116 US"perl",
117 US"prvs",
118 US"prvscheck",
119 US"readfile",
120 US"readsocket",
121 US"reduce",
122 US"run",
123 US"sg",
124 US"substr",
125 US"tr" };
126
127 enum {
128 EITEM_ACL,
129 EITEM_DLFUNC,
130 EITEM_EXTRACT,
131 EITEM_FILTER,
132 EITEM_HASH,
133 EITEM_HMAC,
134 EITEM_IF,
135 EITEM_LENGTH,
136 EITEM_LOOKUP,
137 EITEM_MAP,
138 EITEM_NHASH,
139 EITEM_PERL,
140 EITEM_PRVS,
141 EITEM_PRVSCHECK,
142 EITEM_READFILE,
143 EITEM_READSOCK,
144 EITEM_REDUCE,
145 EITEM_RUN,
146 EITEM_SG,
147 EITEM_SUBSTR,
148 EITEM_TR };
149
150 /* Tables of operator names, and corresponding switch numbers. The names must be
151 in alphabetical order. There are two tables, because underscore is used in some
152 cases to introduce arguments, whereas for other it is part of the name. This is
153 an historical mis-design. */
154
155 static uschar *op_table_underscore[] = {
156 US"from_utf8",
157 US"local_part",
158 US"quote_local_part",
159 US"reverse_ip",
160 US"time_eval",
161 US"time_interval"};
162
163 enum {
164 EOP_FROM_UTF8,
165 EOP_LOCAL_PART,
166 EOP_QUOTE_LOCAL_PART,
167 EOP_REVERSE_IP,
168 EOP_TIME_EVAL,
169 EOP_TIME_INTERVAL };
170
171 static uschar *op_table_main[] = {
172 US"address",
173 US"addresses",
174 US"base62",
175 US"base62d",
176 US"domain",
177 US"escape",
178 US"eval",
179 US"eval10",
180 US"expand",
181 US"h",
182 US"hash",
183 US"hex2b64",
184 US"l",
185 US"lc",
186 US"length",
187 US"listcount",
188 US"listnamed",
189 US"mask",
190 US"md5",
191 US"nh",
192 US"nhash",
193 US"quote",
194 US"randint",
195 US"rfc2047",
196 US"rfc2047d",
197 US"rxquote",
198 US"s",
199 US"sha1",
200 US"stat",
201 US"str2b64",
202 US"strlen",
203 US"substr",
204 US"uc" };
205
206 enum {
207 EOP_ADDRESS = sizeof(op_table_underscore)/sizeof(uschar *),
208 EOP_ADDRESSES,
209 EOP_BASE62,
210 EOP_BASE62D,
211 EOP_DOMAIN,
212 EOP_ESCAPE,
213 EOP_EVAL,
214 EOP_EVAL10,
215 EOP_EXPAND,
216 EOP_H,
217 EOP_HASH,
218 EOP_HEX2B64,
219 EOP_L,
220 EOP_LC,
221 EOP_LENGTH,
222 EOP_LISTCOUNT,
223 EOP_LISTNAMED,
224 EOP_MASK,
225 EOP_MD5,
226 EOP_NH,
227 EOP_NHASH,
228 EOP_QUOTE,
229 EOP_RANDINT,
230 EOP_RFC2047,
231 EOP_RFC2047D,
232 EOP_RXQUOTE,
233 EOP_S,
234 EOP_SHA1,
235 EOP_STAT,
236 EOP_STR2B64,
237 EOP_STRLEN,
238 EOP_SUBSTR,
239 EOP_UC };
240
241
242 /* Table of condition names, and corresponding switch numbers. The names must
243 be in alphabetical order. */
244
245 static uschar *cond_table[] = {
246 US"<",
247 US"<=",
248 US"=",
249 US"==", /* Backward compatibility */
250 US">",
251 US">=",
252 US"acl",
253 US"and",
254 US"bool",
255 US"bool_lax",
256 US"crypteq",
257 US"def",
258 US"eq",
259 US"eqi",
260 US"exists",
261 US"first_delivery",
262 US"forall",
263 US"forany",
264 US"ge",
265 US"gei",
266 US"gt",
267 US"gti",
268 US"inlist",
269 US"inlisti",
270 US"isip",
271 US"isip4",
272 US"isip6",
273 US"ldapauth",
274 US"le",
275 US"lei",
276 US"lt",
277 US"lti",
278 US"match",
279 US"match_address",
280 US"match_domain",
281 US"match_ip",
282 US"match_local_part",
283 US"or",
284 US"pam",
285 US"pwcheck",
286 US"queue_running",
287 US"radius",
288 US"saslauthd"
289 };
290
291 enum {
292 ECOND_NUM_L,
293 ECOND_NUM_LE,
294 ECOND_NUM_E,
295 ECOND_NUM_EE,
296 ECOND_NUM_G,
297 ECOND_NUM_GE,
298 ECOND_ACL,
299 ECOND_AND,
300 ECOND_BOOL,
301 ECOND_BOOL_LAX,
302 ECOND_CRYPTEQ,
303 ECOND_DEF,
304 ECOND_STR_EQ,
305 ECOND_STR_EQI,
306 ECOND_EXISTS,
307 ECOND_FIRST_DELIVERY,
308 ECOND_FORALL,
309 ECOND_FORANY,
310 ECOND_STR_GE,
311 ECOND_STR_GEI,
312 ECOND_STR_GT,
313 ECOND_STR_GTI,
314 ECOND_INLIST,
315 ECOND_INLISTI,
316 ECOND_ISIP,
317 ECOND_ISIP4,
318 ECOND_ISIP6,
319 ECOND_LDAPAUTH,
320 ECOND_STR_LE,
321 ECOND_STR_LEI,
322 ECOND_STR_LT,
323 ECOND_STR_LTI,
324 ECOND_MATCH,
325 ECOND_MATCH_ADDRESS,
326 ECOND_MATCH_DOMAIN,
327 ECOND_MATCH_IP,
328 ECOND_MATCH_LOCAL_PART,
329 ECOND_OR,
330 ECOND_PAM,
331 ECOND_PWCHECK,
332 ECOND_QUEUE_RUNNING,
333 ECOND_RADIUS,
334 ECOND_SASLAUTHD
335 };
336
337
338 /* Type for main variable table */
339
340 typedef struct {
341 const char *name;
342 int type;
343 void *value;
344 } var_entry;
345
346 /* Type for entries pointing to address/length pairs. Not currently
347 in use. */
348
349 typedef struct {
350 uschar **address;
351 int *length;
352 } alblock;
353
354 /* Types of table entry */
355
356 enum {
357 vtype_int, /* value is address of int */
358 vtype_filter_int, /* ditto, but recognized only when filtering */
359 vtype_ino, /* value is address of ino_t (not always an int) */
360 vtype_uid, /* value is address of uid_t (not always an int) */
361 vtype_gid, /* value is address of gid_t (not always an int) */
362 vtype_bool, /* value is address of bool */
363 vtype_stringptr, /* value is address of pointer to string */
364 vtype_msgbody, /* as stringptr, but read when first required */
365 vtype_msgbody_end, /* ditto, the end of the message */
366 vtype_msgheaders, /* the message's headers, processed */
367 vtype_msgheaders_raw, /* the message's headers, unprocessed */
368 vtype_localpart, /* extract local part from string */
369 vtype_domain, /* extract domain from string */
370 vtype_string_func, /* value is string returned by given function */
371 vtype_todbsdin, /* value not used; generate BSD inbox tod */
372 vtype_tode, /* value not used; generate tod in epoch format */
373 vtype_todel, /* value not used; generate tod in epoch/usec format */
374 vtype_todf, /* value not used; generate full tod */
375 vtype_todl, /* value not used; generate log tod */
376 vtype_todlf, /* value not used; generate log file datestamp tod */
377 vtype_todzone, /* value not used; generate time zone only */
378 vtype_todzulu, /* value not used; generate zulu tod */
379 vtype_reply, /* value not used; get reply from headers */
380 vtype_pid, /* value not used; result is pid */
381 vtype_host_lookup, /* value not used; get host name */
382 vtype_load_avg, /* value not used; result is int from os_getloadavg */
383 vtype_pspace, /* partition space; value is T/F for spool/log */
384 vtype_pinodes /* partition inodes; value is T/F for spool/log */
385 #ifndef DISABLE_DKIM
386 ,vtype_dkim /* Lookup of value in DKIM signature */
387 #endif
388 };
389
390 static uschar * fn_recipients(void);
391
392 /* This table must be kept in alphabetical order. */
393
394 static var_entry var_table[] = {
395 /* WARNING: Do not invent variables whose names start acl_c or acl_m because
396 they will be confused with user-creatable ACL variables. */
397 { "acl_arg1", vtype_stringptr, &acl_arg[0] },
398 { "acl_arg2", vtype_stringptr, &acl_arg[1] },
399 { "acl_arg3", vtype_stringptr, &acl_arg[2] },
400 { "acl_arg4", vtype_stringptr, &acl_arg[3] },
401 { "acl_arg5", vtype_stringptr, &acl_arg[4] },
402 { "acl_arg6", vtype_stringptr, &acl_arg[5] },
403 { "acl_arg7", vtype_stringptr, &acl_arg[6] },
404 { "acl_arg8", vtype_stringptr, &acl_arg[7] },
405 { "acl_arg9", vtype_stringptr, &acl_arg[8] },
406 { "acl_narg", vtype_int, &acl_narg },
407 { "acl_verify_message", vtype_stringptr, &acl_verify_message },
408 { "address_data", vtype_stringptr, &deliver_address_data },
409 { "address_file", vtype_stringptr, &address_file },
410 { "address_pipe", vtype_stringptr, &address_pipe },
411 { "authenticated_id", vtype_stringptr, &authenticated_id },
412 { "authenticated_sender",vtype_stringptr, &authenticated_sender },
413 { "authentication_failed",vtype_int, &authentication_failed },
414 #ifdef WITH_CONTENT_SCAN
415 { "av_failed", vtype_int, &av_failed },
416 #endif
417 #ifdef EXPERIMENTAL_BRIGHTMAIL
418 { "bmi_alt_location", vtype_stringptr, &bmi_alt_location },
419 { "bmi_base64_tracker_verdict", vtype_stringptr, &bmi_base64_tracker_verdict },
420 { "bmi_base64_verdict", vtype_stringptr, &bmi_base64_verdict },
421 { "bmi_deliver", vtype_int, &bmi_deliver },
422 #endif
423 { "body_linecount", vtype_int, &body_linecount },
424 { "body_zerocount", vtype_int, &body_zerocount },
425 { "bounce_recipient", vtype_stringptr, &bounce_recipient },
426 { "bounce_return_size_limit", vtype_int, &bounce_return_size_limit },
427 { "caller_gid", vtype_gid, &real_gid },
428 { "caller_uid", vtype_uid, &real_uid },
429 { "compile_date", vtype_stringptr, &version_date },
430 { "compile_number", vtype_stringptr, &version_cnumber },
431 { "csa_status", vtype_stringptr, &csa_status },
432 #ifdef EXPERIMENTAL_DCC
433 { "dcc_header", vtype_stringptr, &dcc_header },
434 { "dcc_result", vtype_stringptr, &dcc_result },
435 #endif
436 #ifdef WITH_OLD_DEMIME
437 { "demime_errorlevel", vtype_int, &demime_errorlevel },
438 { "demime_reason", vtype_stringptr, &demime_reason },
439 #endif
440 #ifndef DISABLE_DKIM
441 { "dkim_algo", vtype_dkim, (void *)DKIM_ALGO },
442 { "dkim_bodylength", vtype_dkim, (void *)DKIM_BODYLENGTH },
443 { "dkim_canon_body", vtype_dkim, (void *)DKIM_CANON_BODY },
444 { "dkim_canon_headers", vtype_dkim, (void *)DKIM_CANON_HEADERS },
445 { "dkim_copiedheaders", vtype_dkim, (void *)DKIM_COPIEDHEADERS },
446 { "dkim_created", vtype_dkim, (void *)DKIM_CREATED },
447 { "dkim_cur_signer", vtype_stringptr, &dkim_cur_signer },
448 { "dkim_domain", vtype_stringptr, &dkim_signing_domain },
449 { "dkim_expires", vtype_dkim, (void *)DKIM_EXPIRES },
450 { "dkim_headernames", vtype_dkim, (void *)DKIM_HEADERNAMES },
451 { "dkim_identity", vtype_dkim, (void *)DKIM_IDENTITY },
452 { "dkim_key_granularity",vtype_dkim, (void *)DKIM_KEY_GRANULARITY },
453 { "dkim_key_nosubdomains",vtype_dkim, (void *)DKIM_NOSUBDOMAINS },
454 { "dkim_key_notes", vtype_dkim, (void *)DKIM_KEY_NOTES },
455 { "dkim_key_srvtype", vtype_dkim, (void *)DKIM_KEY_SRVTYPE },
456 { "dkim_key_testing", vtype_dkim, (void *)DKIM_KEY_TESTING },
457 { "dkim_selector", vtype_stringptr, &dkim_signing_selector },
458 { "dkim_signers", vtype_stringptr, &dkim_signers },
459 { "dkim_verify_reason", vtype_dkim, (void *)DKIM_VERIFY_REASON },
460 { "dkim_verify_status", vtype_dkim, (void *)DKIM_VERIFY_STATUS},
461 #endif
462 { "dnslist_domain", vtype_stringptr, &dnslist_domain },
463 { "dnslist_matched", vtype_stringptr, &dnslist_matched },
464 { "dnslist_text", vtype_stringptr, &dnslist_text },
465 { "dnslist_value", vtype_stringptr, &dnslist_value },
466 { "domain", vtype_stringptr, &deliver_domain },
467 { "domain_data", vtype_stringptr, &deliver_domain_data },
468 { "exim_gid", vtype_gid, &exim_gid },
469 { "exim_path", vtype_stringptr, &exim_path },
470 { "exim_uid", vtype_uid, &exim_uid },
471 #ifdef WITH_OLD_DEMIME
472 { "found_extension", vtype_stringptr, &found_extension },
473 #endif
474 { "headers_added", vtype_string_func, &fn_hdrs_added },
475 { "home", vtype_stringptr, &deliver_home },
476 { "host", vtype_stringptr, &deliver_host },
477 { "host_address", vtype_stringptr, &deliver_host_address },
478 { "host_data", vtype_stringptr, &host_data },
479 { "host_lookup_deferred",vtype_int, &host_lookup_deferred },
480 { "host_lookup_failed", vtype_int, &host_lookup_failed },
481 { "inode", vtype_ino, &deliver_inode },
482 { "interface_address", vtype_stringptr, &interface_address },
483 { "interface_port", vtype_int, &interface_port },
484 { "item", vtype_stringptr, &iterate_item },
485 #ifdef LOOKUP_LDAP
486 { "ldap_dn", vtype_stringptr, &eldap_dn },
487 #endif
488 { "load_average", vtype_load_avg, NULL },
489 { "local_part", vtype_stringptr, &deliver_localpart },
490 { "local_part_data", vtype_stringptr, &deliver_localpart_data },
491 { "local_part_prefix", vtype_stringptr, &deliver_localpart_prefix },
492 { "local_part_suffix", vtype_stringptr, &deliver_localpart_suffix },
493 { "local_scan_data", vtype_stringptr, &local_scan_data },
494 { "local_user_gid", vtype_gid, &local_user_gid },
495 { "local_user_uid", vtype_uid, &local_user_uid },
496 { "localhost_number", vtype_int, &host_number },
497 { "log_inodes", vtype_pinodes, (void *)FALSE },
498 { "log_space", vtype_pspace, (void *)FALSE },
499 { "mailstore_basename", vtype_stringptr, &mailstore_basename },
500 #ifdef WITH_CONTENT_SCAN
501 { "malware_name", vtype_stringptr, &malware_name },
502 #endif
503 { "max_received_linelength", vtype_int, &max_received_linelength },
504 { "message_age", vtype_int, &message_age },
505 { "message_body", vtype_msgbody, &message_body },
506 { "message_body_end", vtype_msgbody_end, &message_body_end },
507 { "message_body_size", vtype_int, &message_body_size },
508 { "message_exim_id", vtype_stringptr, &message_id },
509 { "message_headers", vtype_msgheaders, NULL },
510 { "message_headers_raw", vtype_msgheaders_raw, NULL },
511 { "message_id", vtype_stringptr, &message_id },
512 { "message_linecount", vtype_int, &message_linecount },
513 { "message_size", vtype_int, &message_size },
514 #ifdef WITH_CONTENT_SCAN
515 { "mime_anomaly_level", vtype_int, &mime_anomaly_level },
516 { "mime_anomaly_text", vtype_stringptr, &mime_anomaly_text },
517 { "mime_boundary", vtype_stringptr, &mime_boundary },
518 { "mime_charset", vtype_stringptr, &mime_charset },
519 { "mime_content_description", vtype_stringptr, &mime_content_description },
520 { "mime_content_disposition", vtype_stringptr, &mime_content_disposition },
521 { "mime_content_id", vtype_stringptr, &mime_content_id },
522 { "mime_content_size", vtype_int, &mime_content_size },
523 { "mime_content_transfer_encoding",vtype_stringptr, &mime_content_transfer_encoding },
524 { "mime_content_type", vtype_stringptr, &mime_content_type },
525 { "mime_decoded_filename", vtype_stringptr, &mime_decoded_filename },
526 { "mime_filename", vtype_stringptr, &mime_filename },
527 { "mime_is_coverletter", vtype_int, &mime_is_coverletter },
528 { "mime_is_multipart", vtype_int, &mime_is_multipart },
529 { "mime_is_rfc822", vtype_int, &mime_is_rfc822 },
530 { "mime_part_count", vtype_int, &mime_part_count },
531 #endif
532 { "n0", vtype_filter_int, &filter_n[0] },
533 { "n1", vtype_filter_int, &filter_n[1] },
534 { "n2", vtype_filter_int, &filter_n[2] },
535 { "n3", vtype_filter_int, &filter_n[3] },
536 { "n4", vtype_filter_int, &filter_n[4] },
537 { "n5", vtype_filter_int, &filter_n[5] },
538 { "n6", vtype_filter_int, &filter_n[6] },
539 { "n7", vtype_filter_int, &filter_n[7] },
540 { "n8", vtype_filter_int, &filter_n[8] },
541 { "n9", vtype_filter_int, &filter_n[9] },
542 { "original_domain", vtype_stringptr, &deliver_domain_orig },
543 { "original_local_part", vtype_stringptr, &deliver_localpart_orig },
544 { "originator_gid", vtype_gid, &originator_gid },
545 { "originator_uid", vtype_uid, &originator_uid },
546 { "parent_domain", vtype_stringptr, &deliver_domain_parent },
547 { "parent_local_part", vtype_stringptr, &deliver_localpart_parent },
548 { "pid", vtype_pid, NULL },
549 { "primary_hostname", vtype_stringptr, &primary_hostname },
550 { "prvscheck_address", vtype_stringptr, &prvscheck_address },
551 { "prvscheck_keynum", vtype_stringptr, &prvscheck_keynum },
552 { "prvscheck_result", vtype_stringptr, &prvscheck_result },
553 { "qualify_domain", vtype_stringptr, &qualify_domain_sender },
554 { "qualify_recipient", vtype_stringptr, &qualify_domain_recipient },
555 { "rcpt_count", vtype_int, &rcpt_count },
556 { "rcpt_defer_count", vtype_int, &rcpt_defer_count },
557 { "rcpt_fail_count", vtype_int, &rcpt_fail_count },
558 { "received_count", vtype_int, &received_count },
559 { "received_for", vtype_stringptr, &received_for },
560 { "received_ip_address", vtype_stringptr, &interface_address },
561 { "received_port", vtype_int, &interface_port },
562 { "received_protocol", vtype_stringptr, &received_protocol },
563 { "received_time", vtype_int, &received_time },
564 { "recipient_data", vtype_stringptr, &recipient_data },
565 { "recipient_verify_failure",vtype_stringptr,&recipient_verify_failure },
566 { "recipients", vtype_string_func, &fn_recipients },
567 { "recipients_count", vtype_int, &recipients_count },
568 #ifdef WITH_CONTENT_SCAN
569 { "regex_match_string", vtype_stringptr, &regex_match_string },
570 #endif
571 { "reply_address", vtype_reply, NULL },
572 { "return_path", vtype_stringptr, &return_path },
573 { "return_size_limit", vtype_int, &bounce_return_size_limit },
574 { "runrc", vtype_int, &runrc },
575 { "self_hostname", vtype_stringptr, &self_hostname },
576 { "sender_address", vtype_stringptr, &sender_address },
577 { "sender_address_data", vtype_stringptr, &sender_address_data },
578 { "sender_address_domain", vtype_domain, &sender_address },
579 { "sender_address_local_part", vtype_localpart, &sender_address },
580 { "sender_data", vtype_stringptr, &sender_data },
581 { "sender_fullhost", vtype_stringptr, &sender_fullhost },
582 { "sender_helo_name", vtype_stringptr, &sender_helo_name },
583 { "sender_host_address", vtype_stringptr, &sender_host_address },
584 { "sender_host_authenticated",vtype_stringptr, &sender_host_authenticated },
585 { "sender_host_dnssec", vtype_bool, &sender_host_dnssec },
586 { "sender_host_name", vtype_host_lookup, NULL },
587 { "sender_host_port", vtype_int, &sender_host_port },
588 { "sender_ident", vtype_stringptr, &sender_ident },
589 { "sender_rate", vtype_stringptr, &sender_rate },
590 { "sender_rate_limit", vtype_stringptr, &sender_rate_limit },
591 { "sender_rate_period", vtype_stringptr, &sender_rate_period },
592 { "sender_rcvhost", vtype_stringptr, &sender_rcvhost },
593 { "sender_verify_failure",vtype_stringptr, &sender_verify_failure },
594 { "sending_ip_address", vtype_stringptr, &sending_ip_address },
595 { "sending_port", vtype_int, &sending_port },
596 { "smtp_active_hostname", vtype_stringptr, &smtp_active_hostname },
597 { "smtp_command", vtype_stringptr, &smtp_cmd_buffer },
598 { "smtp_command_argument", vtype_stringptr, &smtp_cmd_argument },
599 { "smtp_count_at_connection_start", vtype_int, &smtp_accept_count },
600 { "smtp_notquit_reason", vtype_stringptr, &smtp_notquit_reason },
601 { "sn0", vtype_filter_int, &filter_sn[0] },
602 { "sn1", vtype_filter_int, &filter_sn[1] },
603 { "sn2", vtype_filter_int, &filter_sn[2] },
604 { "sn3", vtype_filter_int, &filter_sn[3] },
605 { "sn4", vtype_filter_int, &filter_sn[4] },
606 { "sn5", vtype_filter_int, &filter_sn[5] },
607 { "sn6", vtype_filter_int, &filter_sn[6] },
608 { "sn7", vtype_filter_int, &filter_sn[7] },
609 { "sn8", vtype_filter_int, &filter_sn[8] },
610 { "sn9", vtype_filter_int, &filter_sn[9] },
611 #ifdef WITH_CONTENT_SCAN
612 { "spam_bar", vtype_stringptr, &spam_bar },
613 { "spam_report", vtype_stringptr, &spam_report },
614 { "spam_score", vtype_stringptr, &spam_score },
615 { "spam_score_int", vtype_stringptr, &spam_score_int },
616 #endif
617 #ifdef EXPERIMENTAL_SPF
618 { "spf_guess", vtype_stringptr, &spf_guess },
619 { "spf_header_comment", vtype_stringptr, &spf_header_comment },
620 { "spf_received", vtype_stringptr, &spf_received },
621 { "spf_result", vtype_stringptr, &spf_result },
622 { "spf_smtp_comment", vtype_stringptr, &spf_smtp_comment },
623 #endif
624 { "spool_directory", vtype_stringptr, &spool_directory },
625 { "spool_inodes", vtype_pinodes, (void *)TRUE },
626 { "spool_space", vtype_pspace, (void *)TRUE },
627 #ifdef EXPERIMENTAL_SRS
628 { "srs_db_address", vtype_stringptr, &srs_db_address },
629 { "srs_db_key", vtype_stringptr, &srs_db_key },
630 { "srs_orig_recipient", vtype_stringptr, &srs_orig_recipient },
631 { "srs_orig_sender", vtype_stringptr, &srs_orig_sender },
632 { "srs_recipient", vtype_stringptr, &srs_recipient },
633 { "srs_status", vtype_stringptr, &srs_status },
634 #endif
635 { "thisaddress", vtype_stringptr, &filter_thisaddress },
636
637 /* The non-(in,out) variables are now deprecated */
638 { "tls_bits", vtype_int, &tls_in.bits },
639 { "tls_certificate_verified", vtype_int, &tls_in.certificate_verified },
640 { "tls_cipher", vtype_stringptr, &tls_in.cipher },
641
642 { "tls_in_bits", vtype_int, &tls_in.bits },
643 { "tls_in_certificate_verified", vtype_int, &tls_in.certificate_verified },
644 { "tls_in_cipher", vtype_stringptr, &tls_in.cipher },
645 { "tls_in_peerdn", vtype_stringptr, &tls_in.peerdn },
646 #if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
647 { "tls_in_sni", vtype_stringptr, &tls_in.sni },
648 #endif
649 { "tls_out_bits", vtype_int, &tls_out.bits },
650 { "tls_out_certificate_verified", vtype_int,&tls_out.certificate_verified },
651 { "tls_out_cipher", vtype_stringptr, &tls_out.cipher },
652 { "tls_out_peerdn", vtype_stringptr, &tls_out.peerdn },
653 #if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
654 { "tls_out_sni", vtype_stringptr, &tls_out.sni },
655 #endif
656
657 { "tls_peerdn", vtype_stringptr, &tls_in.peerdn }, /* mind the alphabetical order! */
658 #if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
659 { "tls_sni", vtype_stringptr, &tls_in.sni }, /* mind the alphabetical order! */
660 #endif
661
662 { "tod_bsdinbox", vtype_todbsdin, NULL },
663 { "tod_epoch", vtype_tode, NULL },
664 { "tod_epoch_l", vtype_todel, NULL },
665 { "tod_full", vtype_todf, NULL },
666 { "tod_log", vtype_todl, NULL },
667 { "tod_logfile", vtype_todlf, NULL },
668 { "tod_zone", vtype_todzone, NULL },
669 { "tod_zulu", vtype_todzulu, NULL },
670 { "value", vtype_stringptr, &lookup_value },
671 { "version_number", vtype_stringptr, &version_string },
672 { "warn_message_delay", vtype_stringptr, &warnmsg_delay },
673 { "warn_message_recipient",vtype_stringptr, &warnmsg_recipients },
674 { "warn_message_recipients",vtype_stringptr,&warnmsg_recipients },
675 { "warnmsg_delay", vtype_stringptr, &warnmsg_delay },
676 { "warnmsg_recipient", vtype_stringptr, &warnmsg_recipients },
677 { "warnmsg_recipients", vtype_stringptr, &warnmsg_recipients }
678 };
679
680 static int var_table_size = sizeof(var_table)/sizeof(var_entry);
681 static uschar var_buffer[256];
682 static BOOL malformed_header;
683
684 /* For textual hashes */
685
686 static const char *hashcodes = "abcdefghijklmnopqrtsuvwxyz"
687 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
688 "0123456789";
689
690 enum { HMAC_MD5, HMAC_SHA1 };
691
692 /* For numeric hashes */
693
694 static unsigned int prime[] = {
695 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
696 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
697 73, 79, 83, 89, 97, 101, 103, 107, 109, 113};
698
699 /* For printing modes in symbolic form */
700
701 static uschar *mtable_normal[] =
702 { US"---", US"--x", US"-w-", US"-wx", US"r--", US"r-x", US"rw-", US"rwx" };
703
704 static uschar *mtable_setid[] =
705 { US"--S", US"--s", US"-wS", US"-ws", US"r-S", US"r-s", US"rwS", US"rws" };
706
707 static uschar *mtable_sticky[] =
708 { US"--T", US"--t", US"-wT", US"-wt", US"r-T", US"r-t", US"rwT", US"rwt" };
709
710
711
712 /*************************************************
713 * Tables for UTF-8 support *
714 *************************************************/
715
716 /* Table of the number of extra characters, indexed by the first character
717 masked with 0x3f. The highest number for a valid UTF-8 character is in fact
718 0x3d. */
719
720 static uschar utf8_table1[] = {
721 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
722 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
723 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
724 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
725
726 /* These are the masks for the data bits in the first byte of a character,
727 indexed by the number of additional bytes. */
728
729 static int utf8_table2[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
730
731 /* Get the next UTF-8 character, advancing the pointer. */
732
733 #define GETUTF8INC(c, ptr) \
734 c = *ptr++; \
735 if ((c & 0xc0) == 0xc0) \
736 { \
737 int a = utf8_table1[c & 0x3f]; /* Number of additional bytes */ \
738 int s = 6*a; \
739 c = (c & utf8_table2[a]) << s; \
740 while (a-- > 0) \
741 { \
742 s -= 6; \
743 c |= (*ptr++ & 0x3f) << s; \
744 } \
745 }
746
747
748 /*************************************************
749 * Binary chop search on a table *
750 *************************************************/
751
752 /* This is used for matching expansion items and operators.
753
754 Arguments:
755 name the name that is being sought
756 table the table to search
757 table_size the number of items in the table
758
759 Returns: the offset in the table, or -1
760 */
761
762 static int
763 chop_match(uschar *name, uschar **table, int table_size)
764 {
765 uschar **bot = table;
766 uschar **top = table + table_size;
767
768 while (top > bot)
769 {
770 uschar **mid = bot + (top - bot)/2;
771 int c = Ustrcmp(name, *mid);
772 if (c == 0) return mid - table;
773 if (c > 0) bot = mid + 1; else top = mid;
774 }
775
776 return -1;
777 }
778
779
780
781 /*************************************************
782 * Check a condition string *
783 *************************************************/
784
785 /* This function is called to expand a string, and test the result for a "true"
786 or "false" value. Failure of the expansion yields FALSE; logged unless it was a
787 forced fail or lookup defer. All store used by the function can be released on
788 exit.
789
790 The actual false-value tests should be replicated for ECOND_BOOL_LAX.
791
792 Arguments:
793 condition the condition string
794 m1 text to be incorporated in panic error
795 m2 ditto
796
797 Returns: TRUE if condition is met, FALSE if not
798 */
799
800 BOOL
801 expand_check_condition(uschar *condition, uschar *m1, uschar *m2)
802 {
803 int rc;
804 void *reset_point = store_get(0);
805 uschar *ss = expand_string(condition);
806 if (ss == NULL)
807 {
808 if (!expand_string_forcedfail && !search_find_defer)
809 log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand condition \"%s\" "
810 "for %s %s: %s", condition, m1, m2, expand_string_message);
811 return FALSE;
812 }
813 rc = ss[0] != 0 && Ustrcmp(ss, "0") != 0 && strcmpic(ss, US"no") != 0 &&
814 strcmpic(ss, US"false") != 0;
815 store_reset(reset_point);
816 return rc;
817 }
818
819
820
821
822 /*************************************************
823 * Pseudo-random number generation *
824 *************************************************/
825
826 /* Pseudo-random number generation. The result is not "expected" to be
827 cryptographically strong but not so weak that someone will shoot themselves
828 in the foot using it as a nonce in some email header scheme or whatever
829 weirdness they'll twist this into. The result should ideally handle fork().
830
831 However, if we're stuck unable to provide this, then we'll fall back to
832 appallingly bad randomness.
833
834 If SUPPORT_TLS is defined then this will not be used except as an emergency
835 fallback.
836
837 Arguments:
838 max range maximum
839 Returns a random number in range [0, max-1]
840 */
841
842 #ifdef SUPPORT_TLS
843 # define vaguely_random_number vaguely_random_number_fallback
844 #endif
845 int
846 vaguely_random_number(int max)
847 {
848 #ifdef SUPPORT_TLS
849 # undef vaguely_random_number
850 #endif
851 static pid_t pid = 0;
852 pid_t p2;
853 #if defined(HAVE_SRANDOM) && !defined(HAVE_SRANDOMDEV)
854 struct timeval tv;
855 #endif
856
857 p2 = getpid();
858 if (p2 != pid)
859 {
860 if (pid != 0)
861 {
862
863 #ifdef HAVE_ARC4RANDOM
864 /* cryptographically strong randomness, common on *BSD platforms, not
865 so much elsewhere. Alas. */
866 arc4random_stir();
867 #elif defined(HAVE_SRANDOM) || defined(HAVE_SRANDOMDEV)
868 #ifdef HAVE_SRANDOMDEV
869 /* uses random(4) for seeding */
870 srandomdev();
871 #else
872 gettimeofday(&tv, NULL);
873 srandom(tv.tv_sec | tv.tv_usec | getpid());
874 #endif
875 #else
876 /* Poor randomness and no seeding here */
877 #endif
878
879 }
880 pid = p2;
881 }
882
883 #ifdef HAVE_ARC4RANDOM
884 return arc4random() % max;
885 #elif defined(HAVE_SRANDOM) || defined(HAVE_SRANDOMDEV)
886 return random() % max;
887 #else
888 /* This one returns a 16-bit number, definitely not crypto-strong */
889 return random_number(max);
890 #endif
891 }
892
893
894
895
896 /*************************************************
897 * Pick out a name from a string *
898 *************************************************/
899
900 /* If the name is too long, it is silently truncated.
901
902 Arguments:
903 name points to a buffer into which to put the name
904 max is the length of the buffer
905 s points to the first alphabetic character of the name
906 extras chars other than alphanumerics to permit
907
908 Returns: pointer to the first character after the name
909
910 Note: The test for *s != 0 in the while loop is necessary because
911 Ustrchr() yields non-NULL if the character is zero (which is not something
912 I expected). */
913
914 static uschar *
915 read_name(uschar *name, int max, uschar *s, uschar *extras)
916 {
917 int ptr = 0;
918 while (*s != 0 && (isalnum(*s) || Ustrchr(extras, *s) != NULL))
919 {
920 if (ptr < max-1) name[ptr++] = *s;
921 s++;
922 }
923 name[ptr] = 0;
924 return s;
925 }
926
927
928
929 /*************************************************
930 * Pick out the rest of a header name *
931 *************************************************/
932
933 /* A variable name starting $header_ (or just $h_ for those who like
934 abbreviations) might not be the complete header name because headers can
935 contain any printing characters in their names, except ':'. This function is
936 called to read the rest of the name, chop h[eader]_ off the front, and put ':'
937 on the end, if the name was terminated by white space.
938
939 Arguments:
940 name points to a buffer in which the name read so far exists
941 max is the length of the buffer
942 s points to the first character after the name so far, i.e. the
943 first non-alphameric character after $header_xxxxx
944
945 Returns: a pointer to the first character after the header name
946 */
947
948 static uschar *
949 read_header_name(uschar *name, int max, uschar *s)
950 {
951 int prelen = Ustrchr(name, '_') - name + 1;
952 int ptr = Ustrlen(name) - prelen;
953 if (ptr > 0) memmove(name, name+prelen, ptr);
954 while (mac_isgraph(*s) && *s != ':')
955 {
956 if (ptr < max-1) name[ptr++] = *s;
957 s++;
958 }
959 if (*s == ':') s++;
960 name[ptr++] = ':';
961 name[ptr] = 0;
962 return s;
963 }
964
965
966
967 /*************************************************
968 * Pick out a number from a string *
969 *************************************************/
970
971 /* Arguments:
972 n points to an integer into which to put the number
973 s points to the first digit of the number
974
975 Returns: a pointer to the character after the last digit
976 */
977
978 static uschar *
979 read_number(int *n, uschar *s)
980 {
981 *n = 0;
982 while (isdigit(*s)) *n = *n * 10 + (*s++ - '0');
983 return s;
984 }
985
986
987
988 /*************************************************
989 * Extract keyed subfield from a string *
990 *************************************************/
991
992 /* The yield is in dynamic store; NULL means that the key was not found.
993
994 Arguments:
995 key points to the name of the key
996 s points to the string from which to extract the subfield
997
998 Returns: NULL if the subfield was not found, or
999 a pointer to the subfield's data
1000 */
1001
1002 static uschar *
1003 expand_getkeyed(uschar *key, uschar *s)
1004 {
1005 int length = Ustrlen(key);
1006 while (isspace(*s)) s++;
1007
1008 /* Loop to search for the key */
1009
1010 while (*s != 0)
1011 {
1012 int dkeylength;
1013 uschar *data;
1014 uschar *dkey = s;
1015
1016 while (*s != 0 && *s != '=' && !isspace(*s)) s++;
1017 dkeylength = s - dkey;
1018 while (isspace(*s)) s++;
1019 if (*s == '=') while (isspace((*(++s))));
1020
1021 data = string_dequote(&s);
1022 if (length == dkeylength && strncmpic(key, dkey, length) == 0)
1023 return data;
1024
1025 while (isspace(*s)) s++;
1026 }
1027
1028 return NULL;
1029 }
1030
1031
1032
1033
1034 /*************************************************
1035 * Extract numbered subfield from string *
1036 *************************************************/
1037
1038 /* Extracts a numbered field from a string that is divided by tokens - for
1039 example a line from /etc/passwd is divided by colon characters. First field is
1040 numbered one. Negative arguments count from the right. Zero returns the whole
1041 string. Returns NULL if there are insufficient tokens in the string
1042
1043 ***WARNING***
1044 Modifies final argument - this is a dynamically generated string, so that's OK.
1045
1046 Arguments:
1047 field number of field to be extracted,
1048 first field = 1, whole string = 0, last field = -1
1049 separators characters that are used to break string into tokens
1050 s points to the string from which to extract the subfield
1051
1052 Returns: NULL if the field was not found,
1053 a pointer to the field's data inside s (modified to add 0)
1054 */
1055
1056 static uschar *
1057 expand_gettokened (int field, uschar *separators, uschar *s)
1058 {
1059 int sep = 1;
1060 int count;
1061 uschar *ss = s;
1062 uschar *fieldtext = NULL;
1063
1064 if (field == 0) return s;
1065
1066 /* Break the line up into fields in place; for field > 0 we stop when we have
1067 done the number of fields we want. For field < 0 we continue till the end of
1068 the string, counting the number of fields. */
1069
1070 count = (field > 0)? field : INT_MAX;
1071
1072 while (count-- > 0)
1073 {
1074 size_t len;
1075
1076 /* Previous field was the last one in the string. For a positive field
1077 number, this means there are not enough fields. For a negative field number,
1078 check that there are enough, and scan back to find the one that is wanted. */
1079
1080 if (sep == 0)
1081 {
1082 if (field > 0 || (-field) > (INT_MAX - count - 1)) return NULL;
1083 if ((-field) == (INT_MAX - count - 1)) return s;
1084 while (field++ < 0)
1085 {
1086 ss--;
1087 while (ss[-1] != 0) ss--;
1088 }
1089 fieldtext = ss;
1090 break;
1091 }
1092
1093 /* Previous field was not last in the string; save its start and put a
1094 zero at its end. */
1095
1096 fieldtext = ss;
1097 len = Ustrcspn(ss, separators);
1098 sep = ss[len];
1099 ss[len] = 0;
1100 ss += len + 1;
1101 }
1102
1103 return fieldtext;
1104 }
1105
1106
1107
1108 /*************************************************
1109 * Extract a substring from a string *
1110 *************************************************/
1111
1112 /* Perform the ${substr or ${length expansion operations.
1113
1114 Arguments:
1115 subject the input string
1116 value1 the offset from the start of the input string to the start of
1117 the output string; if negative, count from the right.
1118 value2 the length of the output string, or negative (-1) for unset
1119 if value1 is positive, unset means "all after"
1120 if value1 is negative, unset means "all before"
1121 len set to the length of the returned string
1122
1123 Returns: pointer to the output string, or NULL if there is an error
1124 */
1125
1126 static uschar *
1127 extract_substr(uschar *subject, int value1, int value2, int *len)
1128 {
1129 int sublen = Ustrlen(subject);
1130
1131 if (value1 < 0) /* count from right */
1132 {
1133 value1 += sublen;
1134
1135 /* If the position is before the start, skip to the start, and adjust the
1136 length. If the length ends up negative, the substring is null because nothing
1137 can precede. This falls out naturally when the length is unset, meaning "all
1138 to the left". */
1139
1140 if (value1 < 0)
1141 {
1142 value2 += value1;
1143 if (value2 < 0) value2 = 0;
1144 value1 = 0;
1145 }
1146
1147 /* Otherwise an unset length => characters before value1 */
1148
1149 else if (value2 < 0)
1150 {
1151 value2 = value1;
1152 value1 = 0;
1153 }
1154 }
1155
1156 /* For a non-negative offset, if the starting position is past the end of the
1157 string, the result will be the null string. Otherwise, an unset length means
1158 "rest"; just set it to the maximum - it will be cut down below if necessary. */
1159
1160 else
1161 {
1162 if (value1 > sublen)
1163 {
1164 value1 = sublen;
1165 value2 = 0;
1166 }
1167 else if (value2 < 0) value2 = sublen;
1168 }
1169
1170 /* Cut the length down to the maximum possible for the offset value, and get
1171 the required characters. */
1172
1173 if (value1 + value2 > sublen) value2 = sublen - value1;
1174 *len = value2;
1175 return subject + value1;
1176 }
1177
1178
1179
1180
1181 /*************************************************
1182 * Old-style hash of a string *
1183 *************************************************/
1184
1185 /* Perform the ${hash expansion operation.
1186
1187 Arguments:
1188 subject the input string (an expanded substring)
1189 value1 the length of the output string; if greater or equal to the
1190 length of the input string, the input string is returned
1191 value2 the number of hash characters to use, or 26 if negative
1192 len set to the length of the returned string
1193
1194 Returns: pointer to the output string, or NULL if there is an error
1195 */
1196
1197 static uschar *
1198 compute_hash(uschar *subject, int value1, int value2, int *len)
1199 {
1200 int sublen = Ustrlen(subject);
1201
1202 if (value2 < 0) value2 = 26;
1203 else if (value2 > Ustrlen(hashcodes))
1204 {
1205 expand_string_message =
1206 string_sprintf("hash count \"%d\" too big", value2);
1207 return NULL;
1208 }
1209
1210 /* Calculate the hash text. We know it is shorter than the original string, so
1211 can safely place it in subject[] (we know that subject is always itself an
1212 expanded substring). */
1213
1214 if (value1 < sublen)
1215 {
1216 int c;
1217 int i = 0;
1218 int j = value1;
1219 while ((c = (subject[j])) != 0)
1220 {
1221 int shift = (c + j++) & 7;
1222 subject[i] ^= (c << shift) | (c >> (8-shift));
1223 if (++i >= value1) i = 0;
1224 }
1225 for (i = 0; i < value1; i++)
1226 subject[i] = hashcodes[(subject[i]) % value2];
1227 }
1228 else value1 = sublen;
1229
1230 *len = value1;
1231 return subject;
1232 }
1233
1234
1235
1236
1237 /*************************************************
1238 * Numeric hash of a string *
1239 *************************************************/
1240
1241 /* Perform the ${nhash expansion operation. The first characters of the
1242 string are treated as most important, and get the highest prime numbers.
1243
1244 Arguments:
1245 subject the input string
1246 value1 the maximum value of the first part of the result
1247 value2 the maximum value of the second part of the result,
1248 or negative to produce only a one-part result
1249 len set to the length of the returned string
1250
1251 Returns: pointer to the output string, or NULL if there is an error.
1252 */
1253
1254 static uschar *
1255 compute_nhash (uschar *subject, int value1, int value2, int *len)
1256 {
1257 uschar *s = subject;
1258 int i = 0;
1259 unsigned long int total = 0; /* no overflow */
1260
1261 while (*s != 0)
1262 {
1263 if (i == 0) i = sizeof(prime)/sizeof(int) - 1;
1264 total += prime[i--] * (unsigned int)(*s++);
1265 }
1266
1267 /* If value2 is unset, just compute one number */
1268
1269 if (value2 < 0)
1270 {
1271 s = string_sprintf("%d", total % value1);
1272 }
1273
1274 /* Otherwise do a div/mod hash */
1275
1276 else
1277 {
1278 total = total % (value1 * value2);
1279 s = string_sprintf("%d/%d", total/value2, total % value2);
1280 }
1281
1282 *len = Ustrlen(s);
1283 return s;
1284 }
1285
1286
1287
1288
1289
1290 /*************************************************
1291 * Find the value of a header or headers *
1292 *************************************************/
1293
1294 /* Multiple instances of the same header get concatenated, and this function
1295 can also return a concatenation of all the header lines. When concatenating
1296 specific headers that contain lists of addresses, a comma is inserted between
1297 them. Otherwise we use a straight concatenation. Because some messages can have
1298 pathologically large number of lines, there is a limit on the length that is
1299 returned. Also, to avoid massive store use which would result from using
1300 string_cat() as it copies and extends strings, we do a preliminary pass to find
1301 out exactly how much store will be needed. On "normal" messages this will be
1302 pretty trivial.
1303
1304 Arguments:
1305 name the name of the header, without the leading $header_ or $h_,
1306 or NULL if a concatenation of all headers is required
1307 exists_only TRUE if called from a def: test; don't need to build a string;
1308 just return a string that is not "" and not "0" if the header
1309 exists
1310 newsize return the size of memory block that was obtained; may be NULL
1311 if exists_only is TRUE
1312 want_raw TRUE if called for $rh_ or $rheader_ variables; no processing,
1313 other than concatenating, will be done on the header. Also used
1314 for $message_headers_raw.
1315 charset name of charset to translate MIME words to; used only if
1316 want_raw is false; if NULL, no translation is done (this is
1317 used for $bh_ and $bheader_)
1318
1319 Returns: NULL if the header does not exist, else a pointer to a new
1320 store block
1321 */
1322
1323 static uschar *
1324 find_header(uschar *name, BOOL exists_only, int *newsize, BOOL want_raw,
1325 uschar *charset)
1326 {
1327 BOOL found = name == NULL;
1328 int comma = 0;
1329 int len = found? 0 : Ustrlen(name);
1330 int i;
1331 uschar *yield = NULL;
1332 uschar *ptr = NULL;
1333
1334 /* Loop for two passes - saves code repetition */
1335
1336 for (i = 0; i < 2; i++)
1337 {
1338 int size = 0;
1339 header_line *h;
1340
1341 for (h = header_list; size < header_insert_maxlen && h != NULL; h = h->next)
1342 {
1343 if (h->type != htype_old && h->text != NULL) /* NULL => Received: placeholder */
1344 {
1345 if (name == NULL || (len <= h->slen && strncmpic(name, h->text, len) == 0))
1346 {
1347 int ilen;
1348 uschar *t;
1349
1350 if (exists_only) return US"1"; /* don't need actual string */
1351 found = TRUE;
1352 t = h->text + len; /* text to insert */
1353 if (!want_raw) /* unless wanted raw, */
1354 while (isspace(*t)) t++; /* remove leading white space */
1355 ilen = h->slen - (t - h->text); /* length to insert */
1356
1357 /* Unless wanted raw, remove trailing whitespace, including the
1358 newline. */
1359
1360 if (!want_raw)
1361 while (ilen > 0 && isspace(t[ilen-1])) ilen--;
1362
1363 /* Set comma = 1 if handling a single header and it's one of those
1364 that contains an address list, except when asked for raw headers. Only
1365 need to do this once. */
1366
1367 if (!want_raw && name != NULL && comma == 0 &&
1368 Ustrchr("BCFRST", h->type) != NULL)
1369 comma = 1;
1370
1371 /* First pass - compute total store needed; second pass - compute
1372 total store used, including this header. */
1373
1374 size += ilen + comma + 1; /* +1 for the newline */
1375
1376 /* Second pass - concatentate the data, up to a maximum. Note that
1377 the loop stops when size hits the limit. */
1378
1379 if (i != 0)
1380 {
1381 if (size > header_insert_maxlen)
1382 {
1383 ilen -= size - header_insert_maxlen - 1;
1384 comma = 0;
1385 }
1386 Ustrncpy(ptr, t, ilen);
1387 ptr += ilen;
1388
1389 /* For a non-raw header, put in the comma if needed, then add
1390 back the newline we removed above, provided there was some text in
1391 the header. */
1392
1393 if (!want_raw && ilen > 0)
1394 {
1395 if (comma != 0) *ptr++ = ',';
1396 *ptr++ = '\n';
1397 }
1398 }
1399 }
1400 }
1401 }
1402
1403 /* At end of first pass, return NULL if no header found. Then truncate size
1404 if necessary, and get the buffer to hold the data, returning the buffer size.
1405 */
1406
1407 if (i == 0)
1408 {
1409 if (!found) return NULL;
1410 if (size > header_insert_maxlen) size = header_insert_maxlen;
1411 *newsize = size + 1;
1412 ptr = yield = store_get(*newsize);
1413 }
1414 }
1415
1416 /* That's all we do for raw header expansion. */
1417
1418 if (want_raw)
1419 {
1420 *ptr = 0;
1421 }
1422
1423 /* Otherwise, remove a final newline and a redundant added comma. Then we do
1424 RFC 2047 decoding, translating the charset if requested. The rfc2047_decode2()
1425 function can return an error with decoded data if the charset translation
1426 fails. If decoding fails, it returns NULL. */
1427
1428 else
1429 {
1430 uschar *decoded, *error;
1431 if (ptr > yield && ptr[-1] == '\n') ptr--;
1432 if (ptr > yield && comma != 0 && ptr[-1] == ',') ptr--;
1433 *ptr = 0;
1434 decoded = rfc2047_decode2(yield, check_rfc2047_length, charset, '?', NULL,
1435 newsize, &error);
1436 if (error != NULL)
1437 {
1438 DEBUG(D_any) debug_printf("*** error in RFC 2047 decoding: %s\n"
1439 " input was: %s\n", error, yield);
1440 }
1441 if (decoded != NULL) yield = decoded;
1442 }
1443
1444 return yield;
1445 }
1446
1447
1448
1449
1450 /*************************************************
1451 * Return list of recipients *
1452 *************************************************/
1453 /* A recipients list is available only during system message filtering,
1454 during ACL processing after DATA, and while expanding pipe commands
1455 generated from a system filter, but not elsewhere. */
1456
1457 static uschar *
1458 fn_recipients(void)
1459 {
1460 if (!enable_dollar_recipients) return NULL; else
1461 {
1462 int size = 128;
1463 int ptr = 0;
1464 int i;
1465 uschar * s = store_get(size);
1466 for (i = 0; i < recipients_count; i++)
1467 {
1468 if (i != 0) s = string_cat(s, &size, &ptr, US", ", 2);
1469 s = string_cat(s, &size, &ptr, recipients_list[i].address,
1470 Ustrlen(recipients_list[i].address));
1471 }
1472 s[ptr] = 0; /* string_cat() leaves room */
1473 return s;
1474 }
1475 }
1476
1477
1478 /*************************************************
1479 * Find value of a variable *
1480 *************************************************/
1481
1482 /* The table of variables is kept in alphabetic order, so we can search it
1483 using a binary chop. The "choplen" variable is nothing to do with the binary
1484 chop.
1485
1486 Arguments:
1487 name the name of the variable being sought
1488 exists_only TRUE if this is a def: test; passed on to find_header()
1489 skipping TRUE => skip any processing evaluation; this is not the same as
1490 exists_only because def: may test for values that are first
1491 evaluated here
1492 newsize pointer to an int which is initially zero; if the answer is in
1493 a new memory buffer, *newsize is set to its size
1494
1495 Returns: NULL if the variable does not exist, or
1496 a pointer to the variable's contents, or
1497 something non-NULL if exists_only is TRUE
1498 */
1499
1500 static uschar *
1501 find_variable(uschar *name, BOOL exists_only, BOOL skipping, int *newsize)
1502 {
1503 int first = 0;
1504 int last = var_table_size;
1505
1506 /* Handle ACL variables, whose names are of the form acl_cxxx or acl_mxxx.
1507 Originally, xxx had to be a number in the range 0-9 (later 0-19), but from
1508 release 4.64 onwards arbitrary names are permitted, as long as the first 5
1509 characters are acl_c or acl_m and the sixth is either a digit or an underscore
1510 (this gave backwards compatibility at the changeover). There may be built-in
1511 variables whose names start acl_ but they should never start in this way. This
1512 slightly messy specification is a consequence of the history, needless to say.
1513
1514 If an ACL variable does not exist, treat it as empty, unless strict_acl_vars is
1515 set, in which case give an error. */
1516
1517 if ((Ustrncmp(name, "acl_c", 5) == 0 || Ustrncmp(name, "acl_m", 5) == 0) &&
1518 !isalpha(name[5]))
1519 {
1520 tree_node *node =
1521 tree_search((name[4] == 'c')? acl_var_c : acl_var_m, name + 4);
1522 return (node == NULL)? (strict_acl_vars? NULL : US"") : node->data.ptr;
1523 }
1524
1525 /* Handle $auth<n> variables. */
1526
1527 if (Ustrncmp(name, "auth", 4) == 0)
1528 {
1529 uschar *endptr;
1530 int n = Ustrtoul(name + 4, &endptr, 10);
1531 if (*endptr == 0 && n != 0 && n <= AUTH_VARS)
1532 return (auth_vars[n-1] == NULL)? US"" : auth_vars[n-1];
1533 }
1534
1535 /* For all other variables, search the table */
1536
1537 while (last > first)
1538 {
1539 uschar *s, *domain;
1540 uschar **ss;
1541 int middle = (first + last)/2;
1542 int c = Ustrcmp(name, var_table[middle].name);
1543
1544 if (c > 0) { first = middle + 1; continue; }
1545 if (c < 0) { last = middle; continue; }
1546
1547 /* Found an existing variable. If in skipping state, the value isn't needed,
1548 and we want to avoid processing (such as looking up the host name). */
1549
1550 if (skipping) return US"";
1551
1552 switch (var_table[middle].type)
1553 {
1554 case vtype_filter_int:
1555 if (!filter_running) return NULL;
1556 /* Fall through */
1557 /* VVVVVVVVVVVV */
1558 case vtype_int:
1559 sprintf(CS var_buffer, "%d", *(int *)(var_table[middle].value)); /* Integer */
1560 return var_buffer;
1561
1562 case vtype_ino:
1563 sprintf(CS var_buffer, "%ld", (long int)(*(ino_t *)(var_table[middle].value))); /* Inode */
1564 return var_buffer;
1565
1566 case vtype_gid:
1567 sprintf(CS var_buffer, "%ld", (long int)(*(gid_t *)(var_table[middle].value))); /* gid */
1568 return var_buffer;
1569
1570 case vtype_uid:
1571 sprintf(CS var_buffer, "%ld", (long int)(*(uid_t *)(var_table[middle].value))); /* uid */
1572 return var_buffer;
1573
1574 case vtype_bool:
1575 sprintf(CS var_buffer, "%s", *(BOOL *)(var_table[middle].value) ? "yes" : "no"); /* bool */
1576 return var_buffer;
1577
1578 case vtype_stringptr: /* Pointer to string */
1579 s = *((uschar **)(var_table[middle].value));
1580 return (s == NULL)? US"" : s;
1581
1582 case vtype_pid:
1583 sprintf(CS var_buffer, "%d", (int)getpid()); /* pid */
1584 return var_buffer;
1585
1586 case vtype_load_avg:
1587 sprintf(CS var_buffer, "%d", OS_GETLOADAVG()); /* load_average */
1588 return var_buffer;
1589
1590 case vtype_host_lookup: /* Lookup if not done so */
1591 if (sender_host_name == NULL && sender_host_address != NULL &&
1592 !host_lookup_failed && host_name_lookup() == OK)
1593 host_build_sender_fullhost();
1594 return (sender_host_name == NULL)? US"" : sender_host_name;
1595
1596 case vtype_localpart: /* Get local part from address */
1597 s = *((uschar **)(var_table[middle].value));
1598 if (s == NULL) return US"";
1599 domain = Ustrrchr(s, '@');
1600 if (domain == NULL) return s;
1601 if (domain - s > sizeof(var_buffer) - 1)
1602 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "local part longer than " SIZE_T_FMT
1603 " in string expansion", sizeof(var_buffer));
1604 Ustrncpy(var_buffer, s, domain - s);
1605 var_buffer[domain - s] = 0;
1606 return var_buffer;
1607
1608 case vtype_domain: /* Get domain from address */
1609 s = *((uschar **)(var_table[middle].value));
1610 if (s == NULL) return US"";
1611 domain = Ustrrchr(s, '@');
1612 return (domain == NULL)? US"" : domain + 1;
1613
1614 case vtype_msgheaders:
1615 return find_header(NULL, exists_only, newsize, FALSE, NULL);
1616
1617 case vtype_msgheaders_raw:
1618 return find_header(NULL, exists_only, newsize, TRUE, NULL);
1619
1620 case vtype_msgbody: /* Pointer to msgbody string */
1621 case vtype_msgbody_end: /* Ditto, the end of the msg */
1622 ss = (uschar **)(var_table[middle].value);
1623 if (*ss == NULL && deliver_datafile >= 0) /* Read body when needed */
1624 {
1625 uschar *body;
1626 off_t start_offset = SPOOL_DATA_START_OFFSET;
1627 int len = message_body_visible;
1628 if (len > message_size) len = message_size;
1629 *ss = body = store_malloc(len+1);
1630 body[0] = 0;
1631 if (var_table[middle].type == vtype_msgbody_end)
1632 {
1633 struct stat statbuf;
1634 if (fstat(deliver_datafile, &statbuf) == 0)
1635 {
1636 start_offset = statbuf.st_size - len;
1637 if (start_offset < SPOOL_DATA_START_OFFSET)
1638 start_offset = SPOOL_DATA_START_OFFSET;
1639 }
1640 }
1641 lseek(deliver_datafile, start_offset, SEEK_SET);
1642 len = read(deliver_datafile, body, len);
1643 if (len > 0)
1644 {
1645 body[len] = 0;
1646 if (message_body_newlines) /* Separate loops for efficiency */
1647 {
1648 while (len > 0)
1649 { if (body[--len] == 0) body[len] = ' '; }
1650 }
1651 else
1652 {
1653 while (len > 0)
1654 { if (body[--len] == '\n' || body[len] == 0) body[len] = ' '; }
1655 }
1656 }
1657 }
1658 return (*ss == NULL)? US"" : *ss;
1659
1660 case vtype_todbsdin: /* BSD inbox time of day */
1661 return tod_stamp(tod_bsdin);
1662
1663 case vtype_tode: /* Unix epoch time of day */
1664 return tod_stamp(tod_epoch);
1665
1666 case vtype_todel: /* Unix epoch/usec time of day */
1667 return tod_stamp(tod_epoch_l);
1668
1669 case vtype_todf: /* Full time of day */
1670 return tod_stamp(tod_full);
1671
1672 case vtype_todl: /* Log format time of day */
1673 return tod_stamp(tod_log_bare); /* (without timezone) */
1674
1675 case vtype_todzone: /* Time zone offset only */
1676 return tod_stamp(tod_zone);
1677
1678 case vtype_todzulu: /* Zulu time */
1679 return tod_stamp(tod_zulu);
1680
1681 case vtype_todlf: /* Log file datestamp tod */
1682 return tod_stamp(tod_log_datestamp_daily);
1683
1684 case vtype_reply: /* Get reply address */
1685 s = find_header(US"reply-to:", exists_only, newsize, TRUE,
1686 headers_charset);
1687 if (s != NULL) while (isspace(*s)) s++;
1688 if (s == NULL || *s == 0)
1689 {
1690 *newsize = 0; /* For the *s==0 case */
1691 s = find_header(US"from:", exists_only, newsize, TRUE, headers_charset);
1692 }
1693 if (s != NULL)
1694 {
1695 uschar *t;
1696 while (isspace(*s)) s++;
1697 for (t = s; *t != 0; t++) if (*t == '\n') *t = ' ';
1698 while (t > s && isspace(t[-1])) t--;
1699 *t = 0;
1700 }
1701 return (s == NULL)? US"" : s;
1702
1703 case vtype_string_func:
1704 {
1705 uschar * (*fn)() = var_table[middle].value;
1706 return fn();
1707 }
1708
1709 case vtype_pspace:
1710 {
1711 int inodes;
1712 sprintf(CS var_buffer, "%d",
1713 receive_statvfs(var_table[middle].value == (void *)TRUE, &inodes));
1714 }
1715 return var_buffer;
1716
1717 case vtype_pinodes:
1718 {
1719 int inodes;
1720 (void) receive_statvfs(var_table[middle].value == (void *)TRUE, &inodes);
1721 sprintf(CS var_buffer, "%d", inodes);
1722 }
1723 return var_buffer;
1724
1725 #ifndef DISABLE_DKIM
1726 case vtype_dkim:
1727 return dkim_exim_expand_query((int)(long)var_table[middle].value);
1728 #endif
1729
1730 }
1731 }
1732
1733 return NULL; /* Unknown variable name */
1734 }
1735
1736
1737
1738
1739 void
1740 modify_variable(uschar *name, void * value)
1741 {
1742 int first = 0;
1743 int last = var_table_size;
1744
1745 while (last > first)
1746 {
1747 int middle = (first + last)/2;
1748 int c = Ustrcmp(name, var_table[middle].name);
1749
1750 if (c > 0) { first = middle + 1; continue; }
1751 if (c < 0) { last = middle; continue; }
1752
1753 /* Found an existing variable; change the item it refers to */
1754 var_table[middle].value = value;
1755 return;
1756 }
1757 return; /* Unknown variable name, fail silently */
1758 }
1759
1760
1761
1762
1763
1764 /*************************************************
1765 * Read and expand substrings *
1766 *************************************************/
1767
1768 /* This function is called to read and expand argument substrings for various
1769 expansion items. Some have a minimum requirement that is less than the maximum;
1770 in these cases, the first non-present one is set to NULL.
1771
1772 Arguments:
1773 sub points to vector of pointers to set
1774 n maximum number of substrings
1775 m minimum required
1776 sptr points to current string pointer
1777 skipping the skipping flag
1778 check_end if TRUE, check for final '}'
1779 name name of item, for error message
1780
1781 Returns: 0 OK; string pointer updated
1782 1 curly bracketing error (too few arguments)
1783 2 too many arguments (only if check_end is set); message set
1784 3 other error (expansion failure)
1785 */
1786
1787 static int
1788 read_subs(uschar **sub, int n, int m, uschar **sptr, BOOL skipping,
1789 BOOL check_end, uschar *name)
1790 {
1791 int i;
1792 uschar *s = *sptr;
1793
1794 while (isspace(*s)) s++;
1795 for (i = 0; i < n; i++)
1796 {
1797 if (*s != '{')
1798 {
1799 if (i < m) return 1;
1800 sub[i] = NULL;
1801 break;
1802 }
1803 sub[i] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE);
1804 if (sub[i] == NULL) return 3;
1805 if (*s++ != '}') return 1;
1806 while (isspace(*s)) s++;
1807 }
1808 if (check_end && *s++ != '}')
1809 {
1810 if (s[-1] == '{')
1811 {
1812 expand_string_message = string_sprintf("Too many arguments for \"%s\" "
1813 "(max is %d)", name, n);
1814 return 2;
1815 }
1816 return 1;
1817 }
1818
1819 *sptr = s;
1820 return 0;
1821 }
1822
1823
1824
1825
1826 /*************************************************
1827 * Elaborate message for bad variable *
1828 *************************************************/
1829
1830 /* For the "unknown variable" message, take a look at the variable's name, and
1831 give additional information about possible ACL variables. The extra information
1832 is added on to expand_string_message.
1833
1834 Argument: the name of the variable
1835 Returns: nothing
1836 */
1837
1838 static void
1839 check_variable_error_message(uschar *name)
1840 {
1841 if (Ustrncmp(name, "acl_", 4) == 0)
1842 expand_string_message = string_sprintf("%s (%s)", expand_string_message,
1843 (name[4] == 'c' || name[4] == 'm')?
1844 (isalpha(name[5])?
1845 US"6th character of a user-defined ACL variable must be a digit or underscore" :
1846 US"strict_acl_vars is set" /* Syntax is OK, it has to be this */
1847 ) :
1848 US"user-defined ACL variables must start acl_c or acl_m");
1849 }
1850
1851
1852
1853 /*
1854 Load args from sub array to globals, and call acl_check().
1855
1856 Returns: OK access is granted by an ACCEPT verb
1857 DISCARD access is granted by a DISCARD verb
1858 FAIL access is denied
1859 FAIL_DROP access is denied; drop the connection
1860 DEFER can't tell at the moment
1861 ERROR disaster
1862 */
1863 static int
1864 eval_acl(uschar ** sub, int nsub, uschar ** user_msgp)
1865 {
1866 int i;
1867 uschar *dummy_log_msg;
1868
1869 for (i = 1; i < nsub && sub[i]; i++)
1870 acl_arg[i-1] = sub[i];
1871 acl_narg = i-1;
1872 while (i < nsub)
1873 acl_arg[i++ - 1] = NULL;
1874
1875 DEBUG(D_expand)
1876 debug_printf("expanding: acl: %s arg: %s%s\n",
1877 sub[0],
1878 acl_narg>0 ? sub[1] : US"<none>",
1879 acl_narg>1 ? " +more" : "");
1880
1881 return acl_check(ACL_WHERE_EXPANSION, NULL, sub[0], user_msgp, &dummy_log_msg);
1882 }
1883
1884
1885
1886
1887 /*************************************************
1888 * Read and evaluate a condition *
1889 *************************************************/
1890
1891 /*
1892 Arguments:
1893 s points to the start of the condition text
1894 yield points to a BOOL to hold the result of the condition test;
1895 if NULL, we are just reading through a condition that is
1896 part of an "or" combination to check syntax, or in a state
1897 where the answer isn't required
1898
1899 Returns: a pointer to the first character after the condition, or
1900 NULL after an error
1901 */
1902
1903 static uschar *
1904 eval_condition(uschar *s, BOOL *yield)
1905 {
1906 BOOL testfor = TRUE;
1907 BOOL tempcond, combined_cond;
1908 BOOL *subcondptr;
1909 BOOL sub2_honour_dollar = TRUE;
1910 int i, rc, cond_type, roffset;
1911 int_eximarith_t num[2];
1912 struct stat statbuf;
1913 uschar name[256];
1914 uschar *sub[10];
1915
1916 const pcre *re;
1917 const uschar *rerror;
1918
1919 for (;;)
1920 {
1921 while (isspace(*s)) s++;
1922 if (*s == '!') { testfor = !testfor; s++; } else break;
1923 }
1924
1925 /* Numeric comparisons are symbolic */
1926
1927 if (*s == '=' || *s == '>' || *s == '<')
1928 {
1929 int p = 0;
1930 name[p++] = *s++;
1931 if (*s == '=')
1932 {
1933 name[p++] = '=';
1934 s++;
1935 }
1936 name[p] = 0;
1937 }
1938
1939 /* All other conditions are named */
1940
1941 else s = read_name(name, 256, s, US"_");
1942
1943 /* If we haven't read a name, it means some non-alpha character is first. */
1944
1945 if (name[0] == 0)
1946 {
1947 expand_string_message = string_sprintf("condition name expected, "
1948 "but found \"%.16s\"", s);
1949 return NULL;
1950 }
1951
1952 /* Find which condition we are dealing with, and switch on it */
1953
1954 cond_type = chop_match(name, cond_table, sizeof(cond_table)/sizeof(uschar *));
1955 switch(cond_type)
1956 {
1957 /* def: tests for a non-empty variable, or for the existence of a header. If
1958 yield == NULL we are in a skipping state, and don't care about the answer. */
1959
1960 case ECOND_DEF:
1961 if (*s != ':')
1962 {
1963 expand_string_message = US"\":\" expected after \"def\"";
1964 return NULL;
1965 }
1966
1967 s = read_name(name, 256, s+1, US"_");
1968
1969 /* Test for a header's existence. If the name contains a closing brace
1970 character, this may be a user error where the terminating colon has been
1971 omitted. Set a flag to adjust a subsequent error message in this case. */
1972
1973 if (Ustrncmp(name, "h_", 2) == 0 ||
1974 Ustrncmp(name, "rh_", 3) == 0 ||
1975 Ustrncmp(name, "bh_", 3) == 0 ||
1976 Ustrncmp(name, "header_", 7) == 0 ||
1977 Ustrncmp(name, "rheader_", 8) == 0 ||
1978 Ustrncmp(name, "bheader_", 8) == 0)
1979 {
1980 s = read_header_name(name, 256, s);
1981 /* {-for-text-editors */
1982 if (Ustrchr(name, '}') != NULL) malformed_header = TRUE;
1983 if (yield != NULL) *yield =
1984 (find_header(name, TRUE, NULL, FALSE, NULL) != NULL) == testfor;
1985 }
1986
1987 /* Test for a variable's having a non-empty value. A non-existent variable
1988 causes an expansion failure. */
1989
1990 else
1991 {
1992 uschar *value = find_variable(name, TRUE, yield == NULL, NULL);
1993 if (value == NULL)
1994 {
1995 expand_string_message = (name[0] == 0)?
1996 string_sprintf("variable name omitted after \"def:\"") :
1997 string_sprintf("unknown variable \"%s\" after \"def:\"", name);
1998 check_variable_error_message(name);
1999 return NULL;
2000 }
2001 if (yield != NULL) *yield = (value[0] != 0) == testfor;
2002 }
2003
2004 return s;
2005
2006
2007 /* first_delivery tests for first delivery attempt */
2008
2009 case ECOND_FIRST_DELIVERY:
2010 if (yield != NULL) *yield = deliver_firsttime == testfor;
2011 return s;
2012
2013
2014 /* queue_running tests for any process started by a queue runner */
2015
2016 case ECOND_QUEUE_RUNNING:
2017 if (yield != NULL) *yield = (queue_run_pid != (pid_t)0) == testfor;
2018 return s;
2019
2020
2021 /* exists: tests for file existence
2022 isip: tests for any IP address
2023 isip4: tests for an IPv4 address
2024 isip6: tests for an IPv6 address
2025 pam: does PAM authentication
2026 radius: does RADIUS authentication
2027 ldapauth: does LDAP authentication
2028 pwcheck: does Cyrus SASL pwcheck authentication
2029 */
2030
2031 case ECOND_EXISTS:
2032 case ECOND_ISIP:
2033 case ECOND_ISIP4:
2034 case ECOND_ISIP6:
2035 case ECOND_PAM:
2036 case ECOND_RADIUS:
2037 case ECOND_LDAPAUTH:
2038 case ECOND_PWCHECK:
2039
2040 while (isspace(*s)) s++;
2041 if (*s != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2042
2043 sub[0] = expand_string_internal(s+1, TRUE, &s, yield == NULL, TRUE);
2044 if (sub[0] == NULL) return NULL;
2045 /* {-for-text-editors */
2046 if (*s++ != '}') goto COND_FAILED_CURLY_END;
2047
2048 if (yield == NULL) return s; /* No need to run the test if skipping */
2049
2050 switch(cond_type)
2051 {
2052 case ECOND_EXISTS:
2053 if ((expand_forbid & RDO_EXISTS) != 0)
2054 {
2055 expand_string_message = US"File existence tests are not permitted";
2056 return NULL;
2057 }
2058 *yield = (Ustat(sub[0], &statbuf) == 0) == testfor;
2059 break;
2060
2061 case ECOND_ISIP:
2062 case ECOND_ISIP4:
2063 case ECOND_ISIP6:
2064 rc = string_is_ip_address(sub[0], NULL);
2065 *yield = ((cond_type == ECOND_ISIP)? (rc != 0) :
2066 (cond_type == ECOND_ISIP4)? (rc == 4) : (rc == 6)) == testfor;
2067 break;
2068
2069 /* Various authentication tests - all optionally compiled */
2070
2071 case ECOND_PAM:
2072 #ifdef SUPPORT_PAM
2073 rc = auth_call_pam(sub[0], &expand_string_message);
2074 goto END_AUTH;
2075 #else
2076 goto COND_FAILED_NOT_COMPILED;
2077 #endif /* SUPPORT_PAM */
2078
2079 case ECOND_RADIUS:
2080 #ifdef RADIUS_CONFIG_FILE
2081 rc = auth_call_radius(sub[0], &expand_string_message);
2082 goto END_AUTH;
2083 #else
2084 goto COND_FAILED_NOT_COMPILED;
2085 #endif /* RADIUS_CONFIG_FILE */
2086
2087 case ECOND_LDAPAUTH:
2088 #ifdef LOOKUP_LDAP
2089 {
2090 /* Just to keep the interface the same */
2091 BOOL do_cache;
2092 int old_pool = store_pool;
2093 store_pool = POOL_SEARCH;
2094 rc = eldapauth_find((void *)(-1), NULL, sub[0], Ustrlen(sub[0]), NULL,
2095 &expand_string_message, &do_cache);
2096 store_pool = old_pool;
2097 }
2098 goto END_AUTH;
2099 #else
2100 goto COND_FAILED_NOT_COMPILED;
2101 #endif /* LOOKUP_LDAP */
2102
2103 case ECOND_PWCHECK:
2104 #ifdef CYRUS_PWCHECK_SOCKET
2105 rc = auth_call_pwcheck(sub[0], &expand_string_message);
2106 goto END_AUTH;
2107 #else
2108 goto COND_FAILED_NOT_COMPILED;
2109 #endif /* CYRUS_PWCHECK_SOCKET */
2110
2111 #if defined(SUPPORT_PAM) || defined(RADIUS_CONFIG_FILE) || \
2112 defined(LOOKUP_LDAP) || defined(CYRUS_PWCHECK_SOCKET)
2113 END_AUTH:
2114 if (rc == ERROR || rc == DEFER) return NULL;
2115 *yield = (rc == OK) == testfor;
2116 #endif
2117 }
2118 return s;
2119
2120
2121 /* call ACL (in a conditional context). Accept true, deny false.
2122 Defer is a forced-fail. Anything set by message= goes to $value.
2123 Up to ten parameters are used; we use the braces round the name+args
2124 like the saslauthd condition does, to permit a variable number of args.
2125 See also the expansion-item version EITEM_ACL and the traditional
2126 acl modifier ACLC_ACL.
2127 */
2128
2129 case ECOND_ACL:
2130 /* ${if acl {{name}{arg1}{arg2}...} {yes}{no}} */
2131 {
2132 uschar *nameargs;
2133 uschar *user_msg;
2134 BOOL cond = FALSE;
2135 int size = 0;
2136 int ptr = 0;
2137
2138 while (isspace(*s)) s++;
2139 if (*s++ != '{') goto COND_FAILED_CURLY_START;
2140
2141 switch(read_subs(sub, sizeof(sub)/sizeof(*sub), 1,
2142 &s, yield == NULL, TRUE, US"acl"))
2143 {
2144 case 1: expand_string_message = US"too few arguments or bracketing "
2145 "error for acl";
2146 case 2:
2147 case 3: return NULL;
2148 }
2149
2150 if (yield != NULL) switch(eval_acl(sub, sizeof(sub)/sizeof(*sub), &user_msg))
2151 {
2152 case OK:
2153 cond = TRUE;
2154 case FAIL:
2155 lookup_value = NULL;
2156 if (user_msg)
2157 {
2158 lookup_value = string_cat(NULL, &size, &ptr, user_msg, Ustrlen(user_msg));
2159 lookup_value[ptr] = '\0';
2160 }
2161 *yield = cond == testfor;
2162 break;
2163
2164 case DEFER:
2165 expand_string_forcedfail = TRUE;
2166 default:
2167 expand_string_message = string_sprintf("error from acl \"%s\"", sub[0]);
2168 return NULL;
2169 }
2170 return s;
2171 }
2172
2173
2174 /* saslauthd: does Cyrus saslauthd authentication. Four parameters are used:
2175
2176 ${if saslauthd {{username}{password}{service}{realm}} {yes}[no}}
2177
2178 However, the last two are optional. That is why the whole set is enclosed
2179 in their own set of braces. */
2180
2181 case ECOND_SASLAUTHD:
2182 #ifndef CYRUS_SASLAUTHD_SOCKET
2183 goto COND_FAILED_NOT_COMPILED;
2184 #else
2185 while (isspace(*s)) s++;
2186 if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2187 switch(read_subs(sub, 4, 2, &s, yield == NULL, TRUE, US"saslauthd"))
2188 {
2189 case 1: expand_string_message = US"too few arguments or bracketing "
2190 "error for saslauthd";
2191 case 2:
2192 case 3: return NULL;
2193 }
2194 if (sub[2] == NULL) sub[3] = NULL; /* realm if no service */
2195 if (yield != NULL)
2196 {
2197 int rc;
2198 rc = auth_call_saslauthd(sub[0], sub[1], sub[2], sub[3],
2199 &expand_string_message);
2200 if (rc == ERROR || rc == DEFER) return NULL;
2201 *yield = (rc == OK) == testfor;
2202 }
2203 return s;
2204 #endif /* CYRUS_SASLAUTHD_SOCKET */
2205
2206
2207 /* symbolic operators for numeric and string comparison, and a number of
2208 other operators, all requiring two arguments.
2209
2210 crypteq: encrypts plaintext and compares against an encrypted text,
2211 using crypt(), crypt16(), MD5 or SHA-1
2212 inlist/inlisti: checks if first argument is in the list of the second
2213 match: does a regular expression match and sets up the numerical
2214 variables if it succeeds
2215 match_address: matches in an address list
2216 match_domain: matches in a domain list
2217 match_ip: matches a host list that is restricted to IP addresses
2218 match_local_part: matches in a local part list
2219 */
2220
2221 case ECOND_MATCH_ADDRESS:
2222 case ECOND_MATCH_DOMAIN:
2223 case ECOND_MATCH_IP:
2224 case ECOND_MATCH_LOCAL_PART:
2225 #ifndef EXPAND_LISTMATCH_RHS
2226 sub2_honour_dollar = FALSE;
2227 #endif
2228 /* FALLTHROUGH */
2229
2230 case ECOND_CRYPTEQ:
2231 case ECOND_INLIST:
2232 case ECOND_INLISTI:
2233 case ECOND_MATCH:
2234
2235 case ECOND_NUM_L: /* Numerical comparisons */
2236 case ECOND_NUM_LE:
2237 case ECOND_NUM_E:
2238 case ECOND_NUM_EE:
2239 case ECOND_NUM_G:
2240 case ECOND_NUM_GE:
2241
2242 case ECOND_STR_LT: /* String comparisons */
2243 case ECOND_STR_LTI:
2244 case ECOND_STR_LE:
2245 case ECOND_STR_LEI:
2246 case ECOND_STR_EQ:
2247 case ECOND_STR_EQI:
2248 case ECOND_STR_GT:
2249 case ECOND_STR_GTI:
2250 case ECOND_STR_GE:
2251 case ECOND_STR_GEI:
2252
2253 for (i = 0; i < 2; i++)
2254 {
2255 /* Sometimes, we don't expand substrings; too many insecure configurations
2256 created using match_address{}{} and friends, where the second param
2257 includes information from untrustworthy sources. */
2258 BOOL honour_dollar = TRUE;
2259 if ((i > 0) && !sub2_honour_dollar)
2260 honour_dollar = FALSE;
2261
2262 while (isspace(*s)) s++;
2263 if (*s != '{')
2264 {
2265 if (i == 0) goto COND_FAILED_CURLY_START;
2266 expand_string_message = string_sprintf("missing 2nd string in {} "
2267 "after \"%s\"", name);
2268 return NULL;
2269 }
2270 sub[i] = expand_string_internal(s+1, TRUE, &s, yield == NULL,
2271 honour_dollar);
2272 if (sub[i] == NULL) return NULL;
2273 if (*s++ != '}') goto COND_FAILED_CURLY_END;
2274
2275 /* Convert to numerical if required; we know that the names of all the
2276 conditions that compare numbers do not start with a letter. This just saves
2277 checking for them individually. */
2278
2279 if (!isalpha(name[0]) && yield != NULL)
2280 {
2281 if (sub[i][0] == 0)
2282 {
2283 num[i] = 0;
2284 DEBUG(D_expand)
2285 debug_printf("empty string cast to zero for numerical comparison\n");
2286 }
2287 else
2288 {
2289 num[i] = expand_string_integer(sub[i], FALSE);
2290 if (expand_string_message != NULL) return NULL;
2291 }
2292 }
2293 }
2294
2295 /* Result not required */
2296
2297 if (yield == NULL) return s;
2298
2299 /* Do an appropriate comparison */
2300
2301 switch(cond_type)
2302 {
2303 case ECOND_NUM_E:
2304 case ECOND_NUM_EE:
2305 tempcond = (num[0] == num[1]);
2306 break;
2307
2308 case ECOND_NUM_G:
2309 tempcond = (num[0] > num[1]);
2310 break;
2311
2312 case ECOND_NUM_GE:
2313 tempcond = (num[0] >= num[1]);
2314 break;
2315
2316 case ECOND_NUM_L:
2317 tempcond = (num[0] < num[1]);
2318 break;
2319
2320 case ECOND_NUM_LE:
2321 tempcond = (num[0] <= num[1]);
2322 break;
2323
2324 case ECOND_STR_LT:
2325 tempcond = (Ustrcmp(sub[0], sub[1]) < 0);
2326 break;
2327
2328 case ECOND_STR_LTI:
2329 tempcond = (strcmpic(sub[0], sub[1]) < 0);
2330 break;
2331
2332 case ECOND_STR_LE:
2333 tempcond = (Ustrcmp(sub[0], sub[1]) <= 0);
2334 break;
2335
2336 case ECOND_STR_LEI:
2337 tempcond = (strcmpic(sub[0], sub[1]) <= 0);
2338 break;
2339
2340 case ECOND_STR_EQ:
2341 tempcond = (Ustrcmp(sub[0], sub[1]) == 0);
2342 break;
2343
2344 case ECOND_STR_EQI:
2345 tempcond = (strcmpic(sub[0], sub[1]) == 0);
2346 break;
2347
2348 case ECOND_STR_GT:
2349 tempcond = (Ustrcmp(sub[0], sub[1]) > 0);
2350 break;
2351
2352 case ECOND_STR_GTI:
2353 tempcond = (strcmpic(sub[0], sub[1]) > 0);
2354 break;
2355
2356 case ECOND_STR_GE:
2357 tempcond = (Ustrcmp(sub[0], sub[1]) >= 0);
2358 break;
2359
2360 case ECOND_STR_GEI:
2361 tempcond = (strcmpic(sub[0], sub[1]) >= 0);
2362 break;
2363
2364 case ECOND_MATCH: /* Regular expression match */
2365 re = pcre_compile(CS sub[1], PCRE_COPT, (const char **)&rerror, &roffset,
2366 NULL);
2367 if (re == NULL)
2368 {
2369 expand_string_message = string_sprintf("regular expression error in "
2370 "\"%s\": %s at offset %d", sub[1], rerror, roffset);
2371 return NULL;
2372 }
2373 tempcond = regex_match_and_setup(re, sub[0], 0, -1);
2374 break;
2375
2376 case ECOND_MATCH_ADDRESS: /* Match in an address list */
2377 rc = match_address_list(sub[0], TRUE, FALSE, &(sub[1]), NULL, -1, 0, NULL);
2378 goto MATCHED_SOMETHING;
2379
2380 case ECOND_MATCH_DOMAIN: /* Match in a domain list */
2381 rc = match_isinlist(sub[0], &(sub[1]), 0, &domainlist_anchor, NULL,
2382 MCL_DOMAIN + MCL_NOEXPAND, TRUE, NULL);
2383 goto MATCHED_SOMETHING;
2384
2385 case ECOND_MATCH_IP: /* Match IP address in a host list */
2386 if (sub[0][0] != 0 && string_is_ip_address(sub[0], NULL) == 0)
2387 {
2388 expand_string_message = string_sprintf("\"%s\" is not an IP address",
2389 sub[0]);
2390 return NULL;
2391 }
2392 else
2393 {
2394 unsigned int *nullcache = NULL;
2395 check_host_block cb;
2396
2397 cb.host_name = US"";
2398 cb.host_address = sub[0];
2399
2400 /* If the host address starts off ::ffff: it is an IPv6 address in
2401 IPv4-compatible mode. Find the IPv4 part for checking against IPv4
2402 addresses. */
2403
2404 cb.host_ipv4 = (Ustrncmp(cb.host_address, "::ffff:", 7) == 0)?
2405 cb.host_address + 7 : cb.host_address;
2406
2407 rc = match_check_list(
2408 &sub[1], /* the list */
2409 0, /* separator character */
2410 &hostlist_anchor, /* anchor pointer */
2411 &nullcache, /* cache pointer */
2412 check_host, /* function for testing */
2413 &cb, /* argument for function */
2414 MCL_HOST, /* type of check */
2415 sub[0], /* text for debugging */
2416 NULL); /* where to pass back data */
2417 }
2418 goto MATCHED_SOMETHING;
2419
2420 case ECOND_MATCH_LOCAL_PART:
2421 rc = match_isinlist(sub[0], &(sub[1]), 0, &localpartlist_anchor, NULL,
2422 MCL_LOCALPART + MCL_NOEXPAND, TRUE, NULL);
2423 /* Fall through */
2424 /* VVVVVVVVVVVV */
2425 MATCHED_SOMETHING:
2426 switch(rc)
2427 {
2428 case OK:
2429 tempcond = TRUE;
2430 break;
2431
2432 case FAIL:
2433 tempcond = FALSE;
2434 break;
2435
2436 case DEFER:
2437 expand_string_message = string_sprintf("unable to complete match "
2438 "against \"%s\": %s", sub[1], search_error_message);
2439 return NULL;
2440 }
2441
2442 break;
2443
2444 /* Various "encrypted" comparisons. If the second string starts with
2445 "{" then an encryption type is given. Default to crypt() or crypt16()
2446 (build-time choice). */
2447 /* }-for-text-editors */
2448
2449 case ECOND_CRYPTEQ:
2450 #ifndef SUPPORT_CRYPTEQ
2451 goto COND_FAILED_NOT_COMPILED;
2452 #else
2453 if (strncmpic(sub[1], US"{md5}", 5) == 0)
2454 {
2455 int sublen = Ustrlen(sub[1]+5);
2456 md5 base;
2457 uschar digest[16];
2458
2459 md5_start(&base);
2460 md5_end(&base, (uschar *)sub[0], Ustrlen(sub[0]), digest);
2461
2462 /* If the length that we are comparing against is 24, the MD5 digest
2463 is expressed as a base64 string. This is the way LDAP does it. However,
2464 some other software uses a straightforward hex representation. We assume
2465 this if the length is 32. Other lengths fail. */
2466
2467 if (sublen == 24)
2468 {
2469 uschar *coded = auth_b64encode((uschar *)digest, 16);
2470 DEBUG(D_auth) debug_printf("crypteq: using MD5+B64 hashing\n"
2471 " subject=%s\n crypted=%s\n", coded, sub[1]+5);
2472 tempcond = (Ustrcmp(coded, sub[1]+5) == 0);
2473 }
2474 else if (sublen == 32)
2475 {
2476 int i;
2477 uschar coded[36];
2478 for (i = 0; i < 16; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
2479 coded[32] = 0;
2480 DEBUG(D_auth) debug_printf("crypteq: using MD5+hex hashing\n"
2481 " subject=%s\n crypted=%s\n", coded, sub[1]+5);
2482 tempcond = (strcmpic(coded, sub[1]+5) == 0);
2483 }
2484 else
2485 {
2486 DEBUG(D_auth) debug_printf("crypteq: length for MD5 not 24 or 32: "
2487 "fail\n crypted=%s\n", sub[1]+5);
2488 tempcond = FALSE;
2489 }
2490 }
2491
2492 else if (strncmpic(sub[1], US"{sha1}", 6) == 0)
2493 {
2494 int sublen = Ustrlen(sub[1]+6);
2495 sha1 base;
2496 uschar digest[20];
2497
2498 sha1_start(&base);
2499 sha1_end(&base, (uschar *)sub[0], Ustrlen(sub[0]), digest);
2500
2501 /* If the length that we are comparing against is 28, assume the SHA1
2502 digest is expressed as a base64 string. If the length is 40, assume a
2503 straightforward hex representation. Other lengths fail. */
2504
2505 if (sublen == 28)
2506 {
2507 uschar *coded = auth_b64encode((uschar *)digest, 20);
2508 DEBUG(D_auth) debug_printf("crypteq: using SHA1+B64 hashing\n"
2509 " subject=%s\n crypted=%s\n", coded, sub[1]+6);
2510 tempcond = (Ustrcmp(coded, sub[1]+6) == 0);
2511 }
2512 else if (sublen == 40)
2513 {
2514 int i;
2515 uschar coded[44];
2516 for (i = 0; i < 20; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
2517 coded[40] = 0;
2518 DEBUG(D_auth) debug_printf("crypteq: using SHA1+hex hashing\n"
2519 " subject=%s\n crypted=%s\n", coded, sub[1]+6);
2520 tempcond = (strcmpic(coded, sub[1]+6) == 0);
2521 }
2522 else
2523 {
2524 DEBUG(D_auth) debug_printf("crypteq: length for SHA-1 not 28 or 40: "
2525 "fail\n crypted=%s\n", sub[1]+6);
2526 tempcond = FALSE;
2527 }
2528 }
2529
2530 else /* {crypt} or {crypt16} and non-{ at start */
2531 /* }-for-text-editors */
2532 {
2533 int which = 0;
2534 uschar *coded;
2535
2536 if (strncmpic(sub[1], US"{crypt}", 7) == 0)
2537 {
2538 sub[1] += 7;
2539 which = 1;
2540 }
2541 else if (strncmpic(sub[1], US"{crypt16}", 9) == 0)
2542 {
2543 sub[1] += 9;
2544 which = 2;
2545 }
2546 else if (sub[1][0] == '{') /* }-for-text-editors */
2547 {
2548 expand_string_message = string_sprintf("unknown encryption mechanism "
2549 "in \"%s\"", sub[1]);
2550 return NULL;
2551 }
2552
2553 switch(which)
2554 {
2555 case 0: coded = US DEFAULT_CRYPT(CS sub[0], CS sub[1]); break;
2556 case 1: coded = US crypt(CS sub[0], CS sub[1]); break;
2557 default: coded = US crypt16(CS sub[0], CS sub[1]); break;
2558 }
2559
2560 #define STR(s) # s
2561 #define XSTR(s) STR(s)
2562 DEBUG(D_auth) debug_printf("crypteq: using %s()\n"
2563 " subject=%s\n crypted=%s\n",
2564 (which == 0)? XSTR(DEFAULT_CRYPT) : (which == 1)? "crypt" : "crypt16",
2565 coded, sub[1]);
2566 #undef STR
2567 #undef XSTR
2568
2569 /* If the encrypted string contains fewer than two characters (for the
2570 salt), force failure. Otherwise we get false positives: with an empty
2571 string the yield of crypt() is an empty string! */
2572
2573 tempcond = (Ustrlen(sub[1]) < 2)? FALSE :
2574 (Ustrcmp(coded, sub[1]) == 0);
2575 }
2576 break;
2577 #endif /* SUPPORT_CRYPTEQ */
2578
2579 case ECOND_INLIST:
2580 case ECOND_INLISTI:
2581 {
2582 int sep = 0;
2583 uschar *save_iterate_item = iterate_item;
2584 int (*compare)(const uschar *, const uschar *);
2585
2586 tempcond = FALSE;
2587 if (cond_type == ECOND_INLISTI)
2588 compare = strcmpic;
2589 else
2590 compare = (int (*)(const uschar *, const uschar *)) strcmp;
2591
2592 while ((iterate_item = string_nextinlist(&sub[1], &sep, NULL, 0)) != NULL)
2593 if (compare(sub[0], iterate_item) == 0)
2594 {
2595 tempcond = TRUE;
2596 break;
2597 }
2598 iterate_item = save_iterate_item;
2599 }
2600
2601 } /* Switch for comparison conditions */
2602
2603 *yield = tempcond == testfor;
2604 return s; /* End of comparison conditions */
2605
2606
2607 /* and/or: computes logical and/or of several conditions */
2608
2609 case ECOND_AND:
2610 case ECOND_OR:
2611 subcondptr = (yield == NULL)? NULL : &tempcond;
2612 combined_cond = (cond_type == ECOND_AND);
2613
2614 while (isspace(*s)) s++;
2615 if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2616
2617 for (;;)
2618 {
2619 while (isspace(*s)) s++;
2620 /* {-for-text-editors */
2621 if (*s == '}') break;
2622 if (*s != '{') /* }-for-text-editors */
2623 {
2624 expand_string_message = string_sprintf("each subcondition "
2625 "inside an \"%s{...}\" condition must be in its own {}", name);
2626 return NULL;
2627 }
2628
2629 s = eval_condition(s+1, subcondptr);
2630 if (s == NULL)
2631 {
2632 expand_string_message = string_sprintf("%s inside \"%s{...}\" condition",
2633 expand_string_message, name);
2634 return NULL;
2635 }
2636 while (isspace(*s)) s++;
2637
2638 /* {-for-text-editors */
2639 if (*s++ != '}')
2640 {
2641 /* {-for-text-editors */
2642 expand_string_message = string_sprintf("missing } at end of condition "
2643 "inside \"%s\" group", name);
2644 return NULL;
2645 }
2646
2647 if (yield != NULL)
2648 {
2649 if (cond_type == ECOND_AND)
2650 {
2651 combined_cond &= tempcond;
2652 if (!combined_cond) subcondptr = NULL; /* once false, don't */
2653 } /* evaluate any more */
2654 else
2655 {
2656 combined_cond |= tempcond;
2657 if (combined_cond) subcondptr = NULL; /* once true, don't */
2658 } /* evaluate any more */
2659 }
2660 }
2661
2662 if (yield != NULL) *yield = (combined_cond == testfor);
2663 return ++s;
2664
2665
2666 /* forall/forany: iterates a condition with different values */
2667
2668 case ECOND_FORALL:
2669 case ECOND_FORANY:
2670 {
2671 int sep = 0;
2672 uschar *save_iterate_item = iterate_item;
2673
2674 while (isspace(*s)) s++;
2675 if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2676 sub[0] = expand_string_internal(s, TRUE, &s, (yield == NULL), TRUE);
2677 if (sub[0] == NULL) return NULL;
2678 /* {-for-text-editors */
2679 if (*s++ != '}') goto COND_FAILED_CURLY_END;
2680
2681 while (isspace(*s)) s++;
2682 if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2683
2684 sub[1] = s;
2685
2686 /* Call eval_condition once, with result discarded (as if scanning a
2687 "false" part). This allows us to find the end of the condition, because if
2688 the list it empty, we won't actually evaluate the condition for real. */
2689
2690 s = eval_condition(sub[1], NULL);
2691 if (s == NULL)
2692 {
2693 expand_string_message = string_sprintf("%s inside \"%s\" condition",
2694 expand_string_message, name);
2695 return NULL;
2696 }
2697 while (isspace(*s)) s++;
2698
2699 /* {-for-text-editors */
2700 if (*s++ != '}')
2701 {
2702 /* {-for-text-editors */
2703 expand_string_message = string_sprintf("missing } at end of condition "
2704 "inside \"%s\"", name);
2705 return NULL;
2706 }
2707
2708 if (yield != NULL) *yield = !testfor;
2709 while ((iterate_item = string_nextinlist(&sub[0], &sep, NULL, 0)) != NULL)
2710 {
2711 DEBUG(D_expand) debug_printf("%s: $item = \"%s\"\n", name, iterate_item);
2712 if (eval_condition(sub[1], &tempcond) == NULL)
2713 {
2714 expand_string_message = string_sprintf("%s inside \"%s\" condition",
2715 expand_string_message, name);
2716 iterate_item = save_iterate_item;
2717 return NULL;
2718 }
2719 DEBUG(D_expand) debug_printf("%s: condition evaluated to %s\n", name,
2720 tempcond? "true":"false");
2721
2722 if (yield != NULL) *yield = (tempcond == testfor);
2723 if (tempcond == (cond_type == ECOND_FORANY)) break;
2724 }
2725
2726 iterate_item = save_iterate_item;
2727 return s;
2728 }
2729
2730
2731 /* The bool{} expansion condition maps a string to boolean.
2732 The values supported should match those supported by the ACL condition
2733 (acl.c, ACLC_CONDITION) so that we keep to a minimum the different ideas
2734 of true/false. Note that Router "condition" rules have a different
2735 interpretation, where general data can be used and only a few values
2736 map to FALSE.
2737 Note that readconf.c boolean matching, for boolean configuration options,
2738 only matches true/yes/false/no.
2739 The bool_lax{} condition matches the Router logic, which is much more
2740 liberal. */
2741 case ECOND_BOOL:
2742 case ECOND_BOOL_LAX:
2743 {
2744 uschar *sub_arg[1];
2745 uschar *t, *t2;
2746 uschar *ourname;
2747 size_t len;
2748 BOOL boolvalue = FALSE;
2749 while (isspace(*s)) s++;
2750 if (*s != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2751 ourname = cond_type == ECOND_BOOL_LAX ? US"bool_lax" : US"bool";
2752 switch(read_subs(sub_arg, 1, 1, &s, yield == NULL, FALSE, ourname))
2753 {
2754 case 1: expand_string_message = string_sprintf(
2755 "too few arguments or bracketing error for %s",
2756 ourname);
2757 /*FALLTHROUGH*/
2758 case 2:
2759 case 3: return NULL;
2760 }
2761 t = sub_arg[0];
2762 while (isspace(*t)) t++;
2763 len = Ustrlen(t);
2764 if (len)
2765 {
2766 /* trailing whitespace: seems like a good idea to ignore it too */
2767 t2 = t + len - 1;
2768 while (isspace(*t2)) t2--;
2769 if (t2 != (t + len))
2770 {
2771 *++t2 = '\0';
2772 len = t2 - t;
2773 }
2774 }
2775 DEBUG(D_expand)
2776 debug_printf("considering %s: %s\n", ourname, len ? t : US"<empty>");
2777 /* logic for the lax case from expand_check_condition(), which also does
2778 expands, and the logic is both short and stable enough that there should
2779 be no maintenance burden from replicating it. */
2780 if (len == 0)
2781 boolvalue = FALSE;
2782 else if (Ustrspn(t, "0123456789") == len)
2783 {
2784 boolvalue = (Uatoi(t) == 0) ? FALSE : TRUE;
2785 /* expand_check_condition only does a literal string "0" check */
2786 if ((cond_type == ECOND_BOOL_LAX) && (len > 1))
2787 boolvalue = TRUE;
2788 }
2789 else if (strcmpic(t, US"true") == 0 || strcmpic(t, US"yes") == 0)
2790 boolvalue = TRUE;
2791 else if (strcmpic(t, US"false") == 0 || strcmpic(t, US"no") == 0)
2792 boolvalue = FALSE;
2793 else if (cond_type == ECOND_BOOL_LAX)
2794 boolvalue = TRUE;
2795 else
2796 {
2797 expand_string_message = string_sprintf("unrecognised boolean "
2798 "value \"%s\"", t);
2799 return NULL;
2800 }
2801 if (yield != NULL) *yield = (boolvalue == testfor);
2802 return s;
2803 }
2804
2805 /* Unknown condition */
2806
2807 default:
2808 expand_string_message = string_sprintf("unknown condition \"%s\"", name);
2809 return NULL;
2810 } /* End switch on condition type */
2811
2812 /* Missing braces at start and end of data */
2813
2814 COND_FAILED_CURLY_START:
2815 expand_string_message = string_sprintf("missing { after \"%s\"", name);
2816 return NULL;
2817
2818 COND_FAILED_CURLY_END:
2819 expand_string_message = string_sprintf("missing } at end of \"%s\" condition",
2820 name);
2821 return NULL;
2822
2823 /* A condition requires code that is not compiled */
2824
2825 #if !defined(SUPPORT_PAM) || !defined(RADIUS_CONFIG_FILE) || \
2826 !defined(LOOKUP_LDAP) || !defined(CYRUS_PWCHECK_SOCKET) || \
2827 !defined(SUPPORT_CRYPTEQ) || !defined(CYRUS_SASLAUTHD_SOCKET)
2828 COND_FAILED_NOT_COMPILED:
2829 expand_string_message = string_sprintf("support for \"%s\" not compiled",
2830 name);
2831 return NULL;
2832 #endif
2833 }
2834
2835
2836
2837
2838 /*************************************************
2839 * Save numerical variables *
2840 *************************************************/
2841
2842 /* This function is called from items such as "if" that want to preserve and
2843 restore the numbered variables.
2844
2845 Arguments:
2846 save_expand_string points to an array of pointers to set
2847 save_expand_nlength points to an array of ints for the lengths
2848
2849 Returns: the value of expand max to save
2850 */
2851
2852 static int
2853 save_expand_strings(uschar **save_expand_nstring, int *save_expand_nlength)
2854 {
2855 int i;
2856 for (i = 0; i <= expand_nmax; i++)
2857 {
2858 save_expand_nstring[i] = expand_nstring[i];
2859 save_expand_nlength[i] = expand_nlength[i];
2860 }
2861 return expand_nmax;
2862 }
2863
2864
2865
2866 /*************************************************
2867 * Restore numerical variables *
2868 *************************************************/
2869
2870 /* This function restored saved values of numerical strings.
2871
2872 Arguments:
2873 save_expand_nmax the number of strings to restore
2874 save_expand_string points to an array of pointers
2875 save_expand_nlength points to an array of ints
2876
2877 Returns: nothing
2878 */
2879
2880 static void
2881 restore_expand_strings(int save_expand_nmax, uschar **save_expand_nstring,
2882 int *save_expand_nlength)
2883 {
2884 int i;
2885 expand_nmax = save_expand_nmax;
2886 for (i = 0; i <= expand_nmax; i++)
2887 {
2888 expand_nstring[i] = save_expand_nstring[i];
2889 expand_nlength[i] = save_expand_nlength[i];
2890 }
2891 }
2892
2893
2894
2895
2896
2897 /*************************************************
2898 * Handle yes/no substrings *
2899 *************************************************/
2900
2901 /* This function is used by ${if}, ${lookup} and ${extract} to handle the
2902 alternative substrings that depend on whether or not the condition was true,
2903 or the lookup or extraction succeeded. The substrings always have to be
2904 expanded, to check their syntax, but "skipping" is set when the result is not
2905 needed - this avoids unnecessary nested lookups.
2906
2907 Arguments:
2908 skipping TRUE if we were skipping when this item was reached
2909 yes TRUE if the first string is to be used, else use the second
2910 save_lookup a value to put back into lookup_value before the 2nd expansion
2911 sptr points to the input string pointer
2912 yieldptr points to the output string pointer
2913 sizeptr points to the output string size
2914 ptrptr points to the output string pointer
2915 type "lookup" or "if" or "extract" or "run", for error message
2916
2917 Returns: 0 OK; lookup_value has been reset to save_lookup
2918 1 expansion failed
2919 2 expansion failed because of bracketing error
2920 */
2921
2922 static int
2923 process_yesno(BOOL skipping, BOOL yes, uschar *save_lookup, uschar **sptr,
2924 uschar **yieldptr, int *sizeptr, int *ptrptr, uschar *type)
2925 {
2926 int rc = 0;
2927 uschar *s = *sptr; /* Local value */
2928 uschar *sub1, *sub2;
2929
2930 /* If there are no following strings, we substitute the contents of $value for
2931 lookups and for extractions in the success case. For the ${if item, the string
2932 "true" is substituted. In the fail case, nothing is substituted for all three
2933 items. */
2934
2935 while (isspace(*s)) s++;
2936 if (*s == '}')
2937 {
2938 if (type[0] == 'i')
2939 {
2940 if (yes) *yieldptr = string_cat(*yieldptr, sizeptr, ptrptr, US"true", 4);
2941 }
2942 else
2943 {
2944 if (yes && lookup_value != NULL)
2945 *yieldptr = string_cat(*yieldptr, sizeptr, ptrptr, lookup_value,
2946 Ustrlen(lookup_value));
2947 lookup_value = save_lookup;
2948 }
2949 s++;
2950 goto RETURN;
2951 }
2952
2953 /* The first following string must be braced. */
2954
2955 if (*s++ != '{') goto FAILED_CURLY;
2956
2957 /* Expand the first substring. Forced failures are noticed only if we actually
2958 want this string. Set skipping in the call in the fail case (this will always
2959 be the case if we were already skipping). */
2960
2961 sub1 = expand_string_internal(s, TRUE, &s, !yes, TRUE);
2962 if (sub1 == NULL && (yes || !expand_string_forcedfail)) goto FAILED;
2963 expand_string_forcedfail = FALSE;
2964 if (*s++ != '}') goto FAILED_CURLY;
2965
2966 /* If we want the first string, add it to the output */
2967
2968 if (yes)
2969 *yieldptr = string_cat(*yieldptr, sizeptr, ptrptr, sub1, Ustrlen(sub1));
2970
2971 /* If this is called from a lookup or an extract, we want to restore $value to
2972 what it was at the start of the item, so that it has this value during the
2973 second string expansion. For the call from "if" or "run" to this function,
2974 save_lookup is set to lookup_value, so that this statement does nothing. */
2975
2976 lookup_value = save_lookup;
2977
2978 /* There now follows either another substring, or "fail", or nothing. This
2979 time, forced failures are noticed only if we want the second string. We must
2980 set skipping in the nested call if we don't want this string, or if we were
2981 already skipping. */
2982
2983 while (isspace(*s)) s++;
2984 if (*s == '{')
2985 {
2986 sub2 = expand_string_internal(s+1, TRUE, &s, yes || skipping, TRUE);
2987 if (sub2 == NULL && (!yes || !expand_string_forcedfail)) goto FAILED;
2988 expand_string_forcedfail = FALSE;
2989 if (*s++ != '}') goto FAILED_CURLY;
2990
2991 /* If we want the second string, add it to the output */
2992
2993 if (!yes)
2994 *yieldptr = string_cat(*yieldptr, sizeptr, ptrptr, sub2, Ustrlen(sub2));
2995 }
2996
2997 /* If there is no second string, but the word "fail" is present when the use of
2998 the second string is wanted, set a flag indicating it was a forced failure
2999 rather than a syntactic error. Swallow the terminating } in case this is nested
3000 inside another lookup or if or extract. */
3001
3002 else if (*s != '}')
3003 {
3004 uschar name[256];
3005 s = read_name(name, sizeof(name), s, US"_");
3006 if (Ustrcmp(name, "fail") == 0)
3007 {
3008 if (!yes && !skipping)
3009 {
3010 while (isspace(*s)) s++;
3011 if (*s++ != '}') goto FAILED_CURLY;
3012 expand_string_message =
3013 string_sprintf("\"%s\" failed and \"fail\" requested", type);
3014 expand_string_forcedfail = TRUE;
3015 goto FAILED;
3016 }
3017 }
3018 else
3019 {
3020 expand_string_message =
3021 string_sprintf("syntax error in \"%s\" item - \"fail\" expected", type);
3022 goto FAILED;
3023 }
3024 }
3025
3026 /* All we have to do now is to check on the final closing brace. */
3027
3028 while (isspace(*s)) s++;
3029 if (*s++ == '}') goto RETURN;
3030
3031 /* Get here if there is a bracketing failure */
3032
3033 FAILED_CURLY:
3034 rc++;
3035
3036 /* Get here for other failures */
3037
3038 FAILED:
3039 rc++;
3040
3041 /* Update the input pointer value before returning */
3042
3043 RETURN:
3044 *sptr = s;
3045 return rc;
3046 }
3047
3048
3049
3050
3051 /*************************************************
3052 * Handle MD5 or SHA-1 computation for HMAC *
3053 *************************************************/
3054
3055 /* These are some wrapping functions that enable the HMAC code to be a bit
3056 cleaner. A good compiler will spot the tail recursion.
3057
3058 Arguments:
3059 type HMAC_MD5 or HMAC_SHA1
3060 remaining are as for the cryptographic hash functions
3061
3062 Returns: nothing
3063 */
3064
3065 static void
3066 chash_start(int type, void *base)
3067 {
3068 if (type == HMAC_MD5)
3069 md5_start((md5 *)base);
3070 else
3071 sha1_start((sha1 *)base);
3072 }
3073
3074 static void
3075 chash_mid(int type, void *base, uschar *string)
3076 {
3077 if (type == HMAC_MD5)
3078 md5_mid((md5 *)base, string);
3079 else
3080 sha1_mid((sha1 *)base, string);
3081 }
3082
3083 static void
3084 chash_end(int type, void *base, uschar *string, int length, uschar *digest)
3085 {
3086 if (type == HMAC_MD5)
3087 md5_end((md5 *)base, string, length, digest);
3088 else
3089 sha1_end((sha1 *)base, string, length, digest);
3090 }
3091
3092
3093
3094
3095
3096 /********************************************************
3097 * prvs: Get last three digits of days since Jan 1, 1970 *
3098 ********************************************************/
3099
3100 /* This is needed to implement the "prvs" BATV reverse
3101 path signing scheme
3102
3103 Argument: integer "days" offset to add or substract to
3104 or from the current number of days.
3105
3106 Returns: pointer to string containing the last three
3107 digits of the number of days since Jan 1, 1970,
3108 modified by the offset argument, NULL if there
3109 was an error in the conversion.
3110
3111 */
3112
3113 static uschar *
3114 prvs_daystamp(int day_offset)
3115 {
3116 uschar *days = store_get(32); /* Need at least 24 for cases */
3117 (void)string_format(days, 32, TIME_T_FMT, /* where TIME_T_FMT is %lld */
3118 (time(NULL) + day_offset*86400)/86400);
3119 return (Ustrlen(days) >= 3) ? &days[Ustrlen(days)-3] : US"100";
3120 }
3121
3122
3123
3124 /********************************************************
3125 * prvs: perform HMAC-SHA1 computation of prvs bits *
3126 ********************************************************/
3127
3128 /* This is needed to implement the "prvs" BATV reverse
3129 path signing scheme
3130
3131 Arguments:
3132 address RFC2821 Address to use
3133 key The key to use (must be less than 64 characters
3134 in size)
3135 key_num Single-digit key number to use. Defaults to
3136 '0' when NULL.
3137
3138 Returns: pointer to string containing the first three
3139 bytes of the final hash in hex format, NULL if
3140 there was an error in the process.
3141 */
3142
3143 static uschar *
3144 prvs_hmac_sha1(uschar *address, uschar *key, uschar *key_num, uschar *daystamp)
3145 {
3146 uschar *hash_source, *p;
3147 int size = 0,offset = 0,i;
3148 sha1 sha1_base;
3149 void *use_base = &sha1_base;
3150 uschar innerhash[20];
3151 uschar finalhash[20];
3152 uschar innerkey[64];
3153 uschar outerkey[64];
3154 uschar *finalhash_hex = store_get(40);
3155
3156 if (key_num == NULL)
3157 key_num = US"0";
3158
3159 if (Ustrlen(key) > 64)
3160 return NULL;
3161
3162 hash_source = string_cat(NULL,&size,&offset,key_num,1);
3163 string_cat(hash_source,&size,&offset,daystamp,3);
3164 string_cat(hash_source,&size,&offset,address,Ustrlen(address));
3165 hash_source[offset] = '\0';
3166
3167 DEBUG(D_expand) debug_printf("prvs: hash source is '%s'\n", hash_source);
3168
3169 memset(innerkey, 0x36, 64);
3170 memset(outerkey, 0x5c, 64);
3171
3172 for (i = 0; i < Ustrlen(key); i++)
3173 {
3174 innerkey[i] ^= key[i];
3175 outerkey[i] ^= key[i];
3176 }
3177
3178 chash_start(HMAC_SHA1, use_base);
3179 chash_mid(HMAC_SHA1, use_base, innerkey);
3180 chash_end(HMAC_SHA1, use_base, hash_source, offset, innerhash);
3181
3182 chash_start(HMAC_SHA1, use_base);
3183 chash_mid(HMAC_SHA1, use_base, outerkey);
3184 chash_end(HMAC_SHA1, use_base, innerhash, 20, finalhash);
3185
3186 p = finalhash_hex;
3187 for (i = 0; i < 3; i++)
3188 {
3189 *p++ = hex_digits[(finalhash[i] & 0xf0) >> 4];
3190 *p++ = hex_digits[finalhash[i] & 0x0f];
3191 }
3192 *p = '\0';
3193
3194 return finalhash_hex;
3195 }
3196
3197
3198
3199
3200 /*************************************************
3201 * Join a file onto the output string *
3202 *************************************************/
3203
3204 /* This is used for readfile and after a run expansion. It joins the contents
3205 of a file onto the output string, globally replacing newlines with a given
3206 string (optionally). The file is closed at the end.
3207
3208 Arguments:
3209 f the FILE
3210 yield pointer to the expandable string
3211 sizep pointer to the current size
3212 ptrp pointer to the current position
3213 eol newline replacement string, or NULL
3214
3215 Returns: new value of string pointer
3216 */
3217
3218 static uschar *
3219 cat_file(FILE *f, uschar *yield, int *sizep, int *ptrp, uschar *eol)
3220 {
3221 int eollen;
3222 uschar buffer[1024];
3223
3224 eollen = (eol == NULL)? 0 : Ustrlen(eol);
3225
3226 while (Ufgets(buffer, sizeof(buffer), f) != NULL)
3227 {
3228 int len = Ustrlen(buffer);
3229 if (eol != NULL && buffer[len-1] == '\n') len--;
3230 yield = string_cat(yield, sizep, ptrp, buffer, len);
3231 if (buffer[len] != 0)
3232 yield = string_cat(yield, sizep, ptrp, eol, eollen);
3233 }
3234
3235 if (yield != NULL) yield[*ptrp] = 0;
3236
3237 return yield;
3238 }
3239
3240
3241
3242
3243 /*************************************************
3244 * Evaluate numeric expression *
3245 *************************************************/
3246
3247 /* This is a set of mutually recursive functions that evaluate an arithmetic
3248 expression involving + - * / % & | ^ ~ << >> and parentheses. The only one of
3249 these functions that is called from elsewhere is eval_expr, whose interface is:
3250
3251 Arguments:
3252 sptr pointer to the pointer to the string - gets updated
3253 decimal TRUE if numbers are to be assumed decimal
3254 error pointer to where to put an error message - must be NULL on input
3255 endket TRUE if ')' must terminate - FALSE for external call
3256
3257 Returns: on success: the value of the expression, with *error still NULL
3258 on failure: an undefined value, with *error = a message
3259 */
3260
3261 static int_eximarith_t eval_op_or(uschar **, BOOL, uschar **);
3262
3263
3264 static int_eximarith_t
3265 eval_expr(uschar **sptr, BOOL decimal, uschar **error, BOOL endket)
3266 {
3267 uschar *s = *sptr;
3268 int_eximarith_t x = eval_op_or(&s, decimal, error);
3269 if (*error == NULL)
3270 {
3271 if (endket)
3272 {
3273 if (*s != ')')
3274 *error = US"expecting closing parenthesis";
3275 else
3276 while (isspace(*(++s)));
3277 }
3278 else if (*s != 0) *error = US"expecting operator";
3279 }
3280 *sptr = s;
3281 return x;
3282 }
3283
3284
3285 static int_eximarith_t
3286 eval_number(uschar **sptr, BOOL decimal, uschar **error)
3287 {
3288 register int c;
3289 int_eximarith_t n;
3290 uschar *s = *sptr;
3291 while (isspace(*s)) s++;
3292 c = *s;
3293 if (isdigit(c))
3294 {
3295 int count;
3296 (void)sscanf(CS s, (decimal? SC_EXIM_DEC "%n" : SC_EXIM_ARITH "%n"), &n, &count);
3297 s += count;
3298 switch (tolower(*s))
3299 {
3300 default: break;
3301 case 'k': n *= 1024; s++; break;
3302 case 'm': n *= 1024*1024; s++; break;
3303 case 'g': n *= 1024*1024*1024; s++; break;
3304 }
3305 while (isspace (*s)) s++;
3306 }
3307 else if (c == '(')
3308 {
3309 s++;
3310 n = eval_expr(&s, decimal, error, 1);
3311 }
3312 else
3313 {
3314 *error = US"expecting number or opening parenthesis";
3315 n = 0;
3316 }
3317 *sptr = s;
3318 return n;
3319 }
3320
3321
3322 static int_eximarith_t
3323 eval_op_unary(uschar **sptr, BOOL decimal, uschar **error)
3324 {
3325 uschar *s = *sptr;
3326 int_eximarith_t x;
3327 while (isspace(*s)) s++;
3328 if (*s == '+' || *s == '-' || *s == '~')
3329 {
3330 int op = *s++;
3331 x = eval_op_unary(&s, decimal, error);
3332 if (op == '-') x = -x;
3333 else if (op == '~') x = ~x;
3334 }
3335 else
3336 {
3337 x = eval_number(&s, decimal, error);
3338 }
3339 *sptr = s;
3340 return x;
3341 }
3342
3343
3344 static int_eximarith_t
3345 eval_op_mult(uschar **sptr, BOOL decimal, uschar **error)
3346 {
3347 uschar *s = *sptr;
3348 int_eximarith_t x = eval_op_unary(&s, decimal, error);
3349 if (*error == NULL)
3350 {
3351 while (*s == '*' || *s == '/' || *s == '%')
3352 {
3353 int op = *s++;
3354 int_eximarith_t y = eval_op_unary(&s, decimal, error);
3355 if (*error != NULL) break;
3356 /* SIGFPE both on div/mod by zero and on INT_MIN / -1, which would give
3357 * a value of INT_MAX+1. Note that INT_MIN * -1 gives INT_MIN for me, which
3358 * is a bug somewhere in [gcc 4.2.1, FreeBSD, amd64]. In fact, -N*-M where
3359 * -N*M is INT_MIN will yielf INT_MIN.
3360 * Since we don't support floating point, this is somewhat simpler.
3361 * Ideally, we'd return an error, but since we overflow for all other
3362 * arithmetic, consistency suggests otherwise, but what's the correct value
3363 * to use? There is none.
3364 * The C standard guarantees overflow for unsigned arithmetic but signed
3365 * overflow invokes undefined behaviour; in practice, this is overflow
3366 * except for converting INT_MIN to INT_MAX+1. We also can't guarantee
3367 * that long/longlong larger than int are available, or we could just work
3368 * with larger types. We should consider whether to guarantee 32bit eval
3369 * and 64-bit working variables, with errors returned. For now ...
3370 * So, the only SIGFPEs occur with a non-shrinking div/mod, thus -1; we
3371 * can just let the other invalid results occur otherwise, as they have
3372 * until now. For this one case, we can coerce.
3373 */
3374 if (y == -1 && x == LLONG_MIN && op != '*')
3375 {
3376 DEBUG(D_expand)
3377 debug_printf("Integer exception dodging: " PR_EXIM_ARITH "%c-1 coerced to " PR_EXIM_ARITH "\n",
3378 LLONG_MIN, op, LLONG_MAX);
3379 x = LLONG_MAX;
3380 continue;
3381 }
3382 if (op == '*')
3383 x *= y;
3384 else
3385 {
3386 if (y == 0)
3387 {
3388 *error = (op == '/') ? US"divide by zero" : US"modulo by zero";
3389 x = 0;
3390 break;
3391 }
3392 if (op == '/')
3393 x /= y;
3394 else
3395 x %= y;
3396 }
3397 }
3398 }
3399 *sptr = s;
3400 return x;
3401 }
3402
3403
3404 static int_eximarith_t
3405 eval_op_sum(uschar **sptr, BOOL decimal, uschar **error)
3406 {
3407 uschar *s = *sptr;
3408 int_eximarith_t x = eval_op_mult(&s, decimal, error);
3409 if (*error == NULL)
3410 {
3411 while (*s == '+' || *s == '-')
3412 {
3413 int op = *s++;
3414 int_eximarith_t y = eval_op_mult(&s, decimal, error);
3415 if (*error != NULL) break;
3416 if (op == '+') x += y; else x -= y;
3417 }
3418 }
3419 *sptr = s;
3420 return x;
3421 }
3422
3423
3424 static int_eximarith_t
3425 eval_op_shift(uschar **sptr, BOOL decimal, uschar **error)
3426 {
3427 uschar *s = *sptr;
3428 int_eximarith_t x = eval_op_sum(&s, decimal, error);
3429 if (*error == NULL)
3430 {
3431 while ((*s == '<' || *s == '>') && s[1] == s[0])
3432 {
3433 int_eximarith_t y;
3434 int op = *s++;
3435 s++;
3436 y = eval_op_sum(&s, decimal, error);
3437 if (*error != NULL) break;
3438 if (op == '<') x <<= y; else x >>= y;
3439 }
3440 }
3441 *sptr = s;
3442 return x;
3443 }
3444
3445
3446 static int_eximarith_t
3447 eval_op_and(uschar **sptr, BOOL decimal, uschar **error)
3448 {
3449 uschar *s = *sptr;
3450 int_eximarith_t x = eval_op_shift(&s, decimal, error);
3451 if (*error == NULL)
3452 {
3453 while (*s == '&')
3454 {
3455 int_eximarith_t y;
3456 s++;
3457 y = eval_op_shift(&s, decimal, error);
3458 if (*error != NULL) break;
3459 x &= y;
3460 }
3461 }
3462 *sptr = s;
3463 return x;
3464 }
3465
3466
3467 static int_eximarith_t
3468 eval_op_xor(uschar **sptr, BOOL decimal, uschar **error)
3469 {
3470 uschar *s = *sptr;
3471 int_eximarith_t x = eval_op_and(&s, decimal, error);
3472 if (*error == NULL)
3473 {
3474 while (*s == '^')
3475 {
3476 int_eximarith_t y;
3477 s++;
3478 y = eval_op_and(&s, decimal, error);
3479 if (*error != NULL) break;
3480 x ^= y;
3481 }
3482 }
3483 *sptr = s;
3484 return x;
3485 }
3486
3487
3488 static int_eximarith_t
3489 eval_op_or(uschar **sptr, BOOL decimal, uschar **error)
3490 {
3491 uschar *s = *sptr;
3492 int_eximarith_t x = eval_op_xor(&s, decimal, error);
3493 if (*error == NULL)
3494 {
3495 while (*s == '|')
3496 {
3497 int_eximarith_t y;
3498 s++;
3499 y = eval_op_xor(&s, decimal, error);
3500 if (*error != NULL) break;
3501 x |= y;
3502 }
3503 }
3504 *sptr = s;
3505 return x;
3506 }
3507
3508
3509
3510 /*************************************************
3511 * Expand string *
3512 *************************************************/
3513
3514 /* Returns either an unchanged string, or the expanded string in stacking pool
3515 store. Interpreted sequences are:
3516
3517 \... normal escaping rules
3518 $name substitutes the variable
3519 ${name} ditto
3520 ${op:string} operates on the expanded string value
3521 ${item{arg1}{arg2}...} expands the args and then does the business
3522 some literal args are not enclosed in {}
3523
3524 There are now far too many operators and item types to make it worth listing
3525 them here in detail any more.
3526
3527 We use an internal routine recursively to handle embedded substrings. The
3528 external function follows. The yield is NULL if the expansion failed, and there
3529 are two cases: if something collapsed syntactically, or if "fail" was given
3530 as the action on a lookup failure. These can be distinguised by looking at the
3531 variable expand_string_forcedfail, which is TRUE in the latter case.
3532
3533 The skipping flag is set true when expanding a substring that isn't actually
3534 going to be used (after "if" or "lookup") and it prevents lookups from
3535 happening lower down.
3536
3537 Store usage: At start, a store block of the length of the input plus 64
3538 is obtained. This is expanded as necessary by string_cat(), which might have to
3539 get a new block, or might be able to expand the original. At the end of the
3540 function we can release any store above that portion of the yield block that
3541 was actually used. In many cases this will be optimal.
3542
3543 However: if the first item in the expansion is a variable name or header name,
3544 we reset the store before processing it; if the result is in fresh store, we
3545 use that without copying. This is helpful for expanding strings like
3546 $message_headers which can get very long.
3547
3548 There's a problem if a ${dlfunc item has side-effects that cause allocation,
3549 since resetting the store at the end of the expansion will free store that was
3550 allocated by the plugin code as well as the slop after the expanded string. So
3551 we skip any resets if ${dlfunc has been used. This is an unfortunate
3552 consequence of string expansion becoming too powerful.
3553
3554 Arguments:
3555 string the string to be expanded
3556 ket_ends true if expansion is to stop at }
3557 left if not NULL, a pointer to the first character after the
3558 expansion is placed here (typically used with ket_ends)
3559 skipping TRUE for recursive calls when the value isn't actually going
3560 to be used (to allow for optimisation)
3561 honour_dollar TRUE if $ is to be expanded,
3562 FALSE if it's just another character
3563
3564 Returns: NULL if expansion fails:
3565 expand_string_forcedfail is set TRUE if failure was forced
3566 expand_string_message contains a textual error message
3567 a pointer to the expanded string on success
3568 */
3569
3570 static uschar *
3571 expand_string_internal(uschar *string, BOOL ket_ends, uschar **left,
3572 BOOL skipping, BOOL honour_dollar)
3573 {
3574 int ptr = 0;
3575 int size = Ustrlen(string)+ 64;
3576 int item_type;
3577 uschar *yield = store_get(size);
3578 uschar *s = string;
3579 uschar *save_expand_nstring[EXPAND_MAXN+1];
3580 int save_expand_nlength[EXPAND_MAXN+1];
3581 BOOL resetok = TRUE;
3582
3583 expand_string_forcedfail = FALSE;
3584 expand_string_message = US"";
3585
3586 while (*s != 0)
3587 {
3588 uschar *value;
3589 uschar name[256];
3590
3591 /* \ escapes the next character, which must exist, or else
3592 the expansion fails. There's a special escape, \N, which causes
3593 copying of the subject verbatim up to the next \N. Otherwise,
3594 the escapes are the standard set. */
3595
3596 if (*s == '\\')
3597 {
3598 if (s[1] == 0)
3599 {
3600 expand_string_message = US"\\ at end of string";
3601 goto EXPAND_FAILED;
3602 }
3603
3604 if (s[1] == 'N')
3605 {
3606 uschar *t = s + 2;
3607 for (s = t; *s != 0; s++) if (*s == '\\' && s[1] == 'N') break;
3608 yield = string_cat(yield, &size, &ptr, t, s - t);
3609 if (*s != 0) s += 2;
3610 }
3611
3612 else
3613 {
3614 uschar ch[1];
3615 ch[0] = string_interpret_escape(&s);
3616 s++;
3617 yield = string_cat(yield, &size, &ptr, ch, 1);
3618 }
3619
3620 continue;
3621 }
3622
3623 /* Anything other than $ is just copied verbatim, unless we are
3624 looking for a terminating } character. */
3625
3626 if (ket_ends && *s == '}') break;
3627
3628 if (*s != '$' || !honour_dollar)
3629 {
3630 yield = string_cat(yield, &size, &ptr, s++, 1);
3631 continue;
3632 }
3633
3634 /* No { after the $ - must be a plain name or a number for string
3635 match variable. There has to be a fudge for variables that are the
3636 names of header fields preceded by "$header_" because header field
3637 names can contain any printing characters except space and colon.
3638 For those that don't like typing this much, "$h_" is a synonym for
3639 "$header_". A non-existent header yields a NULL value; nothing is
3640 inserted. */
3641
3642 if (isalpha((*(++s))))
3643 {
3644 int len;
3645 int newsize = 0;
3646
3647 s = read_name(name, sizeof(name), s, US"_");
3648
3649 /* If this is the first thing to be expanded, release the pre-allocated
3650 buffer. */
3651
3652 if (ptr == 0 && yield != NULL)
3653 {
3654 if (resetok) store_reset(yield);
3655 yield = NULL;
3656 size = 0;
3657 }
3658
3659 /* Header */
3660
3661 if (Ustrncmp(name, "h_", 2) == 0 ||
3662 Ustrncmp(name, "rh_", 3) == 0 ||
3663 Ustrncmp(name, "bh_", 3) == 0 ||
3664 Ustrncmp(name, "header_", 7) == 0 ||
3665 Ustrncmp(name, "rheader_", 8) == 0 ||
3666 Ustrncmp(name, "bheader_", 8) == 0)
3667 {
3668 BOOL want_raw = (name[0] == 'r')? TRUE : FALSE;
3669 uschar *charset = (name[0] == 'b')? NULL : headers_charset;
3670 s = read_header_name(name, sizeof(name), s);
3671 value = find_header(name, FALSE, &newsize, want_raw, charset);
3672
3673 /* If we didn't find the header, and the header contains a closing brace
3674 character, this may be a user error where the terminating colon
3675 has been omitted. Set a flag to adjust the error message in this case.
3676 But there is no error here - nothing gets inserted. */
3677
3678 if (value == NULL)
3679 {
3680 if (Ustrchr(name, '}') != NULL) malformed_header = TRUE;
3681 continue;
3682 }
3683 }
3684
3685 /* Variable */
3686
3687 else
3688 {
3689 value = find_variable(name, FALSE, skipping, &newsize);
3690 if (value == NULL)
3691 {
3692 expand_string_message =
3693 string_sprintf("unknown variable name \"%s\"", name);
3694 check_variable_error_message(name);
3695 goto EXPAND_FAILED;
3696 }
3697 }
3698
3699 /* If the data is known to be in a new buffer, newsize will be set to the
3700 size of that buffer. If this is the first thing in an expansion string,
3701 yield will be NULL; just point it at the new store instead of copying. Many
3702 expansion strings contain just one reference, so this is a useful
3703 optimization, especially for humungous headers. */
3704
3705 len = Ustrlen(value);
3706 if (yield == NULL && newsize != 0)
3707 {
3708 yield = value;
3709 size = newsize;
3710 ptr = len;
3711 }
3712 else yield = string_cat(yield, &size, &ptr, value, len);
3713
3714 continue;
3715 }
3716
3717 if (isdigit(*s))
3718 {
3719 int n;
3720 s = read_number(&n, s);
3721 if (n >= 0 && n <= expand_nmax)
3722 yield = string_cat(yield, &size, &ptr, expand_nstring[n],
3723 expand_nlength[n]);
3724 continue;
3725 }
3726
3727 /* Otherwise, if there's no '{' after $ it's an error. */
3728
3729 if (*s != '{')
3730 {
3731 expand_string_message = US"$ not followed by letter, digit, or {";
3732 goto EXPAND_FAILED;
3733 }
3734
3735 /* After { there can be various things, but they all start with
3736 an initial word, except for a number for a string match variable. */
3737
3738 if (isdigit((*(++s))))
3739 {
3740 int n;
3741 s = read_number(&n, s);
3742 if (*s++ != '}')
3743 {
3744 expand_string_message = US"} expected after number";
3745 goto EXPAND_FAILED;
3746 }
3747 if (n >= 0 && n <= expand_nmax)
3748 yield = string_cat(yield, &size, &ptr, expand_nstring[n],
3749 expand_nlength[n]);
3750 continue;
3751 }
3752
3753 if (!isalpha(*s))
3754 {
3755 expand_string_message = US"letter or digit expected after ${";
3756 goto EXPAND_FAILED;
3757 }
3758
3759 /* Allow "-" in names to cater for substrings with negative
3760 arguments. Since we are checking for known names after { this is
3761 OK. */
3762
3763 s = read_name(name, sizeof(name), s, US"_-");
3764 item_type = chop_match(name, item_table, sizeof(item_table)/sizeof(uschar *));
3765
3766 switch(item_type)
3767 {
3768 /* Call an ACL from an expansion. We feed data in via $acl_arg1 - $acl_arg9.
3769 If the ACL returns accept or reject we return content set by "message ="
3770 There is currently no limit on recursion; this would have us call
3771 acl_check_internal() directly and get a current level from somewhere.
3772 See also the acl expansion condition ECOND_ACL and the traditional
3773 acl modifier ACLC_ACL.
3774 */
3775
3776 case EITEM_ACL:
3777 /* ${acl {name} {arg1}{arg2}...} */
3778 {
3779 uschar *sub[10]; /* name + arg1-arg9 (which must match number of acl_arg[]) */
3780 uschar *user_msg;
3781
3782 switch(read_subs(sub, 10, 1, &s, skipping, TRUE, US"acl"))
3783 {
3784 case 1: goto EXPAND_FAILED_CURLY;
3785 case 2:
3786 case 3: goto EXPAND_FAILED;
3787 }
3788 if (skipping) continue;
3789
3790 switch(eval_acl(sub, sizeof(sub)/sizeof(*sub), &user_msg))
3791 {
3792 case OK:
3793 case FAIL:
3794 if (user_msg)
3795 yield = string_cat(yield, &size, &ptr, user_msg, Ustrlen(user_msg));
3796 continue;
3797
3798 case DEFER:
3799 expand_string_forcedfail = TRUE;
3800 default:
3801 expand_string_message = string_sprintf("error from acl \"%s\"", sub[0]);
3802 goto EXPAND_FAILED;
3803 }
3804 }
3805
3806 /* Handle conditionals - preserve the values of the numerical expansion
3807 variables in case they get changed by a regular expression match in the
3808 condition. If not, they retain their external settings. At the end
3809 of this "if" section, they get restored to their previous values. */
3810
3811 case EITEM_IF:
3812 {
3813 BOOL cond = FALSE;
3814 uschar *next_s;
3815 int save_expand_nmax =
3816 save_expand_strings(save_expand_nstring, save_expand_nlength);
3817
3818 while (isspace(*s)) s++;
3819 next_s = eval_condition(s, skipping? NULL : &cond);
3820 if (next_s == NULL) goto EXPAND_FAILED; /* message already set */
3821
3822 DEBUG(D_expand)
3823 debug_printf("condition: %.*s\n result: %s\n", (int)(next_s - s), s,
3824 cond? "true" : "false");
3825
3826 s = next_s;
3827
3828 /* The handling of "yes" and "no" result strings is now in a separate
3829 function that is also used by ${lookup} and ${extract} and ${run}. */
3830
3831 switch(process_yesno(
3832 skipping, /* were previously skipping */
3833 cond, /* success/failure indicator */
3834 lookup_value, /* value to reset for string2 */
3835 &s, /* input pointer */
3836 &yield, /* output pointer */
3837 &size, /* output size */
3838 &ptr, /* output current point */
3839 US"if")) /* condition type */
3840 {
3841 case 1: goto EXPAND_FAILED; /* when all is well, the */
3842 case 2: goto EXPAND_FAILED_CURLY; /* returned value is 0 */
3843 }
3844
3845 /* Restore external setting of expansion variables for continuation
3846 at this level. */
3847
3848 restore_expand_strings(save_expand_nmax, save_expand_nstring,
3849 save_expand_nlength);
3850 continue;
3851 }
3852
3853 /* Handle database lookups unless locked out. If "skipping" is TRUE, we are
3854 expanding an internal string that isn't actually going to be used. All we
3855 need to do is check the syntax, so don't do a lookup at all. Preserve the
3856 values of the numerical expansion variables in case they get changed by a
3857 partial lookup. If not, they retain their external settings. At the end
3858 of this "lookup" section, they get restored to their previous values. */
3859
3860 case EITEM_LOOKUP:
3861 {
3862 int stype, partial, affixlen, starflags;
3863 int expand_setup = 0;
3864 int nameptr = 0;
3865 uschar *key, *filename, *affix;
3866 uschar *save_lookup_value = lookup_value;
3867 int save_expand_nmax =
3868 save_expand_strings(save_expand_nstring, save_expand_nlength);
3869
3870 if ((expand_forbid & RDO_LOOKUP) != 0)
3871 {
3872 expand_string_message = US"lookup expansions are not permitted";
3873 goto EXPAND_FAILED;
3874 }
3875
3876 /* Get the key we are to look up for single-key+file style lookups.
3877 Otherwise set the key NULL pro-tem. */
3878
3879 while (isspace(*s)) s++;
3880 if (*s == '{')
3881 {
3882 key = expand_string_internal(s+1, TRUE, &s, skipping, TRUE);
3883 if (key == NULL) goto EXPAND_FAILED;
3884 if (*s++ != '}') goto EXPAND_FAILED_CURLY;
3885 while (isspace(*s)) s++;
3886 }
3887 else key = NULL;
3888
3889 /* Find out the type of database */
3890
3891 if (!isalpha(*s))
3892 {
3893 expand_string_message = US"missing lookup type";
3894 goto EXPAND_FAILED;
3895 }
3896
3897 /* The type is a string that may contain special characters of various
3898 kinds. Allow everything except space or { to appear; the actual content
3899 is checked by search_findtype_partial. */
3900
3901 while (*s != 0 && *s != '{' && !isspace(*s))
3902 {
3903 if (nameptr < sizeof(name) - 1) name[nameptr++] = *s;
3904 s++;
3905 }
3906 name[nameptr] = 0;
3907 while (isspace(*s)) s++;
3908
3909 /* Now check for the individual search type and any partial or default
3910 options. Only those types that are actually in the binary are valid. */
3911
3912 stype = search_findtype_partial(name, &partial, &affix, &affixlen,
3913 &starflags);
3914 if (stype < 0)
3915 {
3916 expand_string_message = search_error_message;
3917 goto EXPAND_FAILED;
3918 }
3919
3920 /* Check that a key was provided for those lookup types that need it,
3921 and was not supplied for those that use the query style. */
3922
3923 if (!mac_islookup(stype, lookup_querystyle|lookup_absfilequery))
3924 {
3925 if (key == NULL)
3926 {
3927 expand_string_message = string_sprintf("missing {key} for single-"
3928 "key \"%s\" lookup", name);
3929 goto EXPAND_FAILED;
3930 }
3931 }
3932 else
3933 {
3934 if (key != NULL)
3935 {
3936 expand_string_message = string_sprintf("a single key was given for "
3937 "lookup type \"%s\", which is not a single-key lookup type", name);
3938 goto EXPAND_FAILED;
3939 }
3940 }
3941
3942 /* Get the next string in brackets and expand it. It is the file name for
3943 single-key+file lookups, and the whole query otherwise. In the case of
3944 queries that also require a file name (e.g. sqlite), the file name comes
3945 first. */
3946
3947 if (*s != '{') goto EXPAND_FAILED_CURLY;
3948 filename = expand_string_internal(s+1, TRUE, &s, skipping, TRUE);
3949 if (filename == NULL) goto EXPAND_FAILED;
3950 if (*s++ != '}') goto EXPAND_FAILED_CURLY;
3951 while (isspace(*s)) s++;
3952
3953 /* If this isn't a single-key+file lookup, re-arrange the variables
3954 to be appropriate for the search_ functions. For query-style lookups,
3955 there is just a "key", and no file name. For the special query-style +
3956 file types, the query (i.e. "key") starts with a file name. */
3957
3958 if (key == NULL)
3959 {
3960 while (isspace(*filename)) filename++;
3961 key = filename;
3962
3963 if (mac_islookup(stype, lookup_querystyle))
3964 {
3965 filename = NULL;
3966 }
3967 else
3968 {
3969 if (*filename != '/')
3970 {
3971 expand_string_message = string_sprintf(
3972 "absolute file name expected for \"%s\" lookup", name);
3973 goto EXPAND_FAILED;
3974 }
3975 while (*key != 0 && !isspace(*key)) key++;
3976 if (*key != 0) *key++ = 0;
3977 }
3978 }
3979
3980 /* If skipping, don't do the next bit - just lookup_value == NULL, as if
3981 the entry was not found. Note that there is no search_close() function.
3982 Files are left open in case of re-use. At suitable places in higher logic,
3983 search_tidyup() is called to tidy all open files. This can save opening
3984 the same file several times. However, files may also get closed when
3985 others are opened, if too many are open at once. The rule is that a
3986 handle should not be used after a second search_open().
3987
3988 Request that a partial search sets up $1 and maybe $2 by passing
3989 expand_setup containing zero. If its value changes, reset expand_nmax,
3990 since new variables will have been set. Note that at the end of this
3991 "lookup" section, the old numeric variables are restored. */
3992
3993 if (skipping)
3994 lookup_value = NULL;
3995 else
3996 {
3997 void *handle = search_open(filename, stype, 0, NULL, NULL);
3998 if (handle == NULL)
3999 {
4000 expand_string_message = search_error_message;
4001 goto EXPAND_FAILED;
4002 }
4003 lookup_value = search_find(handle, filename, key, partial, affix,
4004 affixlen, starflags, &expand_setup);
4005 if (search_find_defer)
4006 {
4007 expand_string_message =
4008 string_sprintf("lookup of \"%s\" gave DEFER: %s",
4009 string_printing2(key, FALSE), search_error_message);
4010 goto EXPAND_FAILED;
4011 }
4012 if (expand_setup > 0) expand_nmax = expand_setup;
4013 }
4014
4015 /* The handling of "yes" and "no" result strings is now in a separate
4016 function that is also used by ${if} and ${extract}. */
4017
4018 switch(process_yesno(
4019 skipping, /* were previously skipping */
4020 lookup_value != NULL, /* success/failure indicator */
4021 save_lookup_value, /* value to reset for string2 */
4022 &s, /* input pointer */
4023 &yield, /* output pointer */
4024 &size, /* output size */
4025 &ptr, /* output current point */
4026 US"lookup")) /* condition type */
4027 {
4028 case 1: goto EXPAND_FAILED; /* when all is well, the */
4029 case 2: goto EXPAND_FAILED_CURLY; /* returned value is 0 */
4030 }
4031
4032 /* Restore external setting of expansion variables for carrying on
4033 at this level, and continue. */
4034
4035 restore_expand_strings(save_expand_nmax, save_expand_nstring,
4036 save_expand_nlength);
4037 continue;
4038 }
4039
4040 /* If Perl support is configured, handle calling embedded perl subroutines,
4041 unless locked out at this time. Syntax is ${perl{sub}} or ${perl{sub}{arg}}
4042 or ${perl{sub}{arg1}{arg2}} or up to a maximum of EXIM_PERL_MAX_ARGS
4043 arguments (defined below). */
4044
4045 #define EXIM_PERL_MAX_ARGS 8
4046
4047 case EITEM_PERL:
4048 #ifndef EXIM_PERL
4049 expand_string_message = US"\"${perl\" encountered, but this facility "
4050 "is not included in this binary";
4051 goto EXPAND_FAILED;
4052
4053 #else /* EXIM_PERL */
4054 {
4055 uschar *sub_arg[EXIM_PERL_MAX_ARGS + 2];
4056 uschar *new_yield;
4057
4058 if ((expand_forbid & RDO_PERL) != 0)
4059 {
4060 expand_string_message = US"Perl calls are not permitted";
4061 goto EXPAND_FAILED;
4062 }
4063
4064 switch(read_subs(sub_arg, EXIM_PERL_MAX_ARGS + 1, 1, &s, skipping, TRUE,
4065 US"perl"))
4066 {
4067 case 1: goto EXPAND_FAILED_CURLY;
4068 case 2:
4069 case 3: goto EXPAND_FAILED;
4070 }
4071
4072 /* If skipping, we don't actually do anything */
4073
4074 if (skipping) continue;
4075
4076 /* Start the interpreter if necessary */
4077
4078 if (!opt_perl_started)
4079 {
4080 uschar *initerror;
4081 if (opt_perl_startup == NULL)
4082 {
4083 expand_string_message = US"A setting of perl_startup is needed when "
4084 "using the Perl interpreter";
4085 goto EXPAND_FAILED;
4086 }
4087 DEBUG(D_any) debug_printf("Starting Perl interpreter\n");
4088 initerror = init_perl(opt_perl_startup);
4089 if (initerror != NULL)
4090 {
4091 expand_string_message =
4092 string_sprintf("error in perl_startup code: %s\n", initerror);
4093 goto EXPAND_FAILED;
4094 }
4095 opt_perl_started = TRUE;
4096 }
4097
4098 /* Call the function */
4099
4100 sub_arg[EXIM_PERL_MAX_ARGS + 1] = NULL;
4101 new_yield = call_perl_cat(yield, &size, &ptr, &expand_string_message,
4102 sub_arg[0], sub_arg + 1);
4103
4104 /* NULL yield indicates failure; if the message pointer has been set to
4105 NULL, the yield was undef, indicating a forced failure. Otherwise the
4106 message will indicate some kind of Perl error. */
4107
4108 if (new_yield == NULL)
4109 {
4110 if (expand_string_message == NULL)
4111 {
4112 expand_string_message =
4113 string_sprintf("Perl subroutine \"%s\" returned undef to force "
4114 "failure", sub_arg[0]);
4115 expand_string_forcedfail = TRUE;
4116 }
4117 goto EXPAND_FAILED;
4118 }
4119
4120 /* Yield succeeded. Ensure forcedfail is unset, just in case it got
4121 set during a callback from Perl. */
4122
4123 expand_string_forcedfail = FALSE;
4124 yield = new_yield;
4125 continue;
4126 }
4127 #endif /* EXIM_PERL */
4128
4129 /* Transform email address to "prvs" scheme to use
4130 as BATV-signed return path */
4131
4132 case EITEM_PRVS:
4133 {
4134 uschar *sub_arg[3];
4135 uschar *p,*domain;
4136
4137 switch(read_subs(sub_arg, 3, 2, &s, skipping, TRUE, US"prvs"))
4138 {
4139 case 1: goto EXPAND_FAILED_CURLY;
4140 case 2:
4141 case 3: goto EXPAND_FAILED;
4142 }
4143
4144 /* If skipping, we don't actually do anything */
4145 if (skipping) continue;
4146
4147 /* sub_arg[0] is the address */
4148 domain = Ustrrchr(sub_arg[0],'@');
4149 if ( (domain == NULL) || (domain == sub_arg[0]) || (Ustrlen(domain) == 1) )
4150 {
4151 expand_string_message = US"prvs first argument must be a qualified email address";
4152 goto EXPAND_FAILED;
4153 }
4154
4155 /* Calculate the hash. The second argument must be a single-digit
4156 key number, or unset. */
4157
4158 if (sub_arg[2] != NULL &&
4159 (!isdigit(sub_arg[2][0]) || sub_arg[2][1] != 0))
4160 {
4161 expand_string_message = US"prvs second argument must be a single digit";
4162 goto EXPAND_FAILED;
4163 }
4164
4165 p = prvs_hmac_sha1(sub_arg[0],sub_arg[1],sub_arg[2],prvs_daystamp(7));
4166 if (p == NULL)
4167 {
4168 expand_string_message = US"prvs hmac-sha1 conversion failed";
4169 goto EXPAND_FAILED;
4170 }
4171
4172 /* Now separate the domain from the local part */
4173 *domain++ = '\0';
4174
4175 yield = string_cat(yield,&size,&ptr,US"prvs=",5);
4176 string_cat(yield,&size,&ptr,(sub_arg[2] != NULL) ? sub_arg[2] : US"0", 1);
4177 string_cat(yield,&size,&ptr,prvs_daystamp(7),3);
4178 string_cat(yield,&size,&ptr,p,6);
4179 string_cat(yield,&size,&ptr,US"=",1);
4180 string_cat(yield,&size,&ptr,sub_arg[0],Ustrlen(sub_arg[0]));
4181 string_cat(yield,&size,&ptr,US"@",1);
4182 string_cat(yield,&size,&ptr,domain,Ustrlen(domain));
4183
4184 continue;
4185 }
4186
4187 /* Check a prvs-encoded address for validity */
4188
4189 case EITEM_PRVSCHECK:
4190 {
4191 uschar *sub_arg[3];
4192 int mysize = 0, myptr = 0;
4193 const pcre *re;
4194 uschar *p;
4195
4196 /* TF: Ugliness: We want to expand parameter 1 first, then set
4197 up expansion variables that are used in the expansion of
4198 parameter 2. So we clone the string for the first
4199 expansion, where we only expand parameter 1.
4200
4201 PH: Actually, that isn't necessary. The read_subs() function is
4202 designed to work this way for the ${if and ${lookup expansions. I've
4203 tidied the code.
4204 */
4205
4206 /* Reset expansion variables */
4207 prvscheck_result = NULL;
4208 prvscheck_address = NULL;
4209 prvscheck_keynum = NULL;
4210
4211 switch(read_subs(sub_arg, 1, 1, &s, skipping, FALSE, US"prvs"))
4212 {
4213 case 1: goto EXPAND_FAILED_CURLY;
4214 case 2:
4215 case 3: goto EXPAND_FAILED;
4216 }
4217
4218 re = regex_must_compile(US"^prvs\\=([0-9])([0-9]{3})([A-F0-9]{6})\\=(.+)\\@(.+)$",
4219 TRUE,FALSE);
4220
4221 if (regex_match_and_setup(re,sub_arg[0],0,-1))
4222 {
4223 uschar *local_part = string_copyn(expand_nstring[4],expand_nlength[4]);
4224 uschar *key_num = string_copyn(expand_nstring[1],expand_nlength[1]);
4225 uschar *daystamp = string_copyn(expand_nstring[2],expand_nlength[2]);
4226 uschar *hash = string_copyn(expand_nstring[3],expand_nlength[3]);
4227 uschar *domain = string_copyn(expand_nstring[5],expand_nlength[5]);
4228
4229 DEBUG(D_expand) debug_printf("prvscheck localpart: %s\n", local_part);
4230 DEBUG(D_expand) debug_printf("prvscheck key number: %s\n", key_num);
4231 DEBUG(D_expand) debug_printf("prvscheck daystamp: %s\n", daystamp);
4232 DEBUG(D_expand) debug_printf("prvscheck hash: %s\n", hash);
4233 DEBUG(D_expand) debug_printf("prvscheck domain: %s\n", domain);
4234
4235 /* Set up expansion variables */
4236 prvscheck_address = string_cat(NULL, &mysize, &myptr, local_part, Ustrlen(local_part));
4237 string_cat(prvscheck_address,&mysize,&myptr,US"@",1);
4238 string_cat(prvscheck_address,&mysize,&myptr,domain,Ustrlen(domain));
4239 prvscheck_address[myptr] = '\0';
4240 prvscheck_keynum = string_copy(key_num);
4241
4242 /* Now expand the second argument */
4243 switch(read_subs(sub_arg, 1, 1, &s, skipping, FALSE, US"prvs"))
4244 {
4245 case 1: goto EXPAND_FAILED_CURLY;
4246 case 2:
4247 case 3: goto EXPAND_FAILED;
4248 }
4249
4250 /* Now we have the key and can check the address. */
4251
4252 p = prvs_hmac_sha1(prvscheck_address, sub_arg[0], prvscheck_keynum,
4253 daystamp);
4254
4255 if (p == NULL)
4256 {
4257 expand_string_message = US"hmac-sha1 conversion failed";
4258 goto EXPAND_FAILED;
4259 }
4260
4261 DEBUG(D_expand) debug_printf("prvscheck: received hash is %s\n", hash);
4262 DEBUG(D_expand) debug_printf("prvscheck: own hash is %s\n", p);
4263
4264 if (Ustrcmp(p,hash) == 0)
4265 {
4266 /* Success, valid BATV address. Now check the expiry date. */
4267 uschar *now = prvs_daystamp(0);
4268 unsigned int inow = 0,iexpire = 1;
4269
4270 (void)sscanf(CS now,"%u",&inow);
4271 (void)sscanf(CS daystamp,"%u",&iexpire);
4272
4273 /* When "iexpire" is < 7, a "flip" has occured.
4274 Adjust "inow" accordingly. */
4275 if ( (iexpire < 7) && (inow >= 993) ) inow = 0;
4276
4277 if (iexpire >= inow)
4278 {
4279 prvscheck_result = US"1";
4280 DEBUG(D_expand) debug_printf("prvscheck: success, $pvrs_result set to 1\n");
4281 }
4282 else
4283 {
4284 prvscheck_result = NULL;
4285 DEBUG(D_expand) debug_printf("prvscheck: signature expired, $pvrs_result unset\n");
4286 }
4287 }
4288 else
4289 {
4290 prvscheck_result = NULL;
4291 DEBUG(D_expand) debug_printf("prvscheck: hash failure, $pvrs_result unset\n");
4292 }
4293
4294 /* Now expand the final argument. We leave this till now so that
4295 it can include $prvscheck_result. */
4296
4297 switch(read_subs(sub_arg, 1, 0, &s, skipping, TRUE, US"prvs"))
4298 {
4299 case 1: goto EXPAND_FAILED_CURLY;
4300 case 2:
4301 case 3: goto EXPAND_FAILED;
4302 }
4303
4304 if (sub_arg[0] == NULL || *sub_arg[0] == '\0')
4305 yield = string_cat(yield,&size,&ptr,prvscheck_address,Ustrlen(prvscheck_address));
4306 else
4307 yield = string_cat(yield,&size,&ptr,sub_arg[0],Ustrlen(sub_arg[0]));
4308
4309 /* Reset the "internal" variables afterwards, because they are in
4310 dynamic store that will be reclaimed if the expansion succeeded. */
4311
4312 prvscheck_address = NULL;
4313 prvscheck_keynum = NULL;
4314 }
4315 else
4316 {
4317 /* Does not look like a prvs encoded address, return the empty string.
4318 We need to make sure all subs are expanded first, so as to skip over
4319 the entire item. */
4320
4321 switch(read_subs(sub_arg, 2, 1, &s, skipping, TRUE, US"prvs"))
4322 {
4323 case 1: goto EXPAND_FAILED_CURLY;
4324 case 2:
4325 case 3: goto EXPAND_FAILED;
4326 }
4327 }
4328
4329 continue;
4330 }
4331
4332 /* Handle "readfile" to insert an entire file */
4333
4334 case EITEM_READFILE:
4335 {
4336 FILE *f;
4337 uschar *sub_arg[2];
4338
4339 if ((expand_forbid & RDO_READFILE) != 0)
4340 {
4341 expand_string_message = US"file insertions are not permitted";
4342 goto EXPAND_FAILED;
4343 }
4344
4345 switch(read_subs(sub_arg, 2, 1, &s, skipping, TRUE, US"readfile"))
4346 {
4347 case 1: goto EXPAND_FAILED_CURLY;
4348 case 2:
4349 case 3: goto EXPAND_FAILED;
4350 }
4351
4352 /* If skipping, we don't actually do anything */
4353
4354 if (skipping) continue;
4355
4356 /* Open the file and read it */
4357
4358 f = Ufopen(sub_arg[0], "rb");
4359 if (f == NULL)
4360 {
4361 expand_string_message = string_open_failed(errno, "%s", sub_arg[0]);
4362 goto EXPAND_FAILED;
4363 }
4364
4365 yield = cat_file(f, yield, &size, &ptr, sub_arg[1]);
4366 (void)fclose(f);
4367 continue;
4368 }
4369
4370 /* Handle "readsocket" to insert data from a Unix domain socket */
4371
4372 case EITEM_READSOCK:
4373 {
4374 int fd;
4375 int timeout = 5;
4376 int save_ptr = ptr;
4377 FILE *f;
4378 struct sockaddr_un sockun; /* don't call this "sun" ! */
4379 uschar *arg;
4380 uschar *sub_arg[4];
4381
4382 if ((expand_forbid & RDO_READSOCK) != 0)
4383 {
4384 expand_string_message = US"socket insertions are not permitted";
4385 goto EXPAND_FAILED;
4386 }
4387
4388 /* Read up to 4 arguments, but don't do the end of item check afterwards,
4389 because there may be a string for expansion on failure. */
4390
4391 switch(read_subs(sub_arg, 4, 2, &s, skipping, FALSE, US"readsocket"))
4392 {
4393 case 1: goto EXPAND_FAILED_CURLY;
4394 case 2: /* Won't occur: no end check */
4395 case 3: goto EXPAND_FAILED;
4396 }
4397
4398 /* Sort out timeout, if given */
4399
4400 if (sub_arg[2] != NULL)
4401 {
4402 timeout = readconf_readtime(sub_arg[2], 0, FALSE);
4403 if (timeout < 0)
4404 {
4405 expand_string_message = string_sprintf("bad time value %s",
4406 sub_arg[2]);
4407 goto EXPAND_FAILED;
4408 }
4409 }
4410 else sub_arg[3] = NULL; /* No eol if no timeout */
4411
4412 /* If skipping, we don't actually do anything. Otherwise, arrange to
4413 connect to either an IP or a Unix socket. */
4414
4415 if (!skipping)
4416 {
4417 /* Handle an IP (internet) domain */
4418
4419 if (Ustrncmp(sub_arg[0], "inet:", 5) == 0)
4420 {
4421 BOOL connected = FALSE;
4422 int namelen, port;
4423 host_item shost;
4424 host_item *h;
4425 uschar *server_name = sub_arg[0] + 5;
4426 uschar *port_name = Ustrrchr(server_name, ':');
4427
4428 /* Sort out the port */
4429
4430 if (port_name == NULL)
4431 {
4432 expand_string_message =
4433 string_sprintf("missing port for readsocket %s", sub_arg[0]);
4434 goto EXPAND_FAILED;
4435 }
4436 *port_name++ = 0; /* Terminate server name */
4437
4438 if (isdigit(*port_name))
4439 {
4440 uschar *end;
4441 port = Ustrtol(port_name, &end, 0);
4442 if (end != port_name + Ustrlen(port_name))
4443 {
4444 expand_string_message =
4445 string_sprintf("invalid port number %s", port_name);
4446 goto EXPAND_FAILED;
4447 }
4448 }
4449 else
4450 {
4451 struct servent *service_info = getservbyname(CS port_name, "tcp");
4452 if (service_info == NULL)
4453 {
4454 expand_string_message = string_sprintf("unknown port \"%s\"",
4455 port_name);
4456 goto EXPAND_FAILED;
4457 }
4458 port = ntohs(service_info->s_port);
4459 }
4460
4461 /* Sort out the server. */
4462
4463 shost.next = NULL;
4464 shost.address = NULL;
4465 shost.port = port;
4466 shost.mx = -1;
4467
4468 namelen = Ustrlen(server_name);
4469
4470 /* Anything enclosed in [] must be an IP address. */
4471
4472 if (server_name[0] == '[' &&
4473 server_name[namelen - 1] == ']')
4474 {
4475 server_name[namelen - 1] = 0;
4476 server_name++;
4477 if (string_is_ip_address(server_name, NULL) == 0)
4478 {
4479 expand_string_message =
4480 string_sprintf("malformed IP address \"%s\"", server_name);
4481 goto EXPAND_FAILED;
4482 }
4483 shost.name = shost.address = server_name;
4484 }
4485
4486 /* Otherwise check for an unadorned IP address */
4487
4488 else if (string_is_ip_address(server_name, NULL) != 0)
4489 shost.name = shost.address = server_name;
4490
4491 /* Otherwise lookup IP address(es) from the name */
4492
4493 else
4494 {
4495 shost.name = server_name;
4496 if (host_find_byname(&shost, NULL, HOST_FIND_QUALIFY_SINGLE, NULL,
4497 FALSE) != HOST_FOUND)
4498 {
4499 expand_string_message =
4500 string_sprintf("no IP address found for host %s", shost.name);
4501 goto EXPAND_FAILED;
4502 }
4503 }
4504
4505 /* Try to connect to the server - test each IP till one works */
4506
4507 for (h = &shost; h != NULL; h = h->next)
4508 {
4509 int af = (Ustrchr(h->address, ':') != 0)? AF_INET6 : AF_INET;
4510 if ((fd = ip_socket(SOCK_STREAM, af)) == -1)
4511 {
4512 expand_string_message = string_sprintf("failed to create socket: "
4513 "%s", strerror(errno));
4514 goto SOCK_FAIL;
4515 }
4516
4517 if (ip_connect(fd, af, h->address, port, timeout) == 0)
4518 {
4519 connected = TRUE;
4520 break;
4521 }
4522 }
4523
4524 if (!connected)
4525 {
4526 expand_string_message = string_sprintf("failed to connect to "
4527 "socket %s: couldn't connect to any host", sub_arg[0],
4528 strerror(errno));
4529 goto SOCK_FAIL;
4530 }
4531 }
4532
4533 /* Handle a Unix domain socket */
4534
4535 else
4536 {
4537 int rc;
4538 if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
4539 {
4540 expand_string_message = string_sprintf("failed to create socket: %s",
4541 strerror(errno));
4542 goto SOCK_FAIL;
4543 }
4544
4545 sockun.sun_family = AF_UNIX;
4546 sprintf(sockun.sun_path, "%.*s", (int)(sizeof(sockun.sun_path)-1),
4547 sub_arg[0]);
4548
4549 sigalrm_seen = FALSE;
4550 alarm(timeout);
4551 rc = connect(fd, (struct sockaddr *)(&sockun), sizeof(sockun));
4552 alarm(0);
4553 if (sigalrm_seen)
4554 {
4555 expand_string_message = US "socket connect timed out";
4556 goto SOCK_FAIL;
4557 }
4558 if (rc < 0)
4559 {
4560 expand_string_message = string_sprintf("failed to connect to socket "
4561 "%s: %s", sub_arg[0], strerror(errno));
4562 goto SOCK_FAIL;
4563 }
4564 }
4565
4566 DEBUG(D_expand) debug_printf("connected to socket %s\n", sub_arg[0]);
4567
4568 /* Write the request string, if not empty */
4569
4570 if (sub_arg[1][0] != 0)
4571 {
4572 int len = Ustrlen(sub_arg[1]);
4573 DEBUG(D_expand) debug_printf("writing \"%s\" to socket\n",
4574 sub_arg[1]);
4575 if (write(fd, sub_arg[1], len) != len)
4576 {
4577 expand_string_message = string_sprintf("request write to socket "
4578 "failed: %s", strerror(errno));
4579 goto SOCK_FAIL;
4580 }
4581 }
4582
4583 /* Shut down the sending side of the socket. This helps some servers to
4584 recognise that it is their turn to do some work. Just in case some
4585 system doesn't have this function, make it conditional. */
4586
4587 #ifdef SHUT_WR
4588 shutdown(fd, SHUT_WR);
4589 #endif
4590
4591 /* Now we need to read from the socket, under a timeout. The function
4592 that reads a file can be used. */
4593
4594 f = fdopen(fd, "rb");
4595 sigalrm_seen = FALSE;
4596 alarm(timeout);
4597 yield = cat_file(f, yield, &size, &ptr, sub_arg[3]);
4598 alarm(0);
4599 (void)fclose(f);
4600
4601 /* After a timeout, we restore the pointer in the result, that is,
4602 make sure we add nothing from the socket. */
4603
4604 if (sigalrm_seen)
4605 {
4606 ptr = save_ptr;
4607 expand_string_message = US "socket read timed out";
4608 goto SOCK_FAIL;
4609 }
4610 }
4611
4612 /* The whole thing has worked (or we were skipping). If there is a
4613 failure string following, we need to skip it. */
4614
4615 if (*s == '{')
4616 {
4617 if (expand_string_internal(s+1, TRUE, &s, TRUE, TRUE) == NULL)
4618 goto EXPAND_FAILED;
4619 if (*s++ != '}') goto EXPAND_FAILED_CURLY;
4620 while (isspace(*s)) s++;
4621 }
4622 if (*s++ != '}') goto EXPAND_FAILED_CURLY;
4623 continue;
4624
4625 /* Come here on failure to create socket, connect socket, write to the
4626 socket, or timeout on reading. If another substring follows, expand and
4627 use it. Otherwise, those conditions give expand errors. */
4628
4629 SOCK_FAIL:
4630 if (*s != '{') goto EXPAND_FAILED;
4631 DEBUG(D_any) debug_printf("%s\n", expand_string_message);
4632 arg = expand_string_internal(s+1, TRUE, &s, FALSE, TRUE);
4633 if (arg == NULL) goto EXPAND_FAILED;
4634 yield = string_cat(yield, &size, &ptr, arg, Ustrlen(arg));
4635 if (*s++ != '}') goto EXPAND_FAILED_CURLY;
4636 while (isspace(*s)) s++;
4637 if (*s++ != '}') goto EXPAND_FAILED_CURLY;
4638 continue;
4639 }
4640
4641 /* Handle "run" to execute a program. */
4642
4643 case EITEM_RUN:
4644 {
4645 FILE *f;
4646 uschar *arg;
4647 uschar **argv;
4648 pid_t pid;
4649 int fd_in, fd_out;
4650 int lsize = 0;
4651 int lptr = 0;
4652
4653 if ((expand_forbid & RDO_RUN) != 0)
4654 {
4655 expand_string_message = US"running a command is not permitted";
4656 goto EXPAND_FAILED;
4657 }
4658
4659 while (isspace(*s)) s++;
4660 if (*s != '{') goto EXPAND_FAILED_CURLY;
4661 arg = expand_string_internal(s+1, TRUE, &s, skipping, TRUE);
4662 if (arg == NULL) goto EXPAND_FAILED;
4663 while (isspace(*s)) s++;
4664 if (*s++ != '}') goto EXPAND_FAILED_CURLY;
4665
4666 if (skipping) /* Just pretend it worked when we're skipping */
4667 {
4668 runrc = 0;
4669 }
4670 else
4671 {
4672 if (!transport_set_up_command(&argv, /* anchor for arg list */
4673 arg, /* raw command */
4674 FALSE, /* don't expand the arguments */
4675 0, /* not relevant when... */
4676 NULL, /* no transporting address */
4677 US"${run} expansion", /* for error messages */
4678 &expand_string_message)) /* where to put error message */
4679 {
4680 goto EXPAND_FAILED;
4681 }
4682
4683 /* Create the child process, making it a group leader. */
4684
4685 pid = child_open(argv, NULL, 0077, &fd_in, &fd_out, TRUE);
4686
4687 if (pid < 0)
4688 {
4689 expand_string_message =
4690 string_sprintf("couldn't create child process: %s", strerror(errno));
4691 goto EXPAND_FAILED;
4692 }
4693
4694 /* Nothing is written to the standard input. */
4695
4696 (void)close(fd_in);
4697
4698 /* Read the pipe to get the command's output into $value (which is kept
4699 in lookup_value). Read during execution, so that if the output exceeds
4700 the OS pipe buffer limit, we don't block forever. */
4701
4702 f = fdopen(fd_out, "rb");
4703 sigalrm_seen = FALSE;
4704 alarm(60);
4705 lookup_value = cat_file(f, lookup_value, &lsize, &lptr, NULL);
4706 alarm(0);
4707 (void)fclose(f);
4708
4709 /* Wait for the process to finish, applying the timeout, and inspect its
4710 return code for serious disasters. Simple non-zero returns are passed on.
4711 */
4712
4713 if (sigalrm_seen == TRUE || (runrc = child_close(pid, 30)) < 0)
4714 {
4715 if (sigalrm_seen == TRUE || runrc == -256)
4716 {
4717 expand_string_message = string_sprintf("command timed out");
4718 killpg(pid, SIGKILL); /* Kill the whole process group */
4719 }
4720
4721 else if (runrc == -257)
4722 expand_string_message = string_sprintf("wait() failed: %s",
4723 strerror(errno));
4724
4725 else
4726 expand_string_message = string_sprintf("command killed by signal %d",
4727 -runrc);
4728
4729 goto EXPAND_FAILED;
4730 }
4731 }
4732
4733 /* Process the yes/no strings; $value may be useful in both cases */
4734
4735 switch(process_yesno(
4736 skipping, /* were previously skipping */
4737 runrc == 0, /* success/failure indicator */
4738 lookup_value, /* value to reset for string2 */
4739 &s, /* input pointer */
4740 &yield, /* output pointer */
4741 &size, /* output size */
4742 &ptr, /* output current point */
4743 US"run")) /* condition type */
4744 {
4745 case 1: goto EXPAND_FAILED; /* when all is well, the */
4746 case 2: goto EXPAND_FAILED_CURLY; /* returned value is 0 */
4747 }
4748
4749 continue;
4750 }
4751
4752 /* Handle character translation for "tr" */
4753
4754 case EITEM_TR:
4755 {
4756 int oldptr = ptr;
4757 int o2m;
4758 uschar *sub[3];
4759
4760 switch(read_subs(sub, 3, 3, &s, skipping, TRUE, US"tr"))
4761 {
4762 case 1: goto EXPAND_FAILED_CURLY;
4763 case 2:
4764 case 3: goto EXPAND_FAILED;
4765 }
4766
4767 yield = string_cat(yield, &size, &ptr, sub[0], Ustrlen(sub[0]));
4768 o2m = Ustrlen(sub[2]) - 1;
4769
4770 if (o2m >= 0) for (; oldptr < ptr; oldptr++)
4771 {
4772 uschar *m = Ustrrchr(sub[1], yield[oldptr]);
4773 if (m != NULL)
4774 {
4775 int o = m - sub[1];
4776 yield[oldptr] = sub[2][(o < o2m)? o : o2m];
4777 }
4778 }
4779
4780 continue;
4781 }
4782
4783 /* Handle "hash", "length", "nhash", and "substr" when they are given with
4784 expanded arguments. */
4785
4786 case EITEM_HASH:
4787 case EITEM_LENGTH:
4788 case EITEM_NHASH:
4789 case EITEM_SUBSTR:
4790 {
4791 int i;
4792 int len;
4793 uschar *ret;
4794 int val[2] = { 0, -1 };
4795 uschar *sub[3];
4796
4797 /* "length" takes only 2 arguments whereas the others take 2 or 3.
4798 Ensure that sub[2] is set in the ${length case. */
4799
4800 sub[2] = NULL;
4801 switch(read_subs(sub, (item_type == EITEM_LENGTH)? 2:3, 2, &s, skipping,
4802 TRUE, name))
4803 {
4804 case 1: goto EXPAND_FAILED_CURLY;
4805 case 2:
4806 case 3: goto EXPAND_FAILED;
4807 }
4808
4809 /* Juggle the arguments if there are only two of them: always move the
4810 string to the last position and make ${length{n}{str}} equivalent to
4811 ${substr{0}{n}{str}}. See the defaults for val[] above. */
4812
4813 if (sub[2] == NULL)
4814 {
4815 sub[2] = sub[1];
4816 sub[1] = NULL;
4817 if (item_type == EITEM_LENGTH)
4818 {
4819 sub[1] = sub[0];
4820 sub[0] = NULL;
4821 }
4822 }
4823
4824 for (i = 0; i < 2; i++)
4825 {
4826 if (sub[i] == NULL) continue;
4827 val[i] = (int)Ustrtol(sub[i], &ret, 10);
4828 if (*ret != 0 || (i != 0 && val[i] < 0))
4829 {
4830 expand_string_message = string_sprintf("\"%s\" is not a%s number "
4831 "(in \"%s\" expansion)", sub[i], (i != 0)? " positive" : "", name);
4832 goto EXPAND_FAILED;
4833 }
4834 }
4835
4836 ret =
4837 (item_type == EITEM_HASH)?
4838 compute_hash(sub[2], val[0], val[1], &len) :
4839 (item_type == EITEM_NHASH)?
4840 compute_nhash(sub[2], val[0], val[1], &len) :
4841 extract_substr(sub[2], val[0], val[1], &len);
4842
4843 if (ret == NULL) goto EXPAND_FAILED;
4844 yield = string_cat(yield, &size, &ptr, ret, len);
4845 continue;
4846 }
4847
4848 /* Handle HMAC computation: ${hmac{<algorithm>}{<secret>}{<text>}}
4849 This code originally contributed by Steve Haslam. It currently supports
4850 the use of MD5 and SHA-1 hashes.
4851
4852 We need some workspace that is large enough to handle all the supported
4853 hash types. Use macros to set the sizes rather than be too elaborate. */
4854
4855 #define MAX_HASHLEN 20
4856 #define MAX_HASHBLOCKLEN 64
4857
4858 case EITEM_HMAC:
4859 {
4860 uschar *sub[3];
4861 md5 md5_base;
4862 sha1 sha1_base;
4863 void *use_base;
4864 int type, i;
4865 int hashlen; /* Number of octets for the hash algorithm's output */
4866 int hashblocklen; /* Number of octets the hash algorithm processes */
4867 uschar *keyptr, *p;
4868 unsigned int keylen;
4869
4870 uschar keyhash[MAX_HASHLEN];
4871 uschar innerhash[MAX_HASHLEN];
4872 uschar finalhash[MAX_HASHLEN];
4873 uschar finalhash_hex[2*MAX_HASHLEN];
4874 uschar innerkey[MAX_HASHBLOCKLEN];
4875 uschar outerkey[MAX_HASHBLOCKLEN];
4876
4877 switch (read_subs(sub, 3, 3, &s, skipping, TRUE, name))
4878 {
4879 case 1: goto EXPAND_FAILED_CURLY;
4880 case 2:
4881 case 3: goto EXPAND_FAILED;
4882 }
4883
4884 if (Ustrcmp(sub[0], "md5") == 0)
4885 {
4886 type = HMAC_MD5;
4887 use_base = &md5_base;
4888 hashlen = 16;
4889 hashblocklen = 64;
4890 }
4891 else if (Ustrcmp(sub[0], "sha1") == 0)
4892 {
4893 type = HMAC_SHA1;
4894 use_base = &sha1_base;
4895 hashlen = 20;
4896 hashblocklen = 64;
4897 }
4898 else
4899 {
4900 expand_string_message =
4901 string_sprintf("hmac algorithm \"%s\" is not recognised", sub[0]);
4902 goto EXPAND_FAILED;
4903 }
4904
4905 keyptr = sub[1];
4906 keylen = Ustrlen(keyptr);
4907
4908 /* If the key is longer than the hash block length, then hash the key
4909 first */
4910
4911 if (keylen > hashblocklen)
4912 {
4913 chash_start(type, use_base);
4914 chash_end(type, use_base, keyptr, keylen, keyhash);
4915 keyptr = keyhash;
4916 keylen = hashlen;
4917 }
4918
4919 /* Now make the inner and outer key values */
4920
4921 memset(innerkey, 0x36, hashblocklen);
4922 memset(outerkey, 0x5c, hashblocklen);
4923
4924 for (i = 0; i < keylen; i++)
4925 {
4926 innerkey[i] ^= keyptr[i];
4927 outerkey[i] ^= keyptr[i];
4928 }
4929
4930 /* Now do the hashes */
4931
4932 chash_start(type, use_base);
4933 chash_mid(type, use_base, innerkey);
4934 chash_end(type, use_base, sub[2], Ustrlen(sub[2]), innerhash);
4935
4936 chash_start(type, use_base);
4937 chash_mid(type, use_base, outerkey);
4938 chash_end(type, use_base, innerhash, hashlen, finalhash);
4939
4940 /* Encode the final hash as a hex string */
4941
4942 p = finalhash_hex;
4943 for (i = 0; i < hashlen; i++)
4944 {
4945 *p++ = hex_digits[(finalhash[i] & 0xf0) >> 4];
4946 *p++ = hex_digits[finalhash[i] & 0x0f];
4947 }
4948
4949 DEBUG(D_any) debug_printf("HMAC[%s](%.*s,%.*s)=%.*s\n", sub[0],
4950 (int)keylen, keyptr, Ustrlen(sub[2]), sub[2], hashlen*2, finalhash_hex);
4951
4952 yield = string_cat(yield, &size, &ptr, finalhash_hex, hashlen*2);
4953 }
4954
4955 continue;
4956
4957 /* Handle global substitution for "sg" - like Perl's s/xxx/yyy/g operator.
4958 We have to save the numerical variables and restore them afterwards. */
4959
4960 case EITEM_SG:
4961 {
4962 const pcre *re;
4963 int moffset, moffsetextra, slen;
4964 int roffset;
4965 int emptyopt;
4966 const uschar *rerror;
4967 uschar *subject;
4968 uschar *sub[3];
4969 int save_expand_nmax =
4970 save_expand_strings(save_expand_nstring, save_expand_nlength);
4971
4972 switch(read_subs(sub, 3, 3, &s, skipping, TRUE, US"sg"))
4973 {
4974 case 1: goto EXPAND_FAILED_CURLY;
4975 case 2:
4976 case 3: goto EXPAND_FAILED;
4977 }
4978
4979 /* Compile the regular expression */
4980
4981 re = pcre_compile(CS sub[1], PCRE_COPT, (const char **)&rerror, &roffset,
4982 NULL);
4983
4984 if (re == NULL)
4985 {
4986 expand_string_message = string_sprintf("regular expression error in "
4987 "\"%s\": %s at offset %d", sub[1], rerror, roffset);
4988 goto EXPAND_FAILED;
4989 }
4990
4991 /* Now run a loop to do the substitutions as often as necessary. It ends
4992 when there are no more matches. Take care over matches of the null string;
4993 do the same thing as Perl does. */
4994
4995 subject = sub[0];
4996 slen = Ustrlen(sub[0]);
4997 moffset = moffsetextra = 0;
4998 emptyopt = 0;
4999
5000 for (;;)
5001 {
5002 int ovector[3*(EXPAND_MAXN+1)];
5003 int n = pcre_exec(re, NULL, CS subject, slen, moffset + moffsetextra,
5004 PCRE_EOPT | emptyopt, ovector, sizeof(ovector)/sizeof(int));
5005 int nn;
5006 uschar *insert;
5007
5008 /* No match - if we previously set PCRE_NOTEMPTY after a null match, this
5009 is not necessarily the end. We want to repeat the match from one
5010 character further along, but leaving the basic offset the same (for
5011 copying below). We can't be at the end of the string - that was checked
5012 before setting PCRE_NOTEMPTY. If PCRE_NOTEMPTY is not set, we are
5013 finished; copy the remaining string and end the loop. */
5014
5015 if (n < 0)
5016 {
5017 if (emptyopt != 0)
5018 {
5019 moffsetextra = 1;
5020 emptyopt = 0;
5021 continue;
5022 }
5023 yield = string_cat(yield, &size, &ptr, subject+moffset, slen-moffset);
5024 break;
5025 }
5026
5027 /* Match - set up for expanding the replacement. */
5028
5029 if (n == 0) n = EXPAND_MAXN + 1;
5030 expand_nmax = 0;
5031 for (nn = 0; nn < n*2; nn += 2)
5032 {
5033 expand_nstring[expand_nmax] = subject + ovector[nn];
5034 expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
5035 }
5036 expand_nmax--;
5037
5038 /* Copy the characters before the match, plus the expanded insertion. */
5039
5040 yield = string_cat(yield, &size, &ptr, subject + moffset,
5041 ovector[0] - moffset);
5042 insert = expand_string(sub[2]);
5043 if (insert == NULL) goto EXPAND_FAILED;
5044 yield = string_cat(yield, &size, &ptr, insert, Ustrlen(insert));
5045
5046 moffset = ovector[1];
5047 moffsetextra = 0;
5048 emptyopt = 0;
5049
5050 /* If we have matched an empty string, first check to see if we are at
5051 the end of the subject. If so, the loop is over. Otherwise, mimic
5052 what Perl's /g options does. This turns out to be rather cunning. First
5053 we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match a non-empty
5054 string at the same point. If this fails (picked up above) we advance to
5055 the next character. */
5056
5057 if (ovector[0] == ovector[1])
5058 {
5059 if (ovector[0] == slen) break;
5060 emptyopt = PCRE_NOTEMPTY | PCRE_ANCHORED;
5061 }
5062 }
5063
5064 /* All done - restore numerical variables. */
5065
5066 restore_expand_strings(save_expand_nmax, save_expand_nstring,
5067 save_expand_nlength);
5068 continue;
5069 }
5070
5071 /* Handle keyed and numbered substring extraction. If the first argument
5072 consists entirely of digits, then a numerical extraction is assumed. */
5073
5074 case EITEM_EXTRACT:
5075 {
5076 int i;
5077 int j = 2;
5078 int field_number = 1;
5079 BOOL field_number_set = FALSE;
5080 uschar *save_lookup_value = lookup_value;
5081 uschar *sub[3];
5082 int save_expand_nmax =
5083 save_expand_strings(save_expand_nstring, save_expand_nlength);
5084
5085 /* Read the arguments */
5086
5087 for (i = 0; i < j; i++)
5088 {
5089 while (isspace(*s)) s++;
5090 if (*s == '{')
5091 {
5092 sub[i] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE);
5093 if (sub[i] == NULL) goto EXPAND_FAILED;
5094 if (*s++ != '}') goto EXPAND_FAILED_CURLY;
5095
5096 /* After removal of leading and trailing white space, the first
5097 argument must not be empty; if it consists entirely of digits
5098 (optionally preceded by a minus sign), this is a numerical
5099 extraction, and we expect 3 arguments. */
5100
5101 if (i == 0)
5102 {
5103 int len;
5104 int x = 0;
5105 uschar *p = sub[0];
5106
5107 while (isspace(*p)) p++;
5108 sub[0] = p;
5109
5110 len = Ustrlen(p);
5111 while (len > 0 && isspace(p[len-1])) len--;
5112 p[len] = 0;
5113
5114 if (*p == 0 && !skipping)
5115 {
5116 expand_string_message = US"first argument of \"extract\" must "
5117 "not be empty";
5118 goto EXPAND_FAILED;
5119 }
5120
5121 if (*p == '-')
5122 {
5123 field_number = -1;
5124 p++;
5125 }
5126 while (*p != 0 && isdigit(*p)) x = x * 10 + *p++ - '0';
5127 if (*p == 0)
5128 {
5129 field_number *= x;
5130 j = 3; /* Need 3 args */
5131 field_number_set = TRUE;
5132 }
5133 }
5134 }
5135 else goto EXPAND_FAILED_CURLY;
5136 }
5137
5138 /* Extract either the numbered or the keyed substring into $value. If
5139 skipping, just pretend the extraction failed. */
5140
5141 lookup_value = skipping? NULL : field_number_set?
5142 expand_gettokened(field_number, sub[1], sub[2]) :
5143 expand_getkeyed(sub[0], sub[1]);
5144
5145 /* If no string follows, $value gets substituted; otherwise there can
5146 be yes/no strings, as for lookup or if. */
5147
5148 switch(process_yesno(
5149 skipping, /* were previously skipping */
5150 lookup_value != NULL, /* success/failure indicator */
5151 save_lookup_value, /* value to reset for string2 */
5152 &s, /* input pointer */
5153 &yield, /* output pointer */
5154 &size, /* output size */
5155 &ptr, /* output current point */
5156 US"extract")) /* condition type */
5157 {
5158 case 1: goto EXPAND_FAILED; /* when all is well, the */
5159 case 2: goto EXPAND_FAILED_CURLY; /* returned value is 0 */
5160 }
5161
5162 /* All done - restore numerical variables. */
5163
5164 restore_expand_strings(save_expand_nmax, save_expand_nstring,
5165 save_expand_nlength);
5166
5167 continue;
5168 }
5169
5170
5171 /* Handle list operations */
5172
5173 case EITEM_FILTER:
5174 case EITEM_MAP:
5175 case EITEM_REDUCE:
5176 {
5177 int sep = 0;
5178 int save_ptr = ptr;
5179 uschar outsep[2] = { '\0', '\0' };
5180 uschar *list, *expr, *temp;
5181 uschar *save_iterate_item = iterate_item;
5182 uschar *save_lookup_value = lookup_value;
5183
5184 while (isspace(*s)) s++;
5185 if (*s++ != '{') goto EXPAND_FAILED_CURLY;
5186
5187 list = expand_string_internal(s, TRUE, &s, skipping, TRUE);
5188 if (list == NULL) goto EXPAND_FAILED;
5189 if (*s++ != '}') goto EXPAND_FAILED_CURLY;
5190
5191 if (item_type == EITEM_REDUCE)
5192 {
5193 while (isspace(*s)) s++;
5194 if (*s++ != '{') goto EXPAND_FAILED_CURLY;
5195 temp = expand_string_internal(s, TRUE, &s, skipping, TRUE);
5196 if (temp == NULL) goto EXPAND_FAILED;
5197 lookup_value = temp;
5198 if (*s++ != '}') goto EXPAND_FAILED_CURLY;
5199 }
5200
5201 while (isspace(*s)) s++;
5202 if (*s++ != '{') goto EXPAND_FAILED_CURLY;
5203
5204 expr = s;
5205
5206 /* For EITEM_FILTER, call eval_condition once, with result discarded (as
5207 if scanning a "false" part). This allows us to find the end of the
5208 condition, because if the list is empty, we won't actually evaluate the
5209 condition for real. For EITEM_MAP and EITEM_REDUCE, do the same, using
5210 the normal internal expansion function. */
5211
5212 if (item_type == EITEM_FILTER)
5213 {
5214 temp = eval_condition(expr, NULL);
5215 if (temp != NULL) s = temp;
5216 }
5217 else
5218 {
5219 temp = expand_string_internal(s, TRUE, &s, TRUE, TRUE);
5220 }
5221
5222 if (temp == NULL)
5223 {
5224 expand_string_message = string_sprintf("%s inside \"%s\" item",
5225 expand_string_message, name);
5226 goto EXPAND_FAILED;
5227 }
5228
5229 while (isspace(*s)) s++;
5230 if (*s++ != '}')
5231 {
5232 expand_string_message = string_sprintf("missing } at end of condition "
5233 "or expression inside \"%s\"", name);
5234 goto EXPAND_FAILED;
5235 }
5236
5237 while (isspace(*s)) s++;
5238 if (*s++ != '}')
5239 {
5240 expand_string_message = string_sprintf("missing } at end of \"%s\"",
5241 name);
5242 goto EXPAND_FAILED;
5243 }
5244
5245 /* If we are skipping, we can now just move on to the next item. When
5246 processing for real, we perform the iteration. */
5247
5248 if (skipping) continue;
5249 while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)) != NULL)
5250 {
5251 *outsep = (uschar)sep; /* Separator as a string */
5252
5253 DEBUG(D_expand) debug_printf("%s: $item = \"%s\"\n", name, iterate_item);
5254
5255 if (item_type == EITEM_FILTER)
5256 {
5257 BOOL condresult;
5258 if (eval_condition(expr, &condresult) == NULL)
5259 {
5260 iterate_item = save_iterate_item;
5261 lookup_value = save_lookup_value;
5262 expand_string_message = string_sprintf("%s inside \"%s\" condition",
5263 expand_string_message, name);
5264 goto EXPAND_FAILED;
5265 }
5266 DEBUG(D_expand) debug_printf("%s: condition is %s\n", name,
5267 condresult? "true":"false");
5268 if (condresult)
5269 temp = iterate_item; /* TRUE => include this item */
5270 else
5271 continue; /* FALSE => skip this item */
5272 }
5273
5274 /* EITEM_MAP and EITEM_REDUCE */
5275
5276 else
5277 {
5278 temp = expand_string_internal(expr, TRUE, NULL, skipping, TRUE);
5279 if (temp == NULL)
5280 {
5281 iterate_item = save_iterate_item;
5282 expand_string_message = string_sprintf("%s inside \"%s\" item",
5283 expand_string_message, name);
5284 goto EXPAND_FAILED;
5285 }
5286 if (item_type == EITEM_REDUCE)
5287 {
5288 lookup_value = temp; /* Update the value of $value */
5289 continue; /* and continue the iteration */
5290 }
5291 }
5292
5293 /* We reach here for FILTER if the condition is true, always for MAP,
5294 and never for REDUCE. The value in "temp" is to be added to the output
5295 list that is being created, ensuring that any occurrences of the
5296 separator character are doubled. Unless we are dealing with the first
5297 item of the output list, add in a space if the new item begins with the
5298 separator character, or is an empty string. */
5299
5300 if (ptr != save_ptr && (temp[0] == *outsep || temp[0] == 0))
5301 yield = string_cat(yield, &size, &ptr, US" ", 1);
5302
5303 /* Add the string in "temp" to the output list that we are building,
5304 This is done in chunks by searching for the separator character. */
5305
5306 for (;;)
5307 {
5308 size_t seglen = Ustrcspn(temp, outsep);
5309 yield = string_cat(yield, &size, &ptr, temp, seglen + 1);
5310
5311 /* If we got to the end of the string we output one character
5312 too many; backup and end the loop. Otherwise arrange to double the
5313 separator. */
5314
5315 if (temp[seglen] == '\0') { ptr--; break; }
5316 yield = string_cat(yield, &size, &ptr, outsep, 1);
5317 temp += seglen + 1;
5318 }
5319
5320 /* Output a separator after the string: we will remove the redundant
5321 final one at the end. */
5322
5323 yield = string_cat(yield, &size, &ptr, outsep, 1);
5324 } /* End of iteration over the list loop */
5325
5326 /* REDUCE has generated no output above: output the final value of
5327 $value. */
5328
5329 if (item_type == EITEM_REDUCE)
5330 {
5331 yield = string_cat(yield, &size, &ptr, lookup_value,
5332 Ustrlen(lookup_value));
5333 lookup_value = save_lookup_value; /* Restore $value */
5334 }
5335
5336 /* FILTER and MAP generate lists: if they have generated anything, remove
5337 the redundant final separator. Even though an empty item at the end of a
5338 list does not count, this is tidier. */
5339
5340 else if (ptr != save_ptr) ptr--;
5341
5342 /* Restore preserved $item */
5343
5344 iterate_item = save_iterate_item;
5345 continue;
5346 }
5347
5348
5349 /* If ${dlfunc support is configured, handle calling dynamically-loaded
5350 functions, unless locked out at this time. Syntax is ${dlfunc{file}{func}}
5351 or ${dlfunc{file}{func}{arg}} or ${dlfunc{file}{func}{arg1}{arg2}} or up to
5352 a maximum of EXPAND_DLFUNC_MAX_ARGS arguments (defined below). */
5353
5354 #define EXPAND_DLFUNC_MAX_ARGS 8
5355
5356 case EITEM_DLFUNC:
5357 #ifndef EXPAND_DLFUNC
5358 expand_string_message = US"\"${dlfunc\" encountered, but this facility "
5359 "is not included in this binary";
5360 goto EXPAND_FAILED;
5361
5362 #else /* EXPAND_DLFUNC */
5363 {
5364 tree_node *t;
5365 exim_dlfunc_t *func;
5366 uschar *result;
5367 int status, argc;
5368 uschar *argv[EXPAND_DLFUNC_MAX_ARGS + 3];
5369
5370 if ((expand_forbid & RDO_DLFUNC) != 0)
5371 {
5372 expand_string_message =
5373 US"dynamically-loaded functions are not permitted";
5374 goto EXPAND_FAILED;
5375 }
5376
5377 switch(read_subs(argv, EXPAND_DLFUNC_MAX_ARGS + 2, 2, &s, skipping,
5378 TRUE, US"dlfunc"))
5379 {
5380 case 1: goto EXPAND_FAILED_CURLY;
5381 case 2:
5382 case 3: goto EXPAND_FAILED;
5383 }
5384
5385 /* If skipping, we don't actually do anything */
5386
5387 if (skipping) continue;
5388
5389 /* Look up the dynamically loaded object handle in the tree. If it isn't
5390 found, dlopen() the file and put the handle in the tree for next time. */
5391
5392 t = tree_search(dlobj_anchor, argv[0]);
5393 if (t == NULL)
5394 {
5395 void *handle = dlopen(CS argv[0], RTLD_LAZY);
5396 if (handle == NULL)
5397 {
5398 expand_string_message = string_sprintf("dlopen \"%s\" failed: %s",
5399 argv[0], dlerror());
5400 log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message);
5401 goto EXPAND_FAILED;
5402 }
5403 t = store_get_perm(sizeof(tree_node) + Ustrlen(argv[0]));
5404 Ustrcpy(t->name, argv[0]);
5405 t->data.ptr = handle;
5406 (void)tree_insertnode(&dlobj_anchor, t);
5407 }
5408
5409 /* Having obtained the dynamically loaded object handle, look up the
5410 function pointer. */
5411
5412 func = (exim_dlfunc_t *)dlsym(t->data.ptr, CS argv[1]);
5413 if (func == NULL)
5414 {
5415 expand_string_message = string_sprintf("dlsym \"%s\" in \"%s\" failed: "
5416 "%s", argv[1], argv[0], dlerror());
5417 log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message);
5418 goto EXPAND_FAILED;
5419 }
5420
5421 /* Call the function and work out what to do with the result. If it
5422 returns OK, we have a replacement string; if it returns DEFER then
5423 expansion has failed in a non-forced manner; if it returns FAIL then
5424 failure was forced; if it returns ERROR or any other value there's a
5425 problem, so panic slightly. In any case, assume that the function has
5426 side-effects on the store that must be preserved. */
5427
5428 resetok = FALSE;
5429 result = NULL;
5430 for (argc = 0; argv[argc] != NULL; argc++);
5431 status = func(&result, argc - 2, &argv[2]);
5432 if(status == OK)
5433 {
5434 if (result == NULL) result = US"";
5435 yield = string_cat(yield, &size, &ptr, result, Ustrlen(result));
5436 continue;
5437 }
5438 else
5439 {
5440 expand_string_message = result == NULL ? US"(no message)" : result;
5441 if(status == FAIL_FORCED) expand_string_forcedfail = TRUE;
5442 else if(status != FAIL)
5443 log_write(0, LOG_MAIN|LOG_PANIC, "dlfunc{%s}{%s} failed (%d): %s",
5444 argv[0], argv[1], status, expand_string_message);
5445 goto EXPAND_FAILED;
5446 }
5447 }
5448 #endif /* EXPAND_DLFUNC */
5449 }
5450
5451 /* Control reaches here if the name is not recognized as one of the more
5452 complicated expansion items. Check for the "operator" syntax (name terminated
5453 by a colon). Some of the operators have arguments, separated by _ from the
5454 name. */
5455
5456 if (*s == ':')
5457 {
5458 int c;
5459 uschar *arg = NULL;
5460 uschar *sub = expand_string_internal(s+1, TRUE, &s, skipping, TRUE);
5461 if (sub == NULL) goto EXPAND_FAILED;
5462 s++;
5463
5464 /* Owing to an historical mis-design, an underscore may be part of the
5465 operator name, or it may introduce arguments. We therefore first scan the
5466 table of names that contain underscores. If there is no match, we cut off
5467 the arguments and then scan the main table. */
5468
5469 c = chop_match(name, op_table_underscore,
5470 sizeof(op_table_underscore)/sizeof(uschar *));
5471
5472 if (c < 0)
5473 {
5474 arg = Ustrchr(name, '_');
5475 if (arg != NULL) *arg = 0;
5476 c = chop_match(name, op_table_main,
5477 sizeof(op_table_main)/sizeof(uschar *));
5478 if (c >= 0) c += sizeof(op_table_underscore)/sizeof(uschar *);
5479 if (arg != NULL) *arg++ = '_'; /* Put back for error messages */
5480 }
5481
5482 /* If we are skipping, we don't need to perform the operation at all.
5483 This matters for operations like "mask", because the data may not be
5484 in the correct format when skipping. For example, the expression may test
5485 for the existence of $sender_host_address before trying to mask it. For
5486 other operations, doing them may not fail, but it is a waste of time. */
5487
5488 if (skipping && c >= 0) continue;
5489
5490 /* Otherwise, switch on the operator type */
5491
5492 switch(c)
5493 {
5494 case EOP_BASE62:
5495 {
5496 uschar *t;
5497 unsigned long int n = Ustrtoul(sub, &t, 10);
5498 if (*t != 0)
5499 {
5500 expand_string_message = string_sprintf("argument for base62 "
5501 "operator is \"%s\", which is not a decimal number", sub);
5502 goto EXPAND_FAILED;
5503 }
5504 t = string_base62(n);
5505 yield = string_cat(yield, &size, &ptr, t, Ustrlen(t));
5506 continue;
5507 }
5508
5509 /* Note that for Darwin and Cygwin, BASE_62 actually has the value 36 */
5510
5511 case EOP_BASE62D:
5512 {
5513 uschar buf[16];
5514 uschar *tt = sub;
5515 unsigned long int n = 0;
5516 while (*tt != 0)
5517 {
5518 uschar *t = Ustrchr(base62_chars, *tt++);
5519 if (t == NULL)
5520 {
5521 expand_string_message = string_sprintf("argument for base62d "
5522 "operator is \"%s\", which is not a base %d number", sub,
5523 BASE_62);
5524 goto EXPAND_FAILED;
5525 }
5526 n = n * BASE_62 + (t - base62_chars);
5527 }
5528 (void)sprintf(CS buf, "%ld", n);
5529 yield = string_cat(yield, &size, &ptr, buf, Ustrlen(buf));
5530 continue;
5531 }
5532
5533 case EOP_EXPAND:
5534 {
5535 uschar *expanded = expand_string_internal(sub, FALSE, NULL, skipping, TRUE);
5536 if (expanded == NULL)
5537 {
5538 expand_string_message =
5539 string_sprintf("internal expansion of \"%s\" failed: %s", sub,
5540 expand_string_message);
5541 goto EXPAND_FAILED;
5542 }
5543 yield = string_cat(yield, &size, &ptr, expanded, Ustrlen(expanded));
5544 continue;
5545 }
5546
5547 case EOP_LC:
5548 {
5549 int count = 0;
5550 uschar *t = sub - 1;
5551 while (*(++t) != 0) { *t = tolower(*t); count++; }
5552 yield = string_cat(yield, &size, &ptr, sub, count);
5553 continue;
5554 }
5555
5556 case EOP_UC:
5557 {
5558 int count = 0;
5559 uschar *t = sub - 1;
5560 while (*(++t) != 0) { *t = toupper(*t); count++; }
5561 yield = string_cat(yield, &size, &ptr, sub, count);
5562 continue;
5563 }
5564
5565 case EOP_MD5:
5566 {
5567 md5 base;
5568 uschar digest[16];
5569 int j;
5570 char st[33];
5571 md5_start(&base);
5572 md5_end(&base, sub, Ustrlen(sub), digest);
5573 for(j = 0; j < 16; j++) sprintf(st+2*j, "%02x", digest[j]);
5574 yield = string_cat(yield, &size, &ptr, US st, (int)strlen(st));
5575 continue;
5576 }
5577
5578 case EOP_SHA1:
5579 {
5580 sha1 base;
5581 uschar digest[20];
5582 int j;
5583 char st[41];
5584 sha1_start(&base);
5585 sha1_end(&base, sub, Ustrlen(sub), digest);
5586 for(j = 0; j < 20; j++) sprintf(st+2*j, "%02X", digest[j]);
5587 yield = string_cat(yield, &size, &ptr, US st, (int)strlen(st));
5588 continue;
5589 }
5590
5591 /* Convert hex encoding to base64 encoding */
5592
5593 case EOP_HEX2B64:
5594 {
5595 int c = 0;
5596 int b = -1;
5597 uschar *in = sub;
5598 uschar *out = sub;
5599 uschar *enc;
5600
5601 for (enc = sub; *enc != 0; enc++)
5602 {
5603 if (!isxdigit(*enc))
5604 {
5605 expand_string_message = string_sprintf("\"%s\" is not a hex "
5606 "string", sub);
5607 goto EXPAND_FAILED;
5608 }
5609 c++;
5610 }
5611
5612 if ((c & 1) != 0)
5613 {
5614 expand_string_message = string_sprintf("\"%s\" contains an odd "
5615 "number of characters", sub);
5616 goto EXPAND_FAILED;
5617 }
5618
5619 while ((c = *in++) != 0)
5620 {
5621 if (isdigit(c)) c -= '0';
5622 else c = toupper(c) - 'A' + 10;
5623 if (b == -1)
5624 {
5625 b = c << 4;
5626 }
5627 else
5628 {
5629 *out++ = b | c;
5630 b = -1;
5631 }
5632 }
5633
5634 enc = auth_b64encode(sub, out - sub);
5635 yield = string_cat(yield, &size, &ptr, enc, Ustrlen(enc));
5636 continue;
5637 }
5638
5639 /* count the number of list elements */
5640
5641 case EOP_LISTCOUNT:
5642 {
5643 int cnt = 0;
5644 int sep = 0;
5645 uschar * cp;
5646 uschar buffer[256];
5647
5648 while (string_nextinlist(&sub, &sep, buffer, sizeof(buffer)) != NULL) cnt++;
5649 cp = string_sprintf("%d", cnt);
5650 yield = string_cat(yield, &size, &ptr, cp, Ustrlen(cp));
5651 continue;
5652 }
5653
5654 /* expand a named list given the name */
5655 /* handles nested named lists; requotes as colon-sep list */
5656
5657 case EOP_LISTNAMED:
5658 {
5659 tree_node *t = NULL;
5660 uschar * list;
5661 int sep = 0;
5662 uschar * item;
5663 uschar * suffix = "";
5664 BOOL needsep = FALSE;
5665 uschar buffer[256];
5666
5667 if (*sub == '+') sub++;
5668 if (arg == NULL) /* no-argument version */
5669 {
5670 if (!(t = tree_search(addresslist_anchor, sub)) &&
5671 !(t = tree_search(domainlist_anchor, sub)) &&
5672 !(t = tree_search(hostlist_anchor, sub)))
5673 t = tree_search(localpartlist_anchor, sub);
5674 }
5675 else switch(*arg) /* specific list-type version */
5676 {
5677 case 'a': t = tree_search(addresslist_anchor, sub); suffix = "_a"; break;
5678 case 'd': t = tree_search(domainlist_anchor, sub); suffix = "_d"; break;
5679 case 'h': t = tree_search(hostlist_anchor, sub); suffix = "_h"; break;
5680 case 'l': t = tree_search(localpartlist_anchor, sub); suffix = "_l"; break;
5681 default:
5682 expand_string_message = string_sprintf("bad suffix on \"list\" operator");
5683 goto EXPAND_FAILED;
5684 }
5685
5686 if(!t)
5687 {
5688 expand_string_message = string_sprintf("\"%s\" is not a %snamed list",
5689 sub, !arg?""
5690 : *arg=='a'?"address "
5691 : *arg=='d'?"domain "
5692 : *arg=='h'?"host "
5693 : *arg=='l'?"localpart "
5694 : 0);
5695 goto EXPAND_FAILED;
5696 }
5697
5698 list = ((namedlist_block *)(t->data.ptr))->string;
5699
5700 while ((item = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
5701 {
5702 uschar * buf = US" : ";
5703 if (needsep)
5704 yield = string_cat(yield, &size, &ptr, buf, 3);
5705 else
5706 needsep = TRUE;
5707
5708 if (*item == '+') /* list item is itself a named list */
5709 {
5710 uschar * sub = string_sprintf("${listnamed%s:%s}", suffix, item);
5711 item = expand_string_internal(sub, FALSE, NULL, FALSE, TRUE);
5712 }
5713 else if (sep != ':') /* item from non-colon-sep list, re-quote for colon list-separator */
5714 {
5715 char * cp;
5716 char tok[3];
5717 tok[0] = sep; tok[1] = ':'; tok[2] = 0;
5718 while ((cp= strpbrk((const char *)item, tok)))
5719 {
5720 yield = string_cat(yield, &size, &ptr, item, cp-(char *)item);
5721 if (*cp++ == ':') /* colon in a non-colon-sep list item, needs doubling */
5722 {
5723 yield = string_cat(yield, &size, &ptr, US"::", 2);
5724 item = cp;
5725 }
5726 else /* sep in item; should already be doubled; emit once */
5727 {
5728 yield = string_cat(yield, &size, &ptr, (uschar *)tok, 1);
5729 if (*cp == sep) cp++;
5730 item = cp;
5731 }
5732 }
5733 }
5734 yield = string_cat(yield, &size, &ptr, item, Ustrlen(item));
5735 }
5736 continue;
5737 }
5738
5739 /* mask applies a mask to an IP address; for example the result of
5740 ${mask:131.111.10.206/28} is 131.111.10.192/28. */
5741
5742 case EOP_MASK:
5743 {
5744 int count;
5745 uschar *endptr;
5746 int binary[4];
5747 int mask, maskoffset;
5748 int type = string_is_ip_address(sub, &maskoffset);
5749 uschar buffer[64];
5750
5751 if (type == 0)
5752 {
5753 expand_string_message = string_sprintf("\"%s\" is not an IP address",
5754 sub);
5755 goto EXPAND_FAILED;
5756 }
5757
5758 if (maskoffset == 0)
5759 {
5760 expand_string_message = string_sprintf("missing mask value in \"%s\"",
5761 sub);
5762 goto EXPAND_FAILED;
5763 }
5764
5765 mask = Ustrtol(sub + maskoffset + 1, &endptr, 10);
5766
5767 if (*endptr != 0 || mask < 0 || mask > ((type == 4)? 32 : 128))
5768 {
5769 expand_string_message = string_sprintf("mask value too big in \"%s\"",
5770 sub);
5771 goto EXPAND_FAILED;
5772 }
5773
5774 /* Convert the address to binary integer(s) and apply the mask */
5775
5776 sub[maskoffset] = 0;
5777 count = host_aton(sub, binary);
5778 host_mask(count, binary, mask);
5779
5780 /* Convert to masked textual format and add to output. */
5781
5782 yield = string_cat(yield, &size, &ptr, buffer,
5783 host_nmtoa(count, binary, mask, buffer, '.'));
5784 continue;
5785 }
5786
5787 case EOP_ADDRESS:
5788 case EOP_LOCAL_PART:
5789 case EOP_DOMAIN:
5790 {
5791 uschar *error;
5792 int start, end, domain;
5793 uschar *t = parse_extract_address(sub, &error, &start, &end, &domain,
5794 FALSE);
5795 if (t != NULL)
5796 {
5797 if (c != EOP_DOMAIN)
5798 {
5799 if (c == EOP_LOCAL_PART && domain != 0) end = start + domain - 1;
5800 yield = string_cat(yield, &size, &ptr, sub+start, end-start);
5801 }
5802 else if (domain != 0)
5803 {
5804 domain += start;
5805 yield = string_cat(yield, &size, &ptr, sub+domain, end-domain);
5806 }
5807 }
5808 continue;
5809 }
5810
5811 case EOP_ADDRESSES:
5812 {
5813 uschar outsep[2] = { ':', '\0' };
5814 uschar *address, *error;
5815 int save_ptr = ptr;
5816 int start, end, domain; /* Not really used */
5817
5818 while (isspace(*sub)) sub++;
5819 if (*sub == '>') { *outsep = *++sub; ++sub; }
5820 parse_allow_group = TRUE;
5821
5822 for (;;)
5823 {
5824 uschar *p = parse_find_address_end(sub, FALSE);
5825 uschar saveend = *p;
5826 *p = '\0';
5827 address = parse_extract_address(sub, &error, &start, &end, &domain,
5828 FALSE);
5829 *p = saveend;
5830
5831 /* Add the address to the output list that we are building. This is
5832 done in chunks by searching for the separator character. At the
5833 start, unless we are dealing with the first address of the output
5834 list, add in a space if the new address begins with the separator
5835 character, or is an empty string. */
5836
5837 if (address != NULL)
5838 {
5839 if (ptr != save_ptr && address[0] == *outsep)
5840 yield = string_cat(yield, &size, &ptr, US" ", 1);
5841
5842 for (;;)
5843 {
5844 size_t seglen = Ustrcspn(address, outsep);
5845 yield = string_cat(yield, &size, &ptr, address, seglen + 1);
5846
5847 /* If we got to the end of the string we output one character
5848 too many. */
5849
5850 if (address[seglen] == '\0') { ptr--; break; }
5851 yield = string_cat(yield, &size, &ptr, outsep, 1);
5852 address += seglen + 1;
5853 }
5854
5855 /* Output a separator after the string: we will remove the
5856 redundant final one at the end. */
5857
5858 yield = string_cat(yield, &size, &ptr, outsep, 1);
5859 }
5860
5861 if (saveend == '\0') break;
5862 sub = p + 1;
5863 }
5864
5865 /* If we have generated anything, remove the redundant final
5866 separator. */
5867
5868 if (ptr != save_ptr) ptr--;
5869 parse_allow_group = FALSE;
5870 continue;
5871 }
5872
5873
5874 /* quote puts a string in quotes if it is empty or contains anything
5875 other than alphamerics, underscore, dot, or hyphen.
5876
5877 quote_local_part puts a string in quotes if RFC 2821/2822 requires it to
5878 be quoted in order to be a valid local part.
5879
5880 In both cases, newlines and carriage returns are converted into \n and \r
5881 respectively */
5882
5883 case EOP_QUOTE:
5884 case EOP_QUOTE_LOCAL_PART:
5885 if (arg == NULL)
5886 {
5887 BOOL needs_quote = (*sub == 0); /* TRUE for empty string */
5888 uschar *t = sub - 1;
5889
5890 if (c == EOP_QUOTE)
5891 {
5892 while (!needs_quote && *(++t) != 0)
5893 needs_quote = !isalnum(*t) && !strchr("_-.", *t);
5894 }
5895 else /* EOP_QUOTE_LOCAL_PART */
5896 {
5897 while (!needs_quote && *(++t) != 0)
5898 needs_quote = !isalnum(*t) &&
5899 strchr("!#$%&'*+-/=?^_`{|}~", *t) == NULL &&
5900 (*t != '.' || t == sub || t[1] == 0);
5901 }
5902
5903 if (needs_quote)
5904 {
5905 yield = string_cat(yield, &size, &ptr, US"\"", 1);
5906 t = sub - 1;
5907 while (*(++t) != 0)
5908 {
5909 if (*t == '\n')
5910 yield = string_cat(yield, &size, &ptr, US"\\n", 2);
5911 else if (*t == '\r')
5912 yield = string_cat(yield, &size, &ptr, US"\\r", 2);
5913 else
5914 {
5915 if (*t == '\\' || *t == '"')
5916 yield = string_cat(yield, &size, &ptr, US"\\", 1);
5917 yield = string_cat(yield, &size, &ptr, t, 1);
5918 }
5919 }
5920 yield = string_cat(yield, &size, &ptr, US"\"", 1);
5921 }
5922 else yield = string_cat(yield, &size, &ptr, sub, Ustrlen(sub));
5923 continue;
5924 }
5925
5926 /* quote_lookuptype does lookup-specific quoting */
5927
5928 else
5929 {
5930 int n;
5931 uschar *opt = Ustrchr(arg, '_');
5932
5933 if (opt != NULL) *opt++ = 0;
5934
5935 n = search_findtype(arg, Ustrlen(arg));
5936 if (n < 0)
5937 {
5938 expand_string_message = search_error_message;
5939 goto EXPAND_FAILED;
5940 }
5941
5942 if (lookup_list[n]->quote != NULL)
5943 sub = (lookup_list[n]->quote)(sub, opt);
5944 else if (opt != NULL) sub = NULL;
5945
5946 if (sub == NULL)
5947 {
5948 expand_string_message = string_sprintf(
5949 "\"%s\" unrecognized after \"${quote_%s\"",
5950 opt, arg);
5951 goto EXPAND_FAILED;
5952 }
5953
5954 yield = string_cat(yield, &size, &ptr, sub, Ustrlen(sub));
5955 continue;
5956 }
5957
5958 /* rx quote sticks in \ before any non-alphameric character so that
5959 the insertion works in a regular expression. */
5960
5961 case EOP_RXQUOTE:
5962 {
5963 uschar *t = sub - 1;
5964 while (*(++t) != 0)
5965 {
5966 if (!isalnum(*t))
5967 yield = string_cat(yield, &size, &ptr, US"\\", 1);
5968 yield = string_cat(yield, &size, &ptr, t, 1);
5969 }
5970 continue;
5971 }
5972
5973 /* RFC 2047 encodes, assuming headers_charset (default ISO 8859-1) as
5974 prescribed by the RFC, if there are characters that need to be encoded */
5975
5976 case EOP_RFC2047:
5977 {
5978 uschar buffer[2048];
5979 uschar *string = parse_quote_2047(sub, Ustrlen(sub), headers_charset,
5980 buffer, sizeof(buffer), FALSE);
5981 yield = string_cat(yield, &size, &ptr, string, Ustrlen(string));
5982 continue;
5983 }
5984
5985 /* RFC 2047 decode */
5986
5987 case EOP_RFC2047D:
5988 {
5989 int len;
5990 uschar *error;
5991 uschar *decoded = rfc2047_decode(sub, check_rfc2047_length,
5992 headers_charset, '?', &len, &error);
5993 if (error != NULL)
5994 {
5995 expand_string_message = error;
5996 goto EXPAND_FAILED;
5997 }
5998 yield = string_cat(yield, &size, &ptr, decoded, len);
5999 continue;
6000 }
6001
6002 /* from_utf8 converts UTF-8 to 8859-1, turning non-existent chars into
6003 underscores */
6004
6005 case EOP_FROM_UTF8:
6006 {
6007 while (*sub != 0)
6008 {
6009 int c;
6010 uschar buff[4];
6011 GETUTF8INC(c, sub);
6012 if (c > 255) c = '_';
6013 buff[0] = c;
6014 yield = string_cat(yield, &size, &ptr, buff, 1);
6015 }
6016 continue;
6017 }
6018
6019 /* escape turns all non-printing characters into escape sequences. */
6020
6021 case EOP_ESCAPE:
6022 {
6023 uschar *t = string_printing(sub);
6024 yield = string_cat(yield, &size, &ptr, t, Ustrlen(t));
6025 continue;
6026 }
6027
6028 /* Handle numeric expression evaluation */
6029
6030 case EOP_EVAL:
6031 case EOP_EVAL10:
6032 {
6033 uschar *save_sub = sub;
6034 uschar *error = NULL;
6035 int_eximarith_t n = eval_expr(&sub, (c == EOP_EVAL10), &error, FALSE);
6036 if (error != NULL)
6037 {
6038 expand_string_message = string_sprintf("error in expression "
6039 "evaluation: %s (after processing \"%.*s\")", error, sub-save_sub,
6040 save_sub);
6041 goto EXPAND_FAILED;
6042 }
6043 sprintf(CS var_buffer, PR_EXIM_ARITH, n);
6044 yield = string_cat(yield, &size, &ptr, var_buffer, Ustrlen(var_buffer));
6045 continue;
6046 }
6047
6048 /* Handle time period formating */
6049
6050 case EOP_TIME_EVAL:
6051 {
6052 int n = readconf_readtime(sub, 0, FALSE);
6053 if (n < 0)
6054 {
6055 expand_string_message = string_sprintf("string \"%s\" is not an "
6056 "Exim time interval in \"%s\" operator", sub, name);
6057 goto EXPAND_FAILED;
6058 }
6059 sprintf(CS var_buffer, "%d", n);
6060 yield = string_cat(yield, &size, &ptr, var_buffer, Ustrlen(var_buffer));
6061 continue;
6062 }
6063
6064 case EOP_TIME_INTERVAL:
6065 {
6066 int n;
6067 uschar *t = read_number(&n, sub);
6068 if (*t != 0) /* Not A Number*/
6069 {
6070 expand_string_message = string_sprintf("string \"%s\" is not a "
6071 "positive number in \"%s\" operator", sub, name);
6072 goto EXPAND_FAILED;
6073 }
6074 t = readconf_printtime(n);
6075 yield = string_cat(yield, &size, &ptr, t, Ustrlen(t));
6076 continue;
6077 }
6078
6079 /* Convert string to base64 encoding */
6080
6081 case EOP_STR2B64:
6082 {
6083 uschar *encstr = auth_b64encode(sub, Ustrlen(sub));
6084 yield = string_cat(yield, &size, &ptr, encstr, Ustrlen(encstr));
6085 continue;
6086 }
6087
6088 /* strlen returns the length of the string */
6089
6090 case EOP_STRLEN:
6091 {
6092 uschar buff[24];
6093 (void)sprintf(CS buff, "%d", Ustrlen(sub));
6094 yield = string_cat(yield, &size, &ptr, buff, Ustrlen(buff));
6095 continue;
6096 }
6097
6098 /* length_n or l_n takes just the first n characters or the whole string,
6099 whichever is the shorter;
6100
6101 substr_m_n, and s_m_n take n characters from offset m; negative m take
6102 from the end; l_n is synonymous with s_0_n. If n is omitted in substr it
6103 takes the rest, either to the right or to the left.
6104
6105 hash_n or h_n makes a hash of length n from the string, yielding n
6106 characters from the set a-z; hash_n_m makes a hash of length n, but
6107 uses m characters from the set a-zA-Z0-9.
6108
6109 nhash_n returns a single number between 0 and n-1 (in text form), while
6110 nhash_n_m returns a div/mod hash as two numbers "a/b". The first lies
6111 between 0 and n-1 and the second between 0 and m-1. */
6112
6113 case EOP_LENGTH:
6114 case EOP_L:
6115 case EOP_SUBSTR:
6116 case EOP_S:
6117 case EOP_HASH:
6118 case EOP_H:
6119 case EOP_NHASH:
6120 case EOP_NH:
6121 {
6122 int sign = 1;
6123 int value1 = 0;
6124 int value2 = -1;
6125 int *pn;
6126 int len;
6127 uschar *ret;
6128
6129 if (arg == NULL)
6130 {
6131 expand_string_message = string_sprintf("missing values after %s",
6132 name);
6133 goto EXPAND_FAILED;
6134 }
6135
6136 /* "length" has only one argument, effectively being synonymous with
6137 substr_0_n. */
6138
6139 if (c == EOP_LENGTH || c == EOP_L)
6140 {
6141 pn = &value2;
6142 value2 = 0;
6143 }
6144
6145 /* The others have one or two arguments; for "substr" the first may be
6146 negative. The second being negative means "not supplied". */
6147
6148 else
6149 {
6150 pn = &value1;
6151 if (name[0] == 's' && *arg == '-') { sign = -1; arg++; }
6152 }
6153
6154 /* Read up to two numbers, separated by underscores */
6155
6156 ret = arg;
6157 while (*arg != 0)
6158 {
6159 if (arg != ret && *arg == '_' && pn == &value1)
6160 {
6161 pn = &value2;
6162 value2 = 0;
6163 if (arg[1] != 0) arg++;
6164 }
6165 else if (!isdigit(*arg))
6166 {
6167 expand_string_message =
6168 string_sprintf("non-digit after underscore in \"%s\"", name);
6169 goto EXPAND_FAILED;
6170 }
6171 else *pn = (*pn)*10 + *arg++ - '0';
6172 }
6173 value1 *= sign;
6174
6175 /* Perform the required operation */
6176
6177 ret =
6178 (c == EOP_HASH || c == EOP_H)?
6179 compute_hash(sub, value1, value2, &len) :
6180 (c == EOP_NHASH || c == EOP_NH)?
6181 compute_nhash(sub, value1, value2, &len) :
6182 extract_substr(sub, value1, value2, &len);
6183
6184 if (ret == NULL) goto EXPAND_FAILED;
6185 yield = string_cat(yield, &size, &ptr, ret, len);
6186 continue;
6187 }
6188
6189 /* Stat a path */
6190
6191 case EOP_STAT:
6192 {
6193 uschar *s;
6194 uschar smode[12];
6195 uschar **modetable[3];
6196 int i;
6197 mode_t mode;
6198 struct stat st;
6199
6200 if ((expand_forbid & RDO_EXISTS) != 0)
6201 {
6202 expand_string_message = US"Use of the stat() expansion is not permitted";
6203 goto EXPAND_FAILED;
6204 }
6205
6206 if (stat(CS sub, &st) < 0)
6207 {
6208 expand_string_message = string_sprintf("stat(%s) failed: %s",
6209 sub, strerror(errno));
6210 goto EXPAND_FAILED;
6211 }
6212 mode = st.st_mode;
6213 switch (mode & S_IFMT)
6214 {
6215 case S_IFIFO: smode[0] = 'p'; break;
6216 case S_IFCHR: smode[0] = 'c'; break;
6217 case S_IFDIR: smode[0] = 'd'; break;
6218 case S_IFBLK: smode[0] = 'b'; break;
6219 case S_IFREG: smode[0] = '-'; break;
6220 default: smode[0] = '?'; break;
6221 }
6222
6223 modetable[0] = ((mode & 01000) == 0)? mtable_normal : mtable_sticky;
6224 modetable[1] = ((mode & 02000) == 0)? mtable_normal : mtable_setid;
6225 modetable[2] = ((mode & 04000) == 0)? mtable_normal : mtable_setid;
6226
6227 for (i = 0; i < 3; i++)
6228 {
6229 memcpy(CS(smode + 7 - i*3), CS(modetable[i][mode & 7]), 3);
6230 mode >>= 3;
6231 }
6232
6233 smode[10] = 0;
6234 s = string_sprintf("mode=%04lo smode=%s inode=%ld device=%ld links=%ld "
6235 "uid=%ld gid=%ld size=" OFF_T_FMT " atime=%ld mtime=%ld ctime=%ld",
6236 (long)(st.st_mode & 077777), smode, (long)st.st_ino,
6237 (long)st.st_dev, (long)st.st_nlink, (long)st.st_uid,
6238 (long)st.st_gid, st.st_size, (long)st.st_atime,
6239 (long)st.st_mtime, (long)st.st_ctime);
6240 yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
6241 continue;
6242 }
6243
6244 /* vaguely random number less than N */
6245
6246 case EOP_RANDINT:
6247 {
6248 int_eximarith_t max;
6249 uschar *s;
6250
6251 max = expand_string_integer(sub, TRUE);
6252 if (expand_string_message != NULL)
6253 goto EXPAND_FAILED;
6254 s = string_sprintf("%d", vaguely_random_number((int)max));
6255 yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
6256 continue;
6257 }
6258
6259 /* Reverse IP, including IPv6 to dotted-nibble */
6260
6261 case EOP_REVERSE_IP:
6262 {
6263 int family, maskptr;
6264 uschar reversed[128];
6265
6266 family = string_is_ip_address(sub, &maskptr);
6267 if (family == 0)
6268 {
6269 expand_string_message = string_sprintf(
6270 "reverse_ip() not given an IP address [%s]", sub);
6271 goto EXPAND_FAILED;
6272 }
6273 invert_address(reversed, sub);
6274 yield = string_cat(yield, &size, &ptr, reversed, Ustrlen(reversed));
6275 continue;
6276 }
6277
6278 /* Unknown operator */
6279
6280 default:
6281 expand_string_message =
6282 string_sprintf("unknown expansion operator \"%s\"", name);
6283 goto EXPAND_FAILED;
6284 }
6285 }
6286
6287 /* Handle a plain name. If this is the first thing in the expansion, release
6288 the pre-allocated buffer. If the result data is known to be in a new buffer,
6289 newsize will be set to the size of that buffer, and we can just point at that
6290 store instead of copying. Many expansion strings contain just one reference,
6291 so this is a useful optimization, especially for humungous headers
6292 ($message_headers). */
6293
6294 if (*s++ == '}')
6295 {
6296 int len;
6297 int newsize = 0;
6298 if (ptr == 0)
6299 {
6300 if (resetok) store_reset(yield);
6301 yield = NULL;
6302 size = 0;
6303 }
6304 value = find_variable(name, FALSE, skipping, &newsize);
6305 if (value == NULL)
6306 {
6307 expand_string_message =
6308 string_sprintf("unknown variable in \"${%s}\"", name);
6309 check_variable_error_message(name);
6310 goto EXPAND_FAILED;
6311 }
6312 len = Ustrlen(value);
6313 if (yield == NULL && newsize != 0)
6314 {
6315 yield = value;
6316 size = newsize;
6317 ptr = len;
6318 }
6319 else yield = string_cat(yield, &size, &ptr, value, len);
6320 continue;
6321 }
6322
6323 /* Else there's something wrong */
6324
6325 expand_string_message =
6326 string_sprintf("\"${%s\" is not a known operator (or a } is missing "
6327 "in a variable reference)", name);
6328 goto EXPAND_FAILED;
6329 }
6330
6331 /* If we hit the end of the string when ket_ends is set, there is a missing
6332 terminating brace. */
6333
6334 if (ket_ends && *s == 0)
6335 {
6336 expand_string_message = malformed_header?
6337 US"missing } at end of string - could be header name not terminated by colon"
6338 :
6339 US"missing } at end of string";
6340 goto EXPAND_FAILED;
6341 }
6342
6343 /* Expansion succeeded; yield may still be NULL here if nothing was actually
6344 added to the string. If so, set up an empty string. Add a terminating zero. If
6345 left != NULL, return a pointer to the terminator. */
6346
6347 if (yield == NULL) yield = store_get(1);
6348 yield[ptr] = 0;
6349 if (left != NULL) *left = s;
6350
6351 /* Any stacking store that was used above the final string is no longer needed.
6352 In many cases the final string will be the first one that was got and so there
6353 will be optimal store usage. */
6354
6355 if (resetok) store_reset(yield + ptr + 1);
6356 DEBUG(D_expand)
6357 {
6358 debug_printf("expanding: %.*s\n result: %s\n", (int)(s - string), string,
6359 yield);
6360 if (skipping) debug_printf("skipping: result is not used\n");
6361 }
6362 return yield;
6363
6364 /* This is the failure exit: easiest to program with a goto. We still need
6365 to update the pointer to the terminator, for cases of nested calls with "fail".
6366 */
6367
6368 EXPAND_FAILED_CURLY:
6369 expand_string_message = malformed_header?
6370 US"missing or misplaced { or } - could be header name not terminated by colon"
6371 :
6372 US"missing or misplaced { or }";
6373
6374 /* At one point, Exim reset the store to yield (if yield was not NULL), but
6375 that is a bad idea, because expand_string_message is in dynamic store. */
6376
6377 EXPAND_FAILED:
6378 if (left != NULL) *left = s;
6379 DEBUG(D_expand)
6380 {
6381 debug_printf("failed to expand: %s\n", string);
6382 debug_printf(" error message: %s\n", expand_string_message);
6383 if (expand_string_forcedfail) debug_printf("failure was forced\n");
6384 }
6385 return NULL;
6386 }
6387
6388
6389 /* This is the external function call. Do a quick check for any expansion
6390 metacharacters, and if there are none, just return the input string.
6391
6392 Argument: the string to be expanded
6393 Returns: the expanded string, or NULL if expansion failed; if failure was
6394 due to a lookup deferring, search_find_defer will be TRUE
6395 */
6396
6397 uschar *
6398 expand_string(uschar *string)
6399 {
6400 search_find_defer = FALSE;
6401 malformed_header = FALSE;
6402 return (Ustrpbrk(string, "$\\") == NULL)? string :
6403 expand_string_internal(string, FALSE, NULL, FALSE, TRUE);
6404 }
6405
6406
6407
6408 /*************************************************
6409 * Expand and copy *
6410 *************************************************/
6411
6412 /* Now and again we want to expand a string and be sure that the result is in a
6413 new bit of store. This function does that.
6414
6415 Argument: the string to be expanded
6416 Returns: the expanded string, always in a new bit of store, or NULL
6417 */
6418
6419 uschar *
6420 expand_string_copy(uschar *string)
6421 {
6422 uschar *yield = expand_string(string);
6423 if (yield == string) yield = string_copy(string);
6424 return yield;
6425 }
6426
6427
6428
6429 /*************************************************
6430 * Expand and interpret as an integer *
6431 *************************************************/
6432
6433 /* Expand a string, and convert the result into an integer.
6434
6435 Arguments:
6436 string the string to be expanded
6437 isplus TRUE if a non-negative number is expected
6438
6439 Returns: the integer value, or
6440 -1 for an expansion error ) in both cases, message in
6441 -2 for an integer interpretation error ) expand_string_message
6442 expand_string_message is set NULL for an OK integer
6443 */
6444
6445 int_eximarith_t
6446 expand_string_integer(uschar *string, BOOL isplus)
6447 {
6448 int_eximarith_t value;
6449 uschar *s = expand_string(string);
6450 uschar *msg = US"invalid integer \"%s\"";
6451 uschar *endptr;
6452
6453 /* If expansion failed, expand_string_message will be set. */
6454
6455 if (s == NULL) return -1;
6456
6457 /* On an overflow, strtol() returns LONG_MAX or LONG_MIN, and sets errno
6458 to ERANGE. When there isn't an overflow, errno is not changed, at least on some
6459 systems, so we set it zero ourselves. */
6460
6461 errno = 0;
6462 expand_string_message = NULL; /* Indicates no error */
6463
6464 /* Before Exim 4.64, strings consisting entirely of whitespace compared
6465 equal to 0. Unfortunately, people actually relied upon that, so preserve
6466 the behaviour explicitly. Stripping leading whitespace is a harmless
6467 noop change since strtol skips it anyway (provided that there is a number
6468 to find at all). */
6469 if (isspace(*s))
6470 {
6471 while (isspace(*s)) ++s;
6472 if (*s == '\0')
6473 {
6474 DEBUG(D_expand)
6475 debug_printf("treating blank string as number 0\n");
6476 return 0;
6477 }
6478 }
6479
6480 value = strtoll(CS s, CSS &endptr, 10);
6481
6482 if (endptr == s)
6483 {
6484 msg = US"integer expected but \"%s\" found";
6485 }
6486 else if (value < 0 && isplus)
6487 {
6488 msg = US"non-negative integer expected but \"%s\" found";
6489 }
6490 else
6491 {
6492 switch (tolower(*endptr))
6493 {
6494 default:
6495 break;
6496 case 'k':
6497 if (value > LLONG_MAX/1024 || value < LLONG_MIN/1024) errno = ERANGE;
6498 else value *= 1024;
6499 endptr++;
6500 break;
6501 case 'm':
6502 if (value > LLONG_MAX/(1024*1024) || value < LLONG_MIN/(1024*1024)) errno = ERANGE;
6503 else value *= 1024*1024;
6504 endptr++;
6505 break;
6506 case 'g':
6507 if (value > LLONG_MAX/(1024*1024*1024) || value < LLONG_MIN/(1024*1024*1024)) errno = ERANGE;
6508 else value *= 1024*1024*1024;
6509 endptr++;
6510 break;
6511 }
6512 if (errno == ERANGE)
6513 msg = US"absolute value of integer \"%s\" is too large (overflow)";
6514 else
6515 {
6516 while (isspace(*endptr)) endptr++;
6517 if (*endptr == 0) return (int)value;
6518 }
6519 }
6520
6521 expand_string_message = string_sprintf(CS msg, s);
6522 return -2;
6523 }
6524
6525
6526 /*************************************************
6527 **************************************************
6528 * Stand-alone test program *
6529 **************************************************
6530 *************************************************/
6531
6532 #ifdef STAND_ALONE
6533
6534
6535 BOOL
6536 regex_match_and_setup(const pcre *re, uschar *subject, int options, int setup)
6537 {
6538 int ovector[3*(EXPAND_MAXN+1)];
6539 int n = pcre_exec(re, NULL, subject, Ustrlen(subject), 0, PCRE_EOPT|options,
6540 ovector, sizeof(ovector)/sizeof(int));
6541 BOOL yield = n >= 0;
6542 if (n == 0) n = EXPAND_MAXN + 1;
6543 if (yield)
6544 {
6545 int nn;
6546 expand_nmax = (setup < 0)? 0 : setup + 1;
6547 for (nn = (setup < 0)? 0 : 2; nn < n*2; nn += 2)
6548 {
6549 expand_nstring[expand_nmax] = subject + ovector[nn];
6550 expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
6551 }
6552 expand_nmax--;
6553 }
6554 return yield;
6555 }
6556
6557
6558 int main(int argc, uschar **argv)
6559 {
6560 int i;
6561 uschar buffer[1024];
6562
6563 debug_selector = D_v;
6564 debug_file = stderr;
6565 debug_fd = fileno(debug_file);
6566 big_buffer = malloc(big_buffer_size);
6567
6568 for (i = 1; i < argc; i++)
6569 {
6570 if (argv[i][0] == '+')
6571 {
6572 debug_trace_memory = 2;
6573 argv[i]++;
6574 }
6575 if (isdigit(argv[i][0]))
6576 debug_selector = Ustrtol(argv[i], NULL, 0);
6577 else
6578 if (Ustrspn(argv[i], "abcdefghijklmnopqrtsuvwxyz0123456789-.:/") ==
6579 Ustrlen(argv[i]))
6580 {
6581 #ifdef LOOKUP_LDAP
6582 eldap_default_servers = argv[i];
6583 #endif
6584 #ifdef LOOKUP_MYSQL
6585 mysql_servers = argv[i];
6586 #endif
6587 #ifdef LOOKUP_PGSQL
6588 pgsql_servers = argv[i];
6589 #endif
6590 }
6591 #ifdef EXIM_PERL
6592 else opt_perl_startup = argv[i];
6593 #endif
6594 }
6595
6596 printf("Testing string expansion: debug_level = %d\n\n", debug_level);
6597
6598 expand_nstring[1] = US"string 1....";
6599 expand_nlength[1] = 8;
6600 expand_nmax = 1;
6601
6602 #ifdef EXIM_PERL
6603 if (opt_perl_startup != NULL)
6604 {
6605 uschar *errstr;
6606 printf("Starting Perl interpreter\n");
6607 errstr = init_perl(opt_perl_startup);
6608 if (errstr != NULL)
6609 {
6610 printf("** error in perl_startup code: %s\n", errstr);
6611 return EXIT_FAILURE;
6612 }
6613 }
6614 #endif /* EXIM_PERL */
6615
6616 while (fgets(buffer, sizeof(buffer), stdin) != NULL)
6617 {
6618 void *reset_point = store_get(0);
6619 uschar *yield = expand_string(buffer);
6620 if (yield != NULL)
6621 {
6622 printf("%s\n", yield);
6623 store_reset(reset_point);
6624 }
6625 else
6626 {
6627 if (search_find_defer) printf("search_find deferred\n");
6628 printf("Failed: %s\n", expand_string_message);
6629 if (expand_string_forcedfail) printf("Forced failure\n");
6630 printf("\n");
6631 }
6632 }
6633
6634 search_tidyup();
6635
6636 return 0;
6637 }
6638
6639 #endif
6640
6641 /* End of expand.c */