Fix ${listextract } from a tainted list
[exim.git] / src / src / expand.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
6 /* Copyright (c) The Exim Maintainers 2020 */
7 /* See the file NOTICE for conditions of use and distribution. */
8
9
10 /* Functions for handling string expansion. */
11
12
13 #include "exim.h"
14
15 /* Recursively called function */
16
17 static uschar *expand_string_internal(const uschar *, BOOL, const uschar **, BOOL, BOOL, BOOL *);
18 static int_eximarith_t expanded_string_integer(const uschar *, BOOL);
19
20 #ifdef STAND_ALONE
21 # ifndef SUPPORT_CRYPTEQ
22 #  define SUPPORT_CRYPTEQ
23 # endif
24 #endif
25
26 #ifdef LOOKUP_LDAP
27 # include "lookups/ldap.h"
28 #endif
29
30 #ifdef SUPPORT_CRYPTEQ
31 # ifdef CRYPT_H
32 #  include <crypt.h>
33 # endif
34 # ifndef HAVE_CRYPT16
35 extern char* crypt16(char*, char*);
36 # endif
37 #endif
38
39 /* The handling of crypt16() is a mess. I will record below the analysis of the
40 mess that was sent to me. We decided, however, to make changing this very low
41 priority, because in practice people are moving away from the crypt()
42 algorithms nowadays, so it doesn't seem worth it.
43
44 <quote>
45 There is an algorithm named "crypt16" in Ultrix and Tru64.  It crypts
46 the first 8 characters of the password using a 20-round version of crypt
47 (standard crypt does 25 rounds).  It then crypts the next 8 characters,
48 or an empty block if the password is less than 9 characters, using a
49 20-round version of crypt and the same salt as was used for the first
50 block.  Characters after the first 16 are ignored.  It always generates
51 a 16-byte hash, which is expressed together with the salt as a string
52 of 24 base 64 digits.  Here are some links to peruse:
53
54         http://cvs.pld.org.pl/pam/pamcrypt/crypt16.c?rev=1.2
55         http://seclists.org/bugtraq/1999/Mar/0076.html
56
57 There's a different algorithm named "bigcrypt" in HP-UX, Digital Unix,
58 and OSF/1.  This is the same as the standard crypt if given a password
59 of 8 characters or less.  If given more, it first does the same as crypt
60 using the first 8 characters, then crypts the next 8 (the 9th to 16th)
61 using as salt the first two base 64 digits from the first hash block.
62 If the password is more than 16 characters then it crypts the 17th to 24th
63 characters using as salt the first two base 64 digits from the second hash
64 block.  And so on: I've seen references to it cutting off the password at
65 40 characters (5 blocks), 80 (10 blocks), or 128 (16 blocks).  Some links:
66
67         http://cvs.pld.org.pl/pam/pamcrypt/bigcrypt.c?rev=1.2
68         http://seclists.org/bugtraq/1999/Mar/0109.html
69         http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-Q0R2D-
70              TET1_html/sec.c222.html#no_id_208
71
72 Exim has something it calls "crypt16".  It will either use a native
73 crypt16 or its own implementation.  A native crypt16 will presumably
74 be the one that I called "crypt16" above.  The internal "crypt16"
75 function, however, is a two-block-maximum implementation of what I called
76 "bigcrypt".  The documentation matches the internal code.
77
78 I suspect that whoever did the "crypt16" stuff for Exim didn't realise
79 that crypt16 and bigcrypt were different things.
80
81 Exim uses the LDAP-style scheme identifier "{crypt16}" to refer
82 to whatever it is using under that name.  This unfortunately sets a
83 precedent for using "{crypt16}" to identify two incompatible algorithms
84 whose output can't be distinguished.  With "{crypt16}" thus rendered
85 ambiguous, I suggest you deprecate it and invent two new identifiers
86 for the two algorithms.
87
88 Both crypt16 and bigcrypt are very poor algorithms, btw.  Hashing parts
89 of the password separately means they can be cracked separately, so
90 the double-length hash only doubles the cracking effort instead of
91 squaring it.  I recommend salted SHA-1 ({SSHA}), or the Blowfish-based
92 bcrypt ({CRYPT}$2a$).
93 </quote>
94 */
95
96
97
98 /*************************************************
99 *            Local statics and tables            *
100 *************************************************/
101
102 /* Table of item names, and corresponding switch numbers. The names must be in
103 alphabetical order. */
104
105 static uschar *item_table[] = {
106   US"acl",
107   US"authresults",
108   US"certextract",
109   US"dlfunc",
110   US"env",
111   US"extract",
112   US"filter",
113   US"hash",
114   US"hmac",
115   US"if",
116 #ifdef SUPPORT_I18N
117   US"imapfolder",
118 #endif
119   US"length",
120   US"listextract",
121   US"listquote",
122   US"lookup",
123   US"map",
124   US"nhash",
125   US"perl",
126   US"prvs",
127   US"prvscheck",
128   US"readfile",
129   US"readsocket",
130   US"reduce",
131   US"run",
132   US"sg",
133   US"sort",
134 #ifdef SUPPORT_SRS
135   US"srs_encode",
136 #endif
137   US"substr",
138   US"tr" };
139
140 enum {
141   EITEM_ACL,
142   EITEM_AUTHRESULTS,
143   EITEM_CERTEXTRACT,
144   EITEM_DLFUNC,
145   EITEM_ENV,
146   EITEM_EXTRACT,
147   EITEM_FILTER,
148   EITEM_HASH,
149   EITEM_HMAC,
150   EITEM_IF,
151 #ifdef SUPPORT_I18N
152   EITEM_IMAPFOLDER,
153 #endif
154   EITEM_LENGTH,
155   EITEM_LISTEXTRACT,
156   EITEM_LISTQUOTE,
157   EITEM_LOOKUP,
158   EITEM_MAP,
159   EITEM_NHASH,
160   EITEM_PERL,
161   EITEM_PRVS,
162   EITEM_PRVSCHECK,
163   EITEM_READFILE,
164   EITEM_READSOCK,
165   EITEM_REDUCE,
166   EITEM_RUN,
167   EITEM_SG,
168   EITEM_SORT,
169 #ifdef SUPPORT_SRS
170   EITEM_SRS_ENCODE,
171 #endif
172   EITEM_SUBSTR,
173   EITEM_TR };
174
175 /* Tables of operator names, and corresponding switch numbers. The names must be
176 in alphabetical order. There are two tables, because underscore is used in some
177 cases to introduce arguments, whereas for other it is part of the name. This is
178 an historical mis-design. */
179
180 static uschar *op_table_underscore[] = {
181   US"from_utf8",
182   US"local_part",
183   US"quote_local_part",
184   US"reverse_ip",
185   US"time_eval",
186   US"time_interval"
187 #ifdef SUPPORT_I18N
188  ,US"utf8_domain_from_alabel",
189   US"utf8_domain_to_alabel",
190   US"utf8_localpart_from_alabel",
191   US"utf8_localpart_to_alabel"
192 #endif
193   };
194
195 enum {
196   EOP_FROM_UTF8,
197   EOP_LOCAL_PART,
198   EOP_QUOTE_LOCAL_PART,
199   EOP_REVERSE_IP,
200   EOP_TIME_EVAL,
201   EOP_TIME_INTERVAL
202 #ifdef SUPPORT_I18N
203  ,EOP_UTF8_DOMAIN_FROM_ALABEL,
204   EOP_UTF8_DOMAIN_TO_ALABEL,
205   EOP_UTF8_LOCALPART_FROM_ALABEL,
206   EOP_UTF8_LOCALPART_TO_ALABEL
207 #endif
208   };
209
210 static uschar *op_table_main[] = {
211   US"address",
212   US"addresses",
213   US"base32",
214   US"base32d",
215   US"base62",
216   US"base62d",
217   US"base64",
218   US"base64d",
219   US"bless",
220   US"domain",
221   US"escape",
222   US"escape8bit",
223   US"eval",
224   US"eval10",
225   US"expand",
226   US"h",
227   US"hash",
228   US"hex2b64",
229   US"hexquote",
230   US"ipv6denorm",
231   US"ipv6norm",
232   US"l",
233   US"lc",
234   US"length",
235   US"listcount",
236   US"listnamed",
237   US"mask",
238   US"md5",
239   US"nh",
240   US"nhash",
241   US"quote",
242   US"randint",
243   US"rfc2047",
244   US"rfc2047d",
245   US"rxquote",
246   US"s",
247   US"sha1",
248   US"sha2",
249   US"sha256",
250   US"sha3",
251   US"stat",
252   US"str2b64",
253   US"strlen",
254   US"substr",
255   US"uc",
256   US"utf8clean" };
257
258 enum {
259   EOP_ADDRESS =  nelem(op_table_underscore),
260   EOP_ADDRESSES,
261   EOP_BASE32,
262   EOP_BASE32D,
263   EOP_BASE62,
264   EOP_BASE62D,
265   EOP_BASE64,
266   EOP_BASE64D,
267   EOP_BLESS,
268   EOP_DOMAIN,
269   EOP_ESCAPE,
270   EOP_ESCAPE8BIT,
271   EOP_EVAL,
272   EOP_EVAL10,
273   EOP_EXPAND,
274   EOP_H,
275   EOP_HASH,
276   EOP_HEX2B64,
277   EOP_HEXQUOTE,
278   EOP_IPV6DENORM,
279   EOP_IPV6NORM,
280   EOP_L,
281   EOP_LC,
282   EOP_LENGTH,
283   EOP_LISTCOUNT,
284   EOP_LISTNAMED,
285   EOP_MASK,
286   EOP_MD5,
287   EOP_NH,
288   EOP_NHASH,
289   EOP_QUOTE,
290   EOP_RANDINT,
291   EOP_RFC2047,
292   EOP_RFC2047D,
293   EOP_RXQUOTE,
294   EOP_S,
295   EOP_SHA1,
296   EOP_SHA2,
297   EOP_SHA256,
298   EOP_SHA3,
299   EOP_STAT,
300   EOP_STR2B64,
301   EOP_STRLEN,
302   EOP_SUBSTR,
303   EOP_UC,
304   EOP_UTF8CLEAN };
305
306
307 /* Table of condition names, and corresponding switch numbers. The names must
308 be in alphabetical order. */
309
310 static uschar *cond_table[] = {
311   US"<",
312   US"<=",
313   US"=",
314   US"==",     /* Backward compatibility */
315   US">",
316   US">=",
317   US"acl",
318   US"and",
319   US"bool",
320   US"bool_lax",
321   US"crypteq",
322   US"def",
323   US"eq",
324   US"eqi",
325   US"exists",
326   US"first_delivery",
327   US"forall",
328   US"forall_json",
329   US"forall_jsons",
330   US"forany",
331   US"forany_json",
332   US"forany_jsons",
333   US"ge",
334   US"gei",
335   US"gt",
336   US"gti",
337 #ifdef SUPPORT_SRS
338   US"inbound_srs",
339 #endif
340   US"inlist",
341   US"inlisti",
342   US"isip",
343   US"isip4",
344   US"isip6",
345   US"ldapauth",
346   US"le",
347   US"lei",
348   US"lt",
349   US"lti",
350   US"match",
351   US"match_address",
352   US"match_domain",
353   US"match_ip",
354   US"match_local_part",
355   US"or",
356   US"pam",
357   US"pwcheck",
358   US"queue_running",
359   US"radius",
360   US"saslauthd"
361 };
362
363 enum {
364   ECOND_NUM_L,
365   ECOND_NUM_LE,
366   ECOND_NUM_E,
367   ECOND_NUM_EE,
368   ECOND_NUM_G,
369   ECOND_NUM_GE,
370   ECOND_ACL,
371   ECOND_AND,
372   ECOND_BOOL,
373   ECOND_BOOL_LAX,
374   ECOND_CRYPTEQ,
375   ECOND_DEF,
376   ECOND_STR_EQ,
377   ECOND_STR_EQI,
378   ECOND_EXISTS,
379   ECOND_FIRST_DELIVERY,
380   ECOND_FORALL,
381   ECOND_FORALL_JSON,
382   ECOND_FORALL_JSONS,
383   ECOND_FORANY,
384   ECOND_FORANY_JSON,
385   ECOND_FORANY_JSONS,
386   ECOND_STR_GE,
387   ECOND_STR_GEI,
388   ECOND_STR_GT,
389   ECOND_STR_GTI,
390 #ifdef SUPPORT_SRS
391   ECOND_INBOUND_SRS,
392 #endif
393   ECOND_INLIST,
394   ECOND_INLISTI,
395   ECOND_ISIP,
396   ECOND_ISIP4,
397   ECOND_ISIP6,
398   ECOND_LDAPAUTH,
399   ECOND_STR_LE,
400   ECOND_STR_LEI,
401   ECOND_STR_LT,
402   ECOND_STR_LTI,
403   ECOND_MATCH,
404   ECOND_MATCH_ADDRESS,
405   ECOND_MATCH_DOMAIN,
406   ECOND_MATCH_IP,
407   ECOND_MATCH_LOCAL_PART,
408   ECOND_OR,
409   ECOND_PAM,
410   ECOND_PWCHECK,
411   ECOND_QUEUE_RUNNING,
412   ECOND_RADIUS,
413   ECOND_SASLAUTHD
414 };
415
416
417 /* Types of table entry */
418
419 enum vtypes {
420   vtype_int,            /* value is address of int */
421   vtype_filter_int,     /* ditto, but recognized only when filtering */
422   vtype_ino,            /* value is address of ino_t (not always an int) */
423   vtype_uid,            /* value is address of uid_t (not always an int) */
424   vtype_gid,            /* value is address of gid_t (not always an int) */
425   vtype_bool,           /* value is address of bool */
426   vtype_stringptr,      /* value is address of pointer to string */
427   vtype_msgbody,        /* as stringptr, but read when first required */
428   vtype_msgbody_end,    /* ditto, the end of the message */
429   vtype_msgheaders,     /* the message's headers, processed */
430   vtype_msgheaders_raw, /* the message's headers, unprocessed */
431   vtype_localpart,      /* extract local part from string */
432   vtype_domain,         /* extract domain from string */
433   vtype_string_func,    /* value is string returned by given function */
434   vtype_todbsdin,       /* value not used; generate BSD inbox tod */
435   vtype_tode,           /* value not used; generate tod in epoch format */
436   vtype_todel,          /* value not used; generate tod in epoch/usec format */
437   vtype_todf,           /* value not used; generate full tod */
438   vtype_todl,           /* value not used; generate log tod */
439   vtype_todlf,          /* value not used; generate log file datestamp tod */
440   vtype_todzone,        /* value not used; generate time zone only */
441   vtype_todzulu,        /* value not used; generate zulu tod */
442   vtype_reply,          /* value not used; get reply from headers */
443   vtype_pid,            /* value not used; result is pid */
444   vtype_host_lookup,    /* value not used; get host name */
445   vtype_load_avg,       /* value not used; result is int from os_getloadavg */
446   vtype_pspace,         /* partition space; value is T/F for spool/log */
447   vtype_pinodes,        /* partition inodes; value is T/F for spool/log */
448   vtype_cert            /* SSL certificate */
449   #ifndef DISABLE_DKIM
450   ,vtype_dkim           /* Lookup of value in DKIM signature */
451   #endif
452 };
453
454 /* Type for main variable table */
455
456 typedef struct {
457   const char *name;
458   enum vtypes type;
459   void       *value;
460 } var_entry;
461
462 /* Type for entries pointing to address/length pairs. Not currently
463 in use. */
464
465 typedef struct {
466   uschar **address;
467   int  *length;
468 } alblock;
469
470 static uschar * fn_recipients(void);
471 typedef uschar * stringptr_fn_t(void);
472 static uschar * fn_queue_size(void);
473
474 /* This table must be kept in alphabetical order. */
475
476 static var_entry var_table[] = {
477   /* WARNING: Do not invent variables whose names start acl_c or acl_m because
478      they will be confused with user-creatable ACL variables. */
479   { "acl_arg1",            vtype_stringptr,   &acl_arg[0] },
480   { "acl_arg2",            vtype_stringptr,   &acl_arg[1] },
481   { "acl_arg3",            vtype_stringptr,   &acl_arg[2] },
482   { "acl_arg4",            vtype_stringptr,   &acl_arg[3] },
483   { "acl_arg5",            vtype_stringptr,   &acl_arg[4] },
484   { "acl_arg6",            vtype_stringptr,   &acl_arg[5] },
485   { "acl_arg7",            vtype_stringptr,   &acl_arg[6] },
486   { "acl_arg8",            vtype_stringptr,   &acl_arg[7] },
487   { "acl_arg9",            vtype_stringptr,   &acl_arg[8] },
488   { "acl_narg",            vtype_int,         &acl_narg },
489   { "acl_verify_message",  vtype_stringptr,   &acl_verify_message },
490   { "address_data",        vtype_stringptr,   &deliver_address_data },
491   { "address_file",        vtype_stringptr,   &address_file },
492   { "address_pipe",        vtype_stringptr,   &address_pipe },
493 #ifdef EXPERIMENTAL_ARC
494   { "arc_domains",         vtype_string_func, (void *) &fn_arc_domains },
495   { "arc_oldest_pass",     vtype_int,         &arc_oldest_pass },
496   { "arc_state",           vtype_stringptr,   &arc_state },
497   { "arc_state_reason",    vtype_stringptr,   &arc_state_reason },
498 #endif
499   { "authenticated_fail_id",vtype_stringptr,  &authenticated_fail_id },
500   { "authenticated_id",    vtype_stringptr,   &authenticated_id },
501   { "authenticated_sender",vtype_stringptr,   &authenticated_sender },
502   { "authentication_failed",vtype_int,        &authentication_failed },
503 #ifdef WITH_CONTENT_SCAN
504   { "av_failed",           vtype_int,         &av_failed },
505 #endif
506 #ifdef EXPERIMENTAL_BRIGHTMAIL
507   { "bmi_alt_location",    vtype_stringptr,   &bmi_alt_location },
508   { "bmi_base64_tracker_verdict", vtype_stringptr, &bmi_base64_tracker_verdict },
509   { "bmi_base64_verdict",  vtype_stringptr,   &bmi_base64_verdict },
510   { "bmi_deliver",         vtype_int,         &bmi_deliver },
511 #endif
512   { "body_linecount",      vtype_int,         &body_linecount },
513   { "body_zerocount",      vtype_int,         &body_zerocount },
514   { "bounce_recipient",    vtype_stringptr,   &bounce_recipient },
515   { "bounce_return_size_limit", vtype_int,    &bounce_return_size_limit },
516   { "caller_gid",          vtype_gid,         &real_gid },
517   { "caller_uid",          vtype_uid,         &real_uid },
518   { "callout_address",     vtype_stringptr,   &callout_address },
519   { "compile_date",        vtype_stringptr,   &version_date },
520   { "compile_number",      vtype_stringptr,   &version_cnumber },
521   { "config_dir",          vtype_stringptr,   &config_main_directory },
522   { "config_file",         vtype_stringptr,   &config_main_filename },
523   { "csa_status",          vtype_stringptr,   &csa_status },
524 #ifdef EXPERIMENTAL_DCC
525   { "dcc_header",          vtype_stringptr,   &dcc_header },
526   { "dcc_result",          vtype_stringptr,   &dcc_result },
527 #endif
528 #ifndef DISABLE_DKIM
529   { "dkim_algo",           vtype_dkim,        (void *)DKIM_ALGO },
530   { "dkim_bodylength",     vtype_dkim,        (void *)DKIM_BODYLENGTH },
531   { "dkim_canon_body",     vtype_dkim,        (void *)DKIM_CANON_BODY },
532   { "dkim_canon_headers",  vtype_dkim,        (void *)DKIM_CANON_HEADERS },
533   { "dkim_copiedheaders",  vtype_dkim,        (void *)DKIM_COPIEDHEADERS },
534   { "dkim_created",        vtype_dkim,        (void *)DKIM_CREATED },
535   { "dkim_cur_signer",     vtype_stringptr,   &dkim_cur_signer },
536   { "dkim_domain",         vtype_stringptr,   &dkim_signing_domain },
537   { "dkim_expires",        vtype_dkim,        (void *)DKIM_EXPIRES },
538   { "dkim_headernames",    vtype_dkim,        (void *)DKIM_HEADERNAMES },
539   { "dkim_identity",       vtype_dkim,        (void *)DKIM_IDENTITY },
540   { "dkim_key_granularity",vtype_dkim,        (void *)DKIM_KEY_GRANULARITY },
541   { "dkim_key_length",     vtype_int,         &dkim_key_length },
542   { "dkim_key_nosubdomains",vtype_dkim,       (void *)DKIM_NOSUBDOMAINS },
543   { "dkim_key_notes",      vtype_dkim,        (void *)DKIM_KEY_NOTES },
544   { "dkim_key_srvtype",    vtype_dkim,        (void *)DKIM_KEY_SRVTYPE },
545   { "dkim_key_testing",    vtype_dkim,        (void *)DKIM_KEY_TESTING },
546   { "dkim_selector",       vtype_stringptr,   &dkim_signing_selector },
547   { "dkim_signers",        vtype_stringptr,   &dkim_signers },
548   { "dkim_verify_reason",  vtype_stringptr,   &dkim_verify_reason },
549   { "dkim_verify_status",  vtype_stringptr,   &dkim_verify_status },
550 #endif
551 #ifdef SUPPORT_DMARC
552   { "dmarc_domain_policy", vtype_stringptr,   &dmarc_domain_policy },
553   { "dmarc_status",        vtype_stringptr,   &dmarc_status },
554   { "dmarc_status_text",   vtype_stringptr,   &dmarc_status_text },
555   { "dmarc_used_domain",   vtype_stringptr,   &dmarc_used_domain },
556 #endif
557   { "dnslist_domain",      vtype_stringptr,   &dnslist_domain },
558   { "dnslist_matched",     vtype_stringptr,   &dnslist_matched },
559   { "dnslist_text",        vtype_stringptr,   &dnslist_text },
560   { "dnslist_value",       vtype_stringptr,   &dnslist_value },
561   { "domain",              vtype_stringptr,   &deliver_domain },
562   { "domain_data",         vtype_stringptr,   &deliver_domain_data },
563 #ifndef DISABLE_EVENT
564   { "event_data",          vtype_stringptr,   &event_data },
565
566   /*XXX want to use generic vars for as many of these as possible*/
567   { "event_defer_errno",   vtype_int,         &event_defer_errno },
568
569   { "event_name",          vtype_stringptr,   &event_name },
570 #endif
571   { "exim_gid",            vtype_gid,         &exim_gid },
572   { "exim_path",           vtype_stringptr,   &exim_path },
573   { "exim_uid",            vtype_uid,         &exim_uid },
574   { "exim_version",        vtype_stringptr,   &version_string },
575   { "headers_added",       vtype_string_func, (void *) &fn_hdrs_added },
576   { "home",                vtype_stringptr,   &deliver_home },
577   { "host",                vtype_stringptr,   &deliver_host },
578   { "host_address",        vtype_stringptr,   &deliver_host_address },
579   { "host_data",           vtype_stringptr,   &host_data },
580   { "host_lookup_deferred",vtype_int,         &host_lookup_deferred },
581   { "host_lookup_failed",  vtype_int,         &host_lookup_failed },
582   { "host_port",           vtype_int,         &deliver_host_port },
583   { "initial_cwd",         vtype_stringptr,   &initial_cwd },
584   { "inode",               vtype_ino,         &deliver_inode },
585   { "interface_address",   vtype_stringptr,   &interface_address },
586   { "interface_port",      vtype_int,         &interface_port },
587   { "item",                vtype_stringptr,   &iterate_item },
588   #ifdef LOOKUP_LDAP
589   { "ldap_dn",             vtype_stringptr,   &eldap_dn },
590   #endif
591   { "load_average",        vtype_load_avg,    NULL },
592   { "local_part",          vtype_stringptr,   &deliver_localpart },
593   { "local_part_data",     vtype_stringptr,   &deliver_localpart_data },
594   { "local_part_prefix",   vtype_stringptr,   &deliver_localpart_prefix },
595   { "local_part_prefix_v", vtype_stringptr,   &deliver_localpart_prefix_v },
596   { "local_part_suffix",   vtype_stringptr,   &deliver_localpart_suffix },
597   { "local_part_suffix_v", vtype_stringptr,   &deliver_localpart_suffix_v },
598 #ifdef HAVE_LOCAL_SCAN
599   { "local_scan_data",     vtype_stringptr,   &local_scan_data },
600 #endif
601   { "local_user_gid",      vtype_gid,         &local_user_gid },
602   { "local_user_uid",      vtype_uid,         &local_user_uid },
603   { "localhost_number",    vtype_int,         &host_number },
604   { "log_inodes",          vtype_pinodes,     (void *)FALSE },
605   { "log_space",           vtype_pspace,      (void *)FALSE },
606   { "lookup_dnssec_authenticated",vtype_stringptr,&lookup_dnssec_authenticated},
607   { "mailstore_basename",  vtype_stringptr,   &mailstore_basename },
608 #ifdef WITH_CONTENT_SCAN
609   { "malware_name",        vtype_stringptr,   &malware_name },
610 #endif
611   { "max_received_linelength", vtype_int,     &max_received_linelength },
612   { "message_age",         vtype_int,         &message_age },
613   { "message_body",        vtype_msgbody,     &message_body },
614   { "message_body_end",    vtype_msgbody_end, &message_body_end },
615   { "message_body_size",   vtype_int,         &message_body_size },
616   { "message_exim_id",     vtype_stringptr,   &message_id },
617   { "message_headers",     vtype_msgheaders,  NULL },
618   { "message_headers_raw", vtype_msgheaders_raw, NULL },
619   { "message_id",          vtype_stringptr,   &message_id },
620   { "message_linecount",   vtype_int,         &message_linecount },
621   { "message_size",        vtype_int,         &message_size },
622 #ifdef SUPPORT_I18N
623   { "message_smtputf8",    vtype_bool,        &message_smtputf8 },
624 #endif
625 #ifdef WITH_CONTENT_SCAN
626   { "mime_anomaly_level",  vtype_int,         &mime_anomaly_level },
627   { "mime_anomaly_text",   vtype_stringptr,   &mime_anomaly_text },
628   { "mime_boundary",       vtype_stringptr,   &mime_boundary },
629   { "mime_charset",        vtype_stringptr,   &mime_charset },
630   { "mime_content_description", vtype_stringptr, &mime_content_description },
631   { "mime_content_disposition", vtype_stringptr, &mime_content_disposition },
632   { "mime_content_id",     vtype_stringptr,   &mime_content_id },
633   { "mime_content_size",   vtype_int,         &mime_content_size },
634   { "mime_content_transfer_encoding",vtype_stringptr, &mime_content_transfer_encoding },
635   { "mime_content_type",   vtype_stringptr,   &mime_content_type },
636   { "mime_decoded_filename", vtype_stringptr, &mime_decoded_filename },
637   { "mime_filename",       vtype_stringptr,   &mime_filename },
638   { "mime_is_coverletter", vtype_int,         &mime_is_coverletter },
639   { "mime_is_multipart",   vtype_int,         &mime_is_multipart },
640   { "mime_is_rfc822",      vtype_int,         &mime_is_rfc822 },
641   { "mime_part_count",     vtype_int,         &mime_part_count },
642 #endif
643   { "n0",                  vtype_filter_int,  &filter_n[0] },
644   { "n1",                  vtype_filter_int,  &filter_n[1] },
645   { "n2",                  vtype_filter_int,  &filter_n[2] },
646   { "n3",                  vtype_filter_int,  &filter_n[3] },
647   { "n4",                  vtype_filter_int,  &filter_n[4] },
648   { "n5",                  vtype_filter_int,  &filter_n[5] },
649   { "n6",                  vtype_filter_int,  &filter_n[6] },
650   { "n7",                  vtype_filter_int,  &filter_n[7] },
651   { "n8",                  vtype_filter_int,  &filter_n[8] },
652   { "n9",                  vtype_filter_int,  &filter_n[9] },
653   { "original_domain",     vtype_stringptr,   &deliver_domain_orig },
654   { "original_local_part", vtype_stringptr,   &deliver_localpart_orig },
655   { "originator_gid",      vtype_gid,         &originator_gid },
656   { "originator_uid",      vtype_uid,         &originator_uid },
657   { "parent_domain",       vtype_stringptr,   &deliver_domain_parent },
658   { "parent_local_part",   vtype_stringptr,   &deliver_localpart_parent },
659   { "pid",                 vtype_pid,         NULL },
660 #ifndef DISABLE_PRDR
661   { "prdr_requested",      vtype_bool,        &prdr_requested },
662 #endif
663   { "primary_hostname",    vtype_stringptr,   &primary_hostname },
664 #if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS)
665   { "proxy_external_address",vtype_stringptr, &proxy_external_address },
666   { "proxy_external_port", vtype_int,         &proxy_external_port },
667   { "proxy_local_address", vtype_stringptr,   &proxy_local_address },
668   { "proxy_local_port",    vtype_int,         &proxy_local_port },
669   { "proxy_session",       vtype_bool,        &proxy_session },
670 #endif
671   { "prvscheck_address",   vtype_stringptr,   &prvscheck_address },
672   { "prvscheck_keynum",    vtype_stringptr,   &prvscheck_keynum },
673   { "prvscheck_result",    vtype_stringptr,   &prvscheck_result },
674   { "qualify_domain",      vtype_stringptr,   &qualify_domain_sender },
675   { "qualify_recipient",   vtype_stringptr,   &qualify_domain_recipient },
676   { "queue_name",          vtype_stringptr,   &queue_name },
677   { "queue_size",          vtype_string_func, &fn_queue_size },
678   { "rcpt_count",          vtype_int,         &rcpt_count },
679   { "rcpt_defer_count",    vtype_int,         &rcpt_defer_count },
680   { "rcpt_fail_count",     vtype_int,         &rcpt_fail_count },
681   { "received_count",      vtype_int,         &received_count },
682   { "received_for",        vtype_stringptr,   &received_for },
683   { "received_ip_address", vtype_stringptr,   &interface_address },
684   { "received_port",       vtype_int,         &interface_port },
685   { "received_protocol",   vtype_stringptr,   &received_protocol },
686   { "received_time",       vtype_int,         &received_time.tv_sec },
687   { "recipient_data",      vtype_stringptr,   &recipient_data },
688   { "recipient_verify_failure",vtype_stringptr,&recipient_verify_failure },
689   { "recipients",          vtype_string_func, (void *) &fn_recipients },
690   { "recipients_count",    vtype_int,         &recipients_count },
691 #ifdef WITH_CONTENT_SCAN
692   { "regex_match_string",  vtype_stringptr,   &regex_match_string },
693 #endif
694   { "reply_address",       vtype_reply,       NULL },
695   { "return_path",         vtype_stringptr,   &return_path },
696   { "return_size_limit",   vtype_int,         &bounce_return_size_limit },
697   { "router_name",         vtype_stringptr,   &router_name },
698   { "runrc",               vtype_int,         &runrc },
699   { "self_hostname",       vtype_stringptr,   &self_hostname },
700   { "sender_address",      vtype_stringptr,   &sender_address },
701   { "sender_address_data", vtype_stringptr,   &sender_address_data },
702   { "sender_address_domain", vtype_domain,    &sender_address },
703   { "sender_address_local_part", vtype_localpart, &sender_address },
704   { "sender_data",         vtype_stringptr,   &sender_data },
705   { "sender_fullhost",     vtype_stringptr,   &sender_fullhost },
706   { "sender_helo_dnssec",  vtype_bool,        &sender_helo_dnssec },
707   { "sender_helo_name",    vtype_stringptr,   &sender_helo_name },
708   { "sender_host_address", vtype_stringptr,   &sender_host_address },
709   { "sender_host_authenticated",vtype_stringptr, &sender_host_authenticated },
710   { "sender_host_dnssec",  vtype_bool,        &sender_host_dnssec },
711   { "sender_host_name",    vtype_host_lookup, NULL },
712   { "sender_host_port",    vtype_int,         &sender_host_port },
713   { "sender_ident",        vtype_stringptr,   &sender_ident },
714   { "sender_rate",         vtype_stringptr,   &sender_rate },
715   { "sender_rate_limit",   vtype_stringptr,   &sender_rate_limit },
716   { "sender_rate_period",  vtype_stringptr,   &sender_rate_period },
717   { "sender_rcvhost",      vtype_stringptr,   &sender_rcvhost },
718   { "sender_verify_failure",vtype_stringptr,  &sender_verify_failure },
719   { "sending_ip_address",  vtype_stringptr,   &sending_ip_address },
720   { "sending_port",        vtype_int,         &sending_port },
721   { "smtp_active_hostname", vtype_stringptr,  &smtp_active_hostname },
722   { "smtp_command",        vtype_stringptr,   &smtp_cmd_buffer },
723   { "smtp_command_argument", vtype_stringptr, &smtp_cmd_argument },
724   { "smtp_command_history", vtype_string_func, (void *) &smtp_cmd_hist },
725   { "smtp_count_at_connection_start", vtype_int, &smtp_accept_count },
726   { "smtp_notquit_reason", vtype_stringptr,   &smtp_notquit_reason },
727   { "sn0",                 vtype_filter_int,  &filter_sn[0] },
728   { "sn1",                 vtype_filter_int,  &filter_sn[1] },
729   { "sn2",                 vtype_filter_int,  &filter_sn[2] },
730   { "sn3",                 vtype_filter_int,  &filter_sn[3] },
731   { "sn4",                 vtype_filter_int,  &filter_sn[4] },
732   { "sn5",                 vtype_filter_int,  &filter_sn[5] },
733   { "sn6",                 vtype_filter_int,  &filter_sn[6] },
734   { "sn7",                 vtype_filter_int,  &filter_sn[7] },
735   { "sn8",                 vtype_filter_int,  &filter_sn[8] },
736   { "sn9",                 vtype_filter_int,  &filter_sn[9] },
737 #ifdef WITH_CONTENT_SCAN
738   { "spam_action",         vtype_stringptr,   &spam_action },
739   { "spam_bar",            vtype_stringptr,   &spam_bar },
740   { "spam_report",         vtype_stringptr,   &spam_report },
741   { "spam_score",          vtype_stringptr,   &spam_score },
742   { "spam_score_int",      vtype_stringptr,   &spam_score_int },
743 #endif
744 #ifdef SUPPORT_SPF
745   { "spf_guess",           vtype_stringptr,   &spf_guess },
746   { "spf_header_comment",  vtype_stringptr,   &spf_header_comment },
747   { "spf_received",        vtype_stringptr,   &spf_received },
748   { "spf_result",          vtype_stringptr,   &spf_result },
749   { "spf_result_guessed",  vtype_bool,        &spf_result_guessed },
750   { "spf_smtp_comment",    vtype_stringptr,   &spf_smtp_comment },
751 #endif
752   { "spool_directory",     vtype_stringptr,   &spool_directory },
753   { "spool_inodes",        vtype_pinodes,     (void *)TRUE },
754   { "spool_space",         vtype_pspace,      (void *)TRUE },
755 #ifdef EXPERIMENTAL_SRS_ALT
756   { "srs_db_address",      vtype_stringptr,   &srs_db_address },
757   { "srs_db_key",          vtype_stringptr,   &srs_db_key },
758   { "srs_orig_recipient",  vtype_stringptr,   &srs_orig_recipient },
759   { "srs_orig_sender",     vtype_stringptr,   &srs_orig_sender },
760 #endif
761 #if defined(EXPERIMENTAL_SRS_ALT) || defined(SUPPORT_SRS)
762   { "srs_recipient",       vtype_stringptr,   &srs_recipient },
763 #endif
764 #ifdef EXPERIMENTAL_SRS_ALT
765   { "srs_status",          vtype_stringptr,   &srs_status },
766 #endif
767   { "thisaddress",         vtype_stringptr,   &filter_thisaddress },
768
769   /* The non-(in,out) variables are now deprecated */
770   { "tls_bits",            vtype_int,         &tls_in.bits },
771   { "tls_certificate_verified", vtype_int,    &tls_in.certificate_verified },
772   { "tls_cipher",          vtype_stringptr,   &tls_in.cipher },
773
774   { "tls_in_bits",         vtype_int,         &tls_in.bits },
775   { "tls_in_certificate_verified", vtype_int, &tls_in.certificate_verified },
776   { "tls_in_cipher",       vtype_stringptr,   &tls_in.cipher },
777   { "tls_in_cipher_std",   vtype_stringptr,   &tls_in.cipher_stdname },
778   { "tls_in_ocsp",         vtype_int,         &tls_in.ocsp },
779   { "tls_in_ourcert",      vtype_cert,        &tls_in.ourcert },
780   { "tls_in_peercert",     vtype_cert,        &tls_in.peercert },
781   { "tls_in_peerdn",       vtype_stringptr,   &tls_in.peerdn },
782 #ifndef DISABLE_TLS_RESUME
783   { "tls_in_resumption",   vtype_int,         &tls_in.resumption },
784 #endif
785 #ifndef DISABLE_TLS
786   { "tls_in_sni",          vtype_stringptr,   &tls_in.sni },
787 #endif
788   { "tls_in_ver",          vtype_stringptr,   &tls_in.ver },
789   { "tls_out_bits",        vtype_int,         &tls_out.bits },
790   { "tls_out_certificate_verified", vtype_int,&tls_out.certificate_verified },
791   { "tls_out_cipher",      vtype_stringptr,   &tls_out.cipher },
792   { "tls_out_cipher_std",  vtype_stringptr,   &tls_out.cipher_stdname },
793 #ifdef SUPPORT_DANE
794   { "tls_out_dane",        vtype_bool,        &tls_out.dane_verified },
795 #endif
796   { "tls_out_ocsp",        vtype_int,         &tls_out.ocsp },
797   { "tls_out_ourcert",     vtype_cert,        &tls_out.ourcert },
798   { "tls_out_peercert",    vtype_cert,        &tls_out.peercert },
799   { "tls_out_peerdn",      vtype_stringptr,   &tls_out.peerdn },
800 #ifndef DISABLE_TLS_RESUME
801   { "tls_out_resumption",  vtype_int,         &tls_out.resumption },
802 #endif
803 #ifndef DISABLE_TLS
804   { "tls_out_sni",         vtype_stringptr,   &tls_out.sni },
805 #endif
806 #ifdef SUPPORT_DANE
807   { "tls_out_tlsa_usage",  vtype_int,         &tls_out.tlsa_usage },
808 #endif
809   { "tls_out_ver",         vtype_stringptr,   &tls_out.ver },
810
811   { "tls_peerdn",          vtype_stringptr,   &tls_in.peerdn }, /* mind the alphabetical order! */
812 #ifndef DISABLE_TLS
813   { "tls_sni",             vtype_stringptr,   &tls_in.sni },    /* mind the alphabetical order! */
814 #endif
815
816   { "tod_bsdinbox",        vtype_todbsdin,    NULL },
817   { "tod_epoch",           vtype_tode,        NULL },
818   { "tod_epoch_l",         vtype_todel,       NULL },
819   { "tod_full",            vtype_todf,        NULL },
820   { "tod_log",             vtype_todl,        NULL },
821   { "tod_logfile",         vtype_todlf,       NULL },
822   { "tod_zone",            vtype_todzone,     NULL },
823   { "tod_zulu",            vtype_todzulu,     NULL },
824   { "transport_name",      vtype_stringptr,   &transport_name },
825   { "value",               vtype_stringptr,   &lookup_value },
826   { "verify_mode",         vtype_stringptr,   &verify_mode },
827   { "version_number",      vtype_stringptr,   &version_string },
828   { "warn_message_delay",  vtype_stringptr,   &warnmsg_delay },
829   { "warn_message_recipient",vtype_stringptr, &warnmsg_recipients },
830   { "warn_message_recipients",vtype_stringptr,&warnmsg_recipients },
831   { "warnmsg_delay",       vtype_stringptr,   &warnmsg_delay },
832   { "warnmsg_recipient",   vtype_stringptr,   &warnmsg_recipients },
833   { "warnmsg_recipients",  vtype_stringptr,   &warnmsg_recipients }
834 };
835
836 static int var_table_size = nelem(var_table);
837 static uschar var_buffer[256];
838 static BOOL malformed_header;
839
840 /* For textual hashes */
841
842 static const char *hashcodes = "abcdefghijklmnopqrtsuvwxyz"
843                                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
844                                "0123456789";
845
846 enum { HMAC_MD5, HMAC_SHA1 };
847
848 /* For numeric hashes */
849
850 static unsigned int prime[] = {
851   2,   3,   5,   7,  11,  13,  17,  19,  23,  29,
852  31,  37,  41,  43,  47,  53,  59,  61,  67,  71,
853  73,  79,  83,  89,  97, 101, 103, 107, 109, 113};
854
855 /* For printing modes in symbolic form */
856
857 static uschar *mtable_normal[] =
858   { US"---", US"--x", US"-w-", US"-wx", US"r--", US"r-x", US"rw-", US"rwx" };
859
860 static uschar *mtable_setid[] =
861   { US"--S", US"--s", US"-wS", US"-ws", US"r-S", US"r-s", US"rwS", US"rws" };
862
863 static uschar *mtable_sticky[] =
864   { US"--T", US"--t", US"-wT", US"-wt", US"r-T", US"r-t", US"rwT", US"rwt" };
865
866 /* flags for find_header() */
867 #define FH_EXISTS_ONLY  BIT(0)
868 #define FH_WANT_RAW     BIT(1)
869 #define FH_WANT_LIST    BIT(2)
870
871
872 /*************************************************
873 *           Tables for UTF-8 support             *
874 *************************************************/
875
876 /* Table of the number of extra characters, indexed by the first character
877 masked with 0x3f. The highest number for a valid UTF-8 character is in fact
878 0x3d. */
879
880 static uschar utf8_table1[] = {
881   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
882   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
883   2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
884   3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
885
886 /* These are the masks for the data bits in the first byte of a character,
887 indexed by the number of additional bytes. */
888
889 static int utf8_table2[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
890
891 /* Get the next UTF-8 character, advancing the pointer. */
892
893 #define GETUTF8INC(c, ptr) \
894   c = *ptr++; \
895   if ((c & 0xc0) == 0xc0) \
896     { \
897     int a = utf8_table1[c & 0x3f];  /* Number of additional bytes */ \
898     int s = 6*a; \
899     c = (c & utf8_table2[a]) << s; \
900     while (a-- > 0) \
901       { \
902       s -= 6; \
903       c |= (*ptr++ & 0x3f) << s; \
904       } \
905     }
906
907
908
909 static uschar * base32_chars = US"abcdefghijklmnopqrstuvwxyz234567";
910
911 /*************************************************
912 *           Binary chop search on a table        *
913 *************************************************/
914
915 /* This is used for matching expansion items and operators.
916
917 Arguments:
918   name        the name that is being sought
919   table       the table to search
920   table_size  the number of items in the table
921
922 Returns:      the offset in the table, or -1
923 */
924
925 static int
926 chop_match(uschar *name, uschar **table, int table_size)
927 {
928 uschar **bot = table;
929 uschar **top = table + table_size;
930
931 while (top > bot)
932   {
933   uschar **mid = bot + (top - bot)/2;
934   int c = Ustrcmp(name, *mid);
935   if (c == 0) return mid - table;
936   if (c > 0) bot = mid + 1; else top = mid;
937   }
938
939 return -1;
940 }
941
942
943
944 /*************************************************
945 *          Check a condition string              *
946 *************************************************/
947
948 /* This function is called to expand a string, and test the result for a "true"
949 or "false" value. Failure of the expansion yields FALSE; logged unless it was a
950 forced fail or lookup defer.
951
952 We used to release all store used, but this is not not safe due
953 to ${dlfunc } and ${acl }.  In any case expand_string_internal()
954 is reasonably careful to release what it can.
955
956 The actual false-value tests should be replicated for ECOND_BOOL_LAX.
957
958 Arguments:
959   condition     the condition string
960   m1            text to be incorporated in panic error
961   m2            ditto
962
963 Returns:        TRUE if condition is met, FALSE if not
964 */
965
966 BOOL
967 expand_check_condition(uschar *condition, uschar *m1, uschar *m2)
968 {
969 uschar * ss = expand_string(condition);
970 if (!ss)
971   {
972   if (!f.expand_string_forcedfail && !f.search_find_defer)
973     log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand condition \"%s\" "
974       "for %s %s: %s", condition, m1, m2, expand_string_message);
975   return FALSE;
976   }
977 return *ss && Ustrcmp(ss, "0") != 0 && strcmpic(ss, US"no") != 0 &&
978   strcmpic(ss, US"false") != 0;
979 }
980
981
982
983
984 /*************************************************
985 *        Pseudo-random number generation         *
986 *************************************************/
987
988 /* Pseudo-random number generation.  The result is not "expected" to be
989 cryptographically strong but not so weak that someone will shoot themselves
990 in the foot using it as a nonce in some email header scheme or whatever
991 weirdness they'll twist this into.  The result should ideally handle fork().
992
993 However, if we're stuck unable to provide this, then we'll fall back to
994 appallingly bad randomness.
995
996 If DISABLE_TLS is not defined then this will not be used except as an emergency
997 fallback.
998
999 Arguments:
1000   max       range maximum
1001 Returns     a random number in range [0, max-1]
1002 */
1003
1004 #ifndef DISABLE_TLS
1005 # define vaguely_random_number vaguely_random_number_fallback
1006 #endif
1007 int
1008 vaguely_random_number(int max)
1009 {
1010 #ifndef DISABLE_TLS
1011 # undef vaguely_random_number
1012 #endif
1013 static pid_t pid = 0;
1014 pid_t p2;
1015
1016 if ((p2 = getpid()) != pid)
1017   {
1018   if (pid != 0)
1019     {
1020
1021 #ifdef HAVE_ARC4RANDOM
1022     /* cryptographically strong randomness, common on *BSD platforms, not
1023     so much elsewhere.  Alas. */
1024 # ifndef NOT_HAVE_ARC4RANDOM_STIR
1025     arc4random_stir();
1026 # endif
1027 #elif defined(HAVE_SRANDOM) || defined(HAVE_SRANDOMDEV)
1028 # ifdef HAVE_SRANDOMDEV
1029     /* uses random(4) for seeding */
1030     srandomdev();
1031 # else
1032     {
1033     struct timeval tv;
1034     gettimeofday(&tv, NULL);
1035     srandom(tv.tv_sec | tv.tv_usec | getpid());
1036     }
1037 # endif
1038 #else
1039     /* Poor randomness and no seeding here */
1040 #endif
1041
1042     }
1043   pid = p2;
1044   }
1045
1046 #ifdef HAVE_ARC4RANDOM
1047 return arc4random() % max;
1048 #elif defined(HAVE_SRANDOM) || defined(HAVE_SRANDOMDEV)
1049 return random() % max;
1050 #else
1051 /* This one returns a 16-bit number, definitely not crypto-strong */
1052 return random_number(max);
1053 #endif
1054 }
1055
1056
1057
1058
1059 /*************************************************
1060 *             Pick out a name from a string      *
1061 *************************************************/
1062
1063 /* If the name is too long, it is silently truncated.
1064
1065 Arguments:
1066   name      points to a buffer into which to put the name
1067   max       is the length of the buffer
1068   s         points to the first alphabetic character of the name
1069   extras    chars other than alphanumerics to permit
1070
1071 Returns:    pointer to the first character after the name
1072
1073 Note: The test for *s != 0 in the while loop is necessary because
1074 Ustrchr() yields non-NULL if the character is zero (which is not something
1075 I expected). */
1076
1077 static const uschar *
1078 read_name(uschar *name, int max, const uschar *s, uschar *extras)
1079 {
1080 int ptr = 0;
1081 while (*s && (isalnum(*s) || Ustrchr(extras, *s) != NULL))
1082   {
1083   if (ptr < max-1) name[ptr++] = *s;
1084   s++;
1085   }
1086 name[ptr] = 0;
1087 return s;
1088 }
1089
1090
1091
1092 /*************************************************
1093 *     Pick out the rest of a header name         *
1094 *************************************************/
1095
1096 /* A variable name starting $header_ (or just $h_ for those who like
1097 abbreviations) might not be the complete header name because headers can
1098 contain any printing characters in their names, except ':'. This function is
1099 called to read the rest of the name, chop h[eader]_ off the front, and put ':'
1100 on the end, if the name was terminated by white space.
1101
1102 Arguments:
1103   name      points to a buffer in which the name read so far exists
1104   max       is the length of the buffer
1105   s         points to the first character after the name so far, i.e. the
1106             first non-alphameric character after $header_xxxxx
1107
1108 Returns:    a pointer to the first character after the header name
1109 */
1110
1111 static const uschar *
1112 read_header_name(uschar *name, int max, const uschar *s)
1113 {
1114 int prelen = Ustrchr(name, '_') - name + 1;
1115 int ptr = Ustrlen(name) - prelen;
1116 if (ptr > 0) memmove(name, name+prelen, ptr);
1117 while (mac_isgraph(*s) && *s != ':')
1118   {
1119   if (ptr < max-1) name[ptr++] = *s;
1120   s++;
1121   }
1122 if (*s == ':') s++;
1123 name[ptr++] = ':';
1124 name[ptr] = 0;
1125 return s;
1126 }
1127
1128
1129
1130 /*************************************************
1131 *           Pick out a number from a string      *
1132 *************************************************/
1133
1134 /* Arguments:
1135   n     points to an integer into which to put the number
1136   s     points to the first digit of the number
1137
1138 Returns:  a pointer to the character after the last digit
1139 */
1140 /*XXX consider expanding to int_eximarith_t.  But the test for
1141 "overbig numbers" in 0002 still needs to overflow it. */
1142
1143 static uschar *
1144 read_number(int *n, uschar *s)
1145 {
1146 *n = 0;
1147 while (isdigit(*s)) *n = *n * 10 + (*s++ - '0');
1148 return s;
1149 }
1150
1151 static const uschar *
1152 read_cnumber(int *n, const uschar *s)
1153 {
1154 *n = 0;
1155 while (isdigit(*s)) *n = *n * 10 + (*s++ - '0');
1156 return s;
1157 }
1158
1159
1160
1161 /*************************************************
1162 *        Extract keyed subfield from a string    *
1163 *************************************************/
1164
1165 /* The yield is in dynamic store; NULL means that the key was not found.
1166
1167 Arguments:
1168   key       points to the name of the key
1169   s         points to the string from which to extract the subfield
1170
1171 Returns:    NULL if the subfield was not found, or
1172             a pointer to the subfield's data
1173 */
1174
1175 uschar *
1176 expand_getkeyed(const uschar * key, const uschar * s)
1177 {
1178 int length = Ustrlen(key);
1179 Uskip_whitespace(&s);
1180
1181 /* Loop to search for the key */
1182
1183 while (*s)
1184   {
1185   int dkeylength;
1186   uschar * data;
1187   const uschar * dkey = s;
1188
1189   while (*s && *s != '=' && !isspace(*s)) s++;
1190   dkeylength = s - dkey;
1191   if (Uskip_whitespace(&s) == '=') while (isspace(*++s));
1192
1193   data = string_dequote(&s);
1194   if (length == dkeylength && strncmpic(key, dkey, length) == 0)
1195     return data;
1196
1197   Uskip_whitespace(&s);
1198   }
1199
1200 return NULL;
1201 }
1202
1203
1204
1205 static var_entry *
1206 find_var_ent(uschar * name)
1207 {
1208 int first = 0;
1209 int last = var_table_size;
1210
1211 while (last > first)
1212   {
1213   int middle = (first + last)/2;
1214   int c = Ustrcmp(name, var_table[middle].name);
1215
1216   if (c > 0) { first = middle + 1; continue; }
1217   if (c < 0) { last = middle; continue; }
1218   return &var_table[middle];
1219   }
1220 return NULL;
1221 }
1222
1223 /*************************************************
1224 *   Extract numbered subfield from string        *
1225 *************************************************/
1226
1227 /* Extracts a numbered field from a string that is divided by tokens - for
1228 example a line from /etc/passwd is divided by colon characters.  First field is
1229 numbered one.  Negative arguments count from the right. Zero returns the whole
1230 string. Returns NULL if there are insufficient tokens in the string
1231
1232 ***WARNING***
1233 Modifies final argument - this is a dynamically generated string, so that's OK.
1234
1235 Arguments:
1236   field       number of field to be extracted,
1237                 first field = 1, whole string = 0, last field = -1
1238   separators  characters that are used to break string into tokens
1239   s           points to the string from which to extract the subfield
1240
1241 Returns:      NULL if the field was not found,
1242               a pointer to the field's data inside s (modified to add 0)
1243 */
1244
1245 static uschar *
1246 expand_gettokened (int field, uschar *separators, uschar *s)
1247 {
1248 int sep = 1;
1249 int count;
1250 uschar *ss = s;
1251 uschar *fieldtext = NULL;
1252
1253 if (field == 0) return s;
1254
1255 /* Break the line up into fields in place; for field > 0 we stop when we have
1256 done the number of fields we want. For field < 0 we continue till the end of
1257 the string, counting the number of fields. */
1258
1259 count = (field > 0)? field : INT_MAX;
1260
1261 while (count-- > 0)
1262   {
1263   size_t len;
1264
1265   /* Previous field was the last one in the string. For a positive field
1266   number, this means there are not enough fields. For a negative field number,
1267   check that there are enough, and scan back to find the one that is wanted. */
1268
1269   if (sep == 0)
1270     {
1271     if (field > 0 || (-field) > (INT_MAX - count - 1)) return NULL;
1272     if ((-field) == (INT_MAX - count - 1)) return s;
1273     while (field++ < 0)
1274       {
1275       ss--;
1276       while (ss[-1] != 0) ss--;
1277       }
1278     fieldtext = ss;
1279     break;
1280     }
1281
1282   /* Previous field was not last in the string; save its start and put a
1283   zero at its end. */
1284
1285   fieldtext = ss;
1286   len = Ustrcspn(ss, separators);
1287   sep = ss[len];
1288   ss[len] = 0;
1289   ss += len + 1;
1290   }
1291
1292 return fieldtext;
1293 }
1294
1295
1296 static uschar *
1297 expand_getlistele(int field, const uschar * list)
1298 {
1299 const uschar * tlist = list;
1300 int sep = 0;
1301 /* Tainted mem for the throwaway element copies */
1302 uschar * dummy = store_get(2, TRUE);
1303
1304 if (field < 0)
1305   {
1306   for (field++; string_nextinlist(&tlist, &sep, dummy, 1); ) field++;
1307   sep = 0;
1308   }
1309 if (field == 0) return NULL;
1310 while (--field > 0 && (string_nextinlist(&list, &sep, dummy, 1))) ;
1311 return string_nextinlist(&list, &sep, NULL, 0);
1312 }
1313
1314
1315 /* Certificate fields, by name.  Worry about by-OID later */
1316 /* Names are chosen to not have common prefixes */
1317
1318 #ifndef DISABLE_TLS
1319 typedef struct
1320 {
1321 uschar * name;
1322 int      namelen;
1323 uschar * (*getfn)(void * cert, uschar * mod);
1324 } certfield;
1325 static certfield certfields[] =
1326 {                       /* linear search; no special order */
1327   { US"version",         7,  &tls_cert_version },
1328   { US"serial_number",   13, &tls_cert_serial_number },
1329   { US"subject",         7,  &tls_cert_subject },
1330   { US"notbefore",       9,  &tls_cert_not_before },
1331   { US"notafter",        8,  &tls_cert_not_after },
1332   { US"issuer",          6,  &tls_cert_issuer },
1333   { US"signature",       9,  &tls_cert_signature },
1334   { US"sig_algorithm",   13, &tls_cert_signature_algorithm },
1335   { US"subj_altname",    12, &tls_cert_subject_altname },
1336   { US"ocsp_uri",        8,  &tls_cert_ocsp_uri },
1337   { US"crl_uri",         7,  &tls_cert_crl_uri },
1338 };
1339
1340 static uschar *
1341 expand_getcertele(uschar * field, uschar * certvar)
1342 {
1343 var_entry * vp;
1344
1345 if (!(vp = find_var_ent(certvar)))
1346   {
1347   expand_string_message =
1348     string_sprintf("no variable named \"%s\"", certvar);
1349   return NULL;          /* Unknown variable name */
1350   }
1351 /* NB this stops us passing certs around in variable.  Might
1352 want to do that in future */
1353 if (vp->type != vtype_cert)
1354   {
1355   expand_string_message =
1356     string_sprintf("\"%s\" is not a certificate", certvar);
1357   return NULL;          /* Unknown variable name */
1358   }
1359 if (!*(void **)vp->value)
1360   return NULL;
1361
1362 if (*field >= '0' && *field <= '9')
1363   return tls_cert_ext_by_oid(*(void **)vp->value, field, 0);
1364
1365 for (certfield * cp = certfields;
1366      cp < certfields + nelem(certfields);
1367      cp++)
1368   if (Ustrncmp(cp->name, field, cp->namelen) == 0)
1369     {
1370     uschar * modifier = *(field += cp->namelen) == ','
1371       ? ++field : NULL;
1372     return (*cp->getfn)( *(void **)vp->value, modifier );
1373     }
1374
1375 expand_string_message =
1376   string_sprintf("bad field selector \"%s\" for certextract", field);
1377 return NULL;
1378 }
1379 #endif  /*DISABLE_TLS*/
1380
1381 /*************************************************
1382 *        Extract a substring from a string       *
1383 *************************************************/
1384
1385 /* Perform the ${substr or ${length expansion operations.
1386
1387 Arguments:
1388   subject     the input string
1389   value1      the offset from the start of the input string to the start of
1390                 the output string; if negative, count from the right.
1391   value2      the length of the output string, or negative (-1) for unset
1392                 if value1 is positive, unset means "all after"
1393                 if value1 is negative, unset means "all before"
1394   len         set to the length of the returned string
1395
1396 Returns:      pointer to the output string, or NULL if there is an error
1397 */
1398
1399 static uschar *
1400 extract_substr(uschar *subject, int value1, int value2, int *len)
1401 {
1402 int sublen = Ustrlen(subject);
1403
1404 if (value1 < 0)    /* count from right */
1405   {
1406   value1 += sublen;
1407
1408   /* If the position is before the start, skip to the start, and adjust the
1409   length. If the length ends up negative, the substring is null because nothing
1410   can precede. This falls out naturally when the length is unset, meaning "all
1411   to the left". */
1412
1413   if (value1 < 0)
1414     {
1415     value2 += value1;
1416     if (value2 < 0) value2 = 0;
1417     value1 = 0;
1418     }
1419
1420   /* Otherwise an unset length => characters before value1 */
1421
1422   else if (value2 < 0)
1423     {
1424     value2 = value1;
1425     value1 = 0;
1426     }
1427   }
1428
1429 /* For a non-negative offset, if the starting position is past the end of the
1430 string, the result will be the null string. Otherwise, an unset length means
1431 "rest"; just set it to the maximum - it will be cut down below if necessary. */
1432
1433 else
1434   {
1435   if (value1 > sublen)
1436     {
1437     value1 = sublen;
1438     value2 = 0;
1439     }
1440   else if (value2 < 0) value2 = sublen;
1441   }
1442
1443 /* Cut the length down to the maximum possible for the offset value, and get
1444 the required characters. */
1445
1446 if (value1 + value2 > sublen) value2 = sublen - value1;
1447 *len = value2;
1448 return subject + value1;
1449 }
1450
1451
1452
1453
1454 /*************************************************
1455 *            Old-style hash of a string          *
1456 *************************************************/
1457
1458 /* Perform the ${hash expansion operation.
1459
1460 Arguments:
1461   subject     the input string (an expanded substring)
1462   value1      the length of the output string; if greater or equal to the
1463                 length of the input string, the input string is returned
1464   value2      the number of hash characters to use, or 26 if negative
1465   len         set to the length of the returned string
1466
1467 Returns:      pointer to the output string, or NULL if there is an error
1468 */
1469
1470 static uschar *
1471 compute_hash(uschar *subject, int value1, int value2, int *len)
1472 {
1473 int sublen = Ustrlen(subject);
1474
1475 if (value2 < 0) value2 = 26;
1476 else if (value2 > Ustrlen(hashcodes))
1477   {
1478   expand_string_message =
1479     string_sprintf("hash count \"%d\" too big", value2);
1480   return NULL;
1481   }
1482
1483 /* Calculate the hash text. We know it is shorter than the original string, so
1484 can safely place it in subject[] (we know that subject is always itself an
1485 expanded substring). */
1486
1487 if (value1 < sublen)
1488   {
1489   int c;
1490   int i = 0;
1491   int j = value1;
1492   while ((c = (subject[j])) != 0)
1493     {
1494     int shift = (c + j++) & 7;
1495     subject[i] ^= (c << shift) | (c >> (8-shift));
1496     if (++i >= value1) i = 0;
1497     }
1498   for (i = 0; i < value1; i++)
1499     subject[i] = hashcodes[(subject[i]) % value2];
1500   }
1501 else value1 = sublen;
1502
1503 *len = value1;
1504 return subject;
1505 }
1506
1507
1508
1509
1510 /*************************************************
1511 *             Numeric hash of a string           *
1512 *************************************************/
1513
1514 /* Perform the ${nhash expansion operation. The first characters of the
1515 string are treated as most important, and get the highest prime numbers.
1516
1517 Arguments:
1518   subject     the input string
1519   value1      the maximum value of the first part of the result
1520   value2      the maximum value of the second part of the result,
1521                 or negative to produce only a one-part result
1522   len         set to the length of the returned string
1523
1524 Returns:  pointer to the output string, or NULL if there is an error.
1525 */
1526
1527 static uschar *
1528 compute_nhash (uschar *subject, int value1, int value2, int *len)
1529 {
1530 uschar *s = subject;
1531 int i = 0;
1532 unsigned long int total = 0; /* no overflow */
1533
1534 while (*s != 0)
1535   {
1536   if (i == 0) i = nelem(prime) - 1;
1537   total += prime[i--] * (unsigned int)(*s++);
1538   }
1539
1540 /* If value2 is unset, just compute one number */
1541
1542 if (value2 < 0)
1543   s = string_sprintf("%lu", total % value1);
1544
1545 /* Otherwise do a div/mod hash */
1546
1547 else
1548   {
1549   total = total % (value1 * value2);
1550   s = string_sprintf("%lu/%lu", total/value2, total % value2);
1551   }
1552
1553 *len = Ustrlen(s);
1554 return s;
1555 }
1556
1557
1558
1559
1560
1561 /*************************************************
1562 *     Find the value of a header or headers      *
1563 *************************************************/
1564
1565 /* Multiple instances of the same header get concatenated, and this function
1566 can also return a concatenation of all the header lines. When concatenating
1567 specific headers that contain lists of addresses, a comma is inserted between
1568 them. Otherwise we use a straight concatenation. Because some messages can have
1569 pathologically large number of lines, there is a limit on the length that is
1570 returned.
1571
1572 Arguments:
1573   name          the name of the header, without the leading $header_ or $h_,
1574                 or NULL if a concatenation of all headers is required
1575   newsize       return the size of memory block that was obtained; may be NULL
1576                 if exists_only is TRUE
1577   flags         FH_EXISTS_ONLY
1578                   set if called from a def: test; don't need to build a string;
1579                   just return a string that is not "" and not "0" if the header
1580                   exists
1581                 FH_WANT_RAW
1582                   set if called for $rh_ or $rheader_ items; no processing,
1583                   other than concatenating, will be done on the header. Also used
1584                   for $message_headers_raw.
1585                 FH_WANT_LIST
1586                   Double colon chars in the content, and replace newline with
1587                   colon between each element when concatenating; returning a
1588                   colon-sep list (elements might contain newlines)
1589   charset       name of charset to translate MIME words to; used only if
1590                 want_raw is false; if NULL, no translation is done (this is
1591                 used for $bh_ and $bheader_)
1592
1593 Returns:        NULL if the header does not exist, else a pointer to a new
1594                 store block
1595 */
1596
1597 static uschar *
1598 find_header(uschar *name, int *newsize, unsigned flags, uschar *charset)
1599 {
1600 BOOL found = !name;
1601 int len = name ? Ustrlen(name) : 0;
1602 BOOL comma = FALSE;
1603 gstring * g = NULL;
1604
1605 for (header_line * h = header_list; h; h = h->next)
1606   if (h->type != htype_old && h->text)  /* NULL => Received: placeholder */
1607     if (!name || (len <= h->slen && strncmpic(name, h->text, len) == 0))
1608       {
1609       uschar * s, * t;
1610       size_t inc;
1611
1612       if (flags & FH_EXISTS_ONLY)
1613         return US"1";  /* don't need actual string */
1614
1615       found = TRUE;
1616       s = h->text + len;                /* text to insert */
1617       if (!(flags & FH_WANT_RAW))       /* unless wanted raw, */
1618         Uskip_whitespace(&s);           /* remove leading white space */
1619       t = h->text + h->slen;            /* end-point */
1620
1621       /* Unless wanted raw, remove trailing whitespace, including the
1622       newline. */
1623
1624       if (flags & FH_WANT_LIST)
1625         while (t > s && t[-1] == '\n') t--;
1626       else if (!(flags & FH_WANT_RAW))
1627         {
1628         while (t > s && isspace(t[-1])) t--;
1629
1630         /* Set comma if handling a single header and it's one of those
1631         that contains an address list, except when asked for raw headers. Only
1632         need to do this once. */
1633
1634         if (name && !comma && Ustrchr("BCFRST", h->type)) comma = TRUE;
1635         }
1636
1637       /* Trim the header roughly if we're approaching limits */
1638       inc = t - s;
1639       if (gstring_length(g) + inc > header_insert_maxlen)
1640         inc = header_insert_maxlen - gstring_length(g);
1641
1642       /* For raw just copy the data; for a list, add the data as a colon-sep
1643       list-element; for comma-list add as an unchecked comma,newline sep
1644       list-elemment; for other nonraw add as an unchecked newline-sep list (we
1645       stripped trailing WS above including the newline). We ignore the potential
1646       expansion due to colon-doubling, just leaving the loop if the limit is met
1647       or exceeded. */
1648
1649       if (flags & FH_WANT_LIST)
1650         g = string_append_listele_n(g, ':', s, (unsigned)inc);
1651       else if (flags & FH_WANT_RAW)
1652         g = string_catn(g, s, (unsigned)inc);
1653       else if (inc > 0)
1654         g = string_append2_listele_n(g, comma ? US",\n" : US"\n",
1655           s, (unsigned)inc);
1656
1657       if (gstring_length(g) >= header_insert_maxlen) break;
1658       }
1659
1660 if (!found) return NULL;        /* No header found */
1661 if (!g) return US"";
1662
1663 /* That's all we do for raw header expansion. */
1664
1665 *newsize = g->size;
1666 if (flags & FH_WANT_RAW)
1667   return string_from_gstring(g);
1668
1669 /* Otherwise do RFC 2047 decoding, translating the charset if requested.
1670 The rfc2047_decode2() function can return an error with decoded data if the
1671 charset translation fails. If decoding fails, it returns NULL. */
1672
1673 else
1674   {
1675   uschar * error, * decoded = rfc2047_decode2(string_from_gstring(g),
1676     check_rfc2047_length, charset, '?', NULL, newsize, &error);
1677   if (error)
1678     DEBUG(D_any) debug_printf("*** error in RFC 2047 decoding: %s\n"
1679       "    input was: %s\n", error, g->s);
1680   return decoded ? decoded : string_from_gstring(g);
1681   }
1682 }
1683
1684
1685
1686
1687 /* Append a "local" element to an Authentication-Results: header
1688 if this was a non-smtp message.
1689 */
1690
1691 static gstring *
1692 authres_local(gstring * g, const uschar * sysname)
1693 {
1694 if (!f.authentication_local)
1695   return g;
1696 g = string_append(g, 3, US";\n\tlocal=pass (non-smtp, ", sysname, US")");
1697 if (authenticated_id) g = string_append(g, 2, " u=", authenticated_id);
1698 return g;
1699 }
1700
1701
1702 /* Append an "iprev" element to an Authentication-Results: header
1703 if we have attempted to get the calling host's name.
1704 */
1705
1706 static gstring *
1707 authres_iprev(gstring * g)
1708 {
1709 if (sender_host_name)
1710   g = string_append(g, 3, US";\n\tiprev=pass (", sender_host_name, US")");
1711 else if (host_lookup_deferred)
1712   g = string_cat(g, US";\n\tiprev=temperror");
1713 else if (host_lookup_failed)
1714   g = string_cat(g, US";\n\tiprev=fail");
1715 else
1716   return g;
1717
1718 if (sender_host_address)
1719   g = string_append(g, 2, US" smtp.remote-ip=", sender_host_address);
1720 return g;
1721 }
1722
1723
1724
1725 /*************************************************
1726 *               Return list of recipients        *
1727 *************************************************/
1728 /* A recipients list is available only during system message filtering,
1729 during ACL processing after DATA, and while expanding pipe commands
1730 generated from a system filter, but not elsewhere. */
1731
1732 static uschar *
1733 fn_recipients(void)
1734 {
1735 uschar * s;
1736 gstring * g = NULL;
1737
1738 if (!f.enable_dollar_recipients) return NULL;
1739
1740 for (int i = 0; i < recipients_count; i++)
1741   {
1742   s = recipients_list[i].address;
1743   g = string_append2_listele_n(g, US", ", s, Ustrlen(s));
1744   }
1745 return g ? g->s : NULL;
1746 }
1747
1748
1749 /*************************************************
1750 *               Return size of queue             *
1751 *************************************************/
1752 /* Ask the daemon for the queue size */
1753
1754 static uschar *
1755 fn_queue_size(void)
1756 {
1757 struct sockaddr_un sa_un = {.sun_family = AF_UNIX};
1758 uschar buf[16];
1759 int fd;
1760 ssize_t len;
1761 const uschar * where;
1762 #ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
1763 uschar * sname;
1764 #endif
1765 fd_set fds;
1766 struct timeval tv;
1767
1768 if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
1769   {
1770   DEBUG(D_expand) debug_printf(" socket: %s\n", strerror(errno));
1771   return NULL;
1772   }
1773
1774 #ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
1775 sa_un.sun_path[0] = 0;  /* Abstract local socket addr - Linux-specific? */
1776 len = offsetof(struct sockaddr_un, sun_path) + 1
1777   + snprintf(sa_un.sun_path+1, sizeof(sa_un.sun_path)-1, "exim_%d", getpid());
1778 #else
1779 sname = string_sprintf("%s/p_%d", spool_directory, getpid());
1780 len = offsetof(struct sockaddr_un, sun_path)
1781   + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s", sname);
1782 #endif
1783
1784 if (bind(fd, (const struct sockaddr *)&sa_un, len) < 0)
1785   { where = US"bind"; goto bad; }
1786
1787 #ifdef notdef
1788 debug_printf("local addr '%s%s'\n",
1789   *sa_un.sun_path ? "" : "@",
1790   sa_un.sun_path + (*sa_un.sun_path ? 0 : 1));
1791 #endif
1792
1793 #ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
1794 sa_un.sun_path[0] = 0;  /* Abstract local socket addr - Linux-specific? */
1795 len = offsetof(struct sockaddr_un, sun_path) + 1
1796   + snprintf(sa_un.sun_path+1, sizeof(sa_un.sun_path)-1, "%s",
1797               expand_string(notifier_socket));
1798 #else
1799 len = offsetof(struct sockaddr_un, sun_path)
1800   + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s",
1801               expand_string(notifier_socket));
1802 #endif
1803
1804 if (connect(fd, (const struct sockaddr *)&sa_un, len) < 0)
1805   { where = US"connect"; goto bad2; }
1806
1807 buf[0] = NOTIFY_QUEUE_SIZE_REQ;
1808 if (send(fd, buf, 1, 0) < 0) { where = US"send"; goto bad; }
1809
1810 FD_ZERO(&fds); FD_SET(fd, &fds);
1811 tv.tv_sec = 2; tv.tv_usec = 0;
1812 if (select(fd + 1, (SELECT_ARG2_TYPE *)&fds, NULL, NULL, &tv) != 1)
1813   {
1814   DEBUG(D_expand) debug_printf("no daemon response; using local evaluation\n");
1815   len = snprintf(CS buf, sizeof(buf), "%u", queue_count_cached());
1816   }
1817 else if ((len = recv(fd, buf, sizeof(buf), 0)) < 0)
1818   { where = US"recv"; goto bad2; }
1819
1820 close(fd);
1821 #ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
1822 Uunlink(sname);
1823 #endif
1824 return string_copyn(buf, len);
1825
1826 bad2:
1827 #ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
1828   Uunlink(sname);
1829 #endif
1830 bad:
1831   close(fd);
1832   DEBUG(D_expand) debug_printf(" %s: %s\n", where, strerror(errno));
1833   return NULL;
1834 }
1835
1836
1837 /*************************************************
1838 *               Find value of a variable         *
1839 *************************************************/
1840
1841 /* The table of variables is kept in alphabetic order, so we can search it
1842 using a binary chop. The "choplen" variable is nothing to do with the binary
1843 chop.
1844
1845 Arguments:
1846   name          the name of the variable being sought
1847   exists_only   TRUE if this is a def: test; passed on to find_header()
1848   skipping      TRUE => skip any processing evaluation; this is not the same as
1849                   exists_only because def: may test for values that are first
1850                   evaluated here
1851   newsize       pointer to an int which is initially zero; if the answer is in
1852                 a new memory buffer, *newsize is set to its size
1853
1854 Returns:        NULL if the variable does not exist, or
1855                 a pointer to the variable's contents, or
1856                 something non-NULL if exists_only is TRUE
1857 */
1858
1859 static uschar *
1860 find_variable(uschar *name, BOOL exists_only, BOOL skipping, int *newsize)
1861 {
1862 var_entry * vp;
1863 uschar *s, *domain;
1864 uschar **ss;
1865 void * val;
1866
1867 /* Handle ACL variables, whose names are of the form acl_cxxx or acl_mxxx.
1868 Originally, xxx had to be a number in the range 0-9 (later 0-19), but from
1869 release 4.64 onwards arbitrary names are permitted, as long as the first 5
1870 characters are acl_c or acl_m and the sixth is either a digit or an underscore
1871 (this gave backwards compatibility at the changeover). There may be built-in
1872 variables whose names start acl_ but they should never start in this way. This
1873 slightly messy specification is a consequence of the history, needless to say.
1874
1875 If an ACL variable does not exist, treat it as empty, unless strict_acl_vars is
1876 set, in which case give an error. */
1877
1878 if ((Ustrncmp(name, "acl_c", 5) == 0 || Ustrncmp(name, "acl_m", 5) == 0) &&
1879      !isalpha(name[5]))
1880   {
1881   tree_node * node =
1882     tree_search(name[4] == 'c' ? acl_var_c : acl_var_m, name + 4);
1883   return node ? node->data.ptr : strict_acl_vars ? NULL : US"";
1884   }
1885 else if (Ustrncmp(name, "r_", 2) == 0)
1886   {
1887   tree_node * node = tree_search(router_var, name + 2);
1888   return node ? node->data.ptr : strict_acl_vars ? NULL : US"";
1889   }
1890
1891 /* Handle $auth<n> variables. */
1892
1893 if (Ustrncmp(name, "auth", 4) == 0)
1894   {
1895   uschar *endptr;
1896   int n = Ustrtoul(name + 4, &endptr, 10);
1897   if (*endptr == 0 && n != 0 && n <= AUTH_VARS)
1898     return !auth_vars[n-1] ? US"" : auth_vars[n-1];
1899   }
1900 else if (Ustrncmp(name, "regex", 5) == 0)
1901   {
1902   uschar *endptr;
1903   int n = Ustrtoul(name + 5, &endptr, 10);
1904   if (*endptr == 0 && n != 0 && n <= REGEX_VARS)
1905     return !regex_vars[n-1] ? US"" : regex_vars[n-1];
1906   }
1907
1908 /* For all other variables, search the table */
1909
1910 if (!(vp = find_var_ent(name)))
1911   return NULL;          /* Unknown variable name */
1912
1913 /* Found an existing variable. If in skipping state, the value isn't needed,
1914 and we want to avoid processing (such as looking up the host name). */
1915
1916 if (skipping)
1917   return US"";
1918
1919 val = vp->value;
1920 switch (vp->type)
1921   {
1922   case vtype_filter_int:
1923     if (!f.filter_running) return NULL;
1924     /* Fall through */
1925     /* VVVVVVVVVVVV */
1926   case vtype_int:
1927     sprintf(CS var_buffer, "%d", *(int *)(val)); /* Integer */
1928     return var_buffer;
1929
1930   case vtype_ino:
1931     sprintf(CS var_buffer, "%ld", (long int)(*(ino_t *)(val))); /* Inode */
1932     return var_buffer;
1933
1934   case vtype_gid:
1935     sprintf(CS var_buffer, "%ld", (long int)(*(gid_t *)(val))); /* gid */
1936     return var_buffer;
1937
1938   case vtype_uid:
1939     sprintf(CS var_buffer, "%ld", (long int)(*(uid_t *)(val))); /* uid */
1940     return var_buffer;
1941
1942   case vtype_bool:
1943     sprintf(CS var_buffer, "%s", *(BOOL *)(val) ? "yes" : "no"); /* bool */
1944     return var_buffer;
1945
1946   case vtype_stringptr:                      /* Pointer to string */
1947     return (s = *((uschar **)(val))) ? s : US"";
1948
1949   case vtype_pid:
1950     sprintf(CS var_buffer, "%d", (int)getpid()); /* pid */
1951     return var_buffer;
1952
1953   case vtype_load_avg:
1954     sprintf(CS var_buffer, "%d", OS_GETLOADAVG()); /* load_average */
1955     return var_buffer;
1956
1957   case vtype_host_lookup:                    /* Lookup if not done so */
1958     if (  !sender_host_name && sender_host_address
1959        && !host_lookup_failed && host_name_lookup() == OK)
1960       host_build_sender_fullhost();
1961     return sender_host_name ? sender_host_name : US"";
1962
1963   case vtype_localpart:                      /* Get local part from address */
1964     if (!(s = *((uschar **)(val)))) return US"";
1965     if (!(domain = Ustrrchr(s, '@'))) return s;
1966     if (domain - s > sizeof(var_buffer) - 1)
1967       log_write(0, LOG_MAIN|LOG_PANIC_DIE, "local part longer than " SIZE_T_FMT
1968           " in string expansion", sizeof(var_buffer));
1969     return string_copyn(s, domain - s);
1970
1971   case vtype_domain:                         /* Get domain from address */
1972     if (!(s = *((uschar **)(val)))) return US"";
1973     domain = Ustrrchr(s, '@');
1974     return domain ? domain + 1 : US"";
1975
1976   case vtype_msgheaders:
1977     return find_header(NULL, newsize, exists_only ? FH_EXISTS_ONLY : 0, NULL);
1978
1979   case vtype_msgheaders_raw:
1980     return find_header(NULL, newsize,
1981                 exists_only ? FH_EXISTS_ONLY|FH_WANT_RAW : FH_WANT_RAW, NULL);
1982
1983   case vtype_msgbody:                        /* Pointer to msgbody string */
1984   case vtype_msgbody_end:                    /* Ditto, the end of the msg */
1985     ss = (uschar **)(val);
1986     if (!*ss && deliver_datafile >= 0)  /* Read body when needed */
1987       {
1988       uschar * body;
1989       off_t start_offset = SPOOL_DATA_START_OFFSET;
1990       int len = message_body_visible;
1991
1992       if (len > message_size) len = message_size;
1993       *ss = body = store_get(len+1, TRUE);
1994       body[0] = 0;
1995       if (vp->type == vtype_msgbody_end)
1996         {
1997         struct stat statbuf;
1998         if (fstat(deliver_datafile, &statbuf) == 0)
1999           {
2000           start_offset = statbuf.st_size - len;
2001           if (start_offset < SPOOL_DATA_START_OFFSET)
2002             start_offset = SPOOL_DATA_START_OFFSET;
2003           }
2004         }
2005       if (lseek(deliver_datafile, start_offset, SEEK_SET) < 0)
2006         log_write(0, LOG_MAIN|LOG_PANIC_DIE, "deliver_datafile lseek: %s",
2007           strerror(errno));
2008       if ((len = read(deliver_datafile, body, len)) > 0)
2009         {
2010         body[len] = 0;
2011         if (message_body_newlines)   /* Separate loops for efficiency */
2012           while (len > 0)
2013             { if (body[--len] == 0) body[len] = ' '; }
2014         else
2015           while (len > 0)
2016             { if (body[--len] == '\n' || body[len] == 0) body[len] = ' '; }
2017         }
2018       }
2019     return *ss ? *ss : US"";
2020
2021   case vtype_todbsdin:                       /* BSD inbox time of day */
2022     return tod_stamp(tod_bsdin);
2023
2024   case vtype_tode:                           /* Unix epoch time of day */
2025     return tod_stamp(tod_epoch);
2026
2027   case vtype_todel:                          /* Unix epoch/usec time of day */
2028     return tod_stamp(tod_epoch_l);
2029
2030   case vtype_todf:                           /* Full time of day */
2031     return tod_stamp(tod_full);
2032
2033   case vtype_todl:                           /* Log format time of day */
2034     return tod_stamp(tod_log_bare);            /* (without timezone) */
2035
2036   case vtype_todzone:                        /* Time zone offset only */
2037     return tod_stamp(tod_zone);
2038
2039   case vtype_todzulu:                        /* Zulu time */
2040     return tod_stamp(tod_zulu);
2041
2042   case vtype_todlf:                          /* Log file datestamp tod */
2043     return tod_stamp(tod_log_datestamp_daily);
2044
2045   case vtype_reply:                          /* Get reply address */
2046     s = find_header(US"reply-to:", newsize,
2047                 exists_only ? FH_EXISTS_ONLY|FH_WANT_RAW : FH_WANT_RAW,
2048                 headers_charset);
2049     if (s) Uskip_whitespace(&s);
2050     if (!s || !*s)
2051       {
2052       *newsize = 0;                            /* For the *s==0 case */
2053       s = find_header(US"from:", newsize,
2054                 exists_only ? FH_EXISTS_ONLY|FH_WANT_RAW : FH_WANT_RAW,
2055                 headers_charset);
2056       }
2057     if (s)
2058       {
2059       uschar *t;
2060       Uskip_whitespace(&s);
2061       for (t = s; *t; t++) if (*t == '\n') *t = ' ';
2062       while (t > s && isspace(t[-1])) t--;
2063       *t = 0;
2064       }
2065     return s ? s : US"";
2066
2067   case vtype_string_func:
2068     {
2069     stringptr_fn_t * fn = (stringptr_fn_t *) val;
2070     uschar* s = fn();
2071     return s ? s : US"";
2072     }
2073
2074   case vtype_pspace:
2075     {
2076     int inodes;
2077     sprintf(CS var_buffer, PR_EXIM_ARITH,
2078       receive_statvfs(val == (void *)TRUE, &inodes));
2079     }
2080   return var_buffer;
2081
2082   case vtype_pinodes:
2083     {
2084     int inodes;
2085     (void) receive_statvfs(val == (void *)TRUE, &inodes);
2086     sprintf(CS var_buffer, "%d", inodes);
2087     }
2088   return var_buffer;
2089
2090   case vtype_cert:
2091     return *(void **)val ? US"<cert>" : US"";
2092
2093 #ifndef DISABLE_DKIM
2094   case vtype_dkim:
2095     return dkim_exim_expand_query((int)(long)val);
2096 #endif
2097
2098   }
2099
2100 return NULL;  /* Unknown variable. Silences static checkers. */
2101 }
2102
2103
2104
2105
2106 void
2107 modify_variable(uschar *name, void * value)
2108 {
2109 var_entry * vp;
2110 if ((vp = find_var_ent(name))) vp->value = value;
2111 return;          /* Unknown variable name, fail silently */
2112 }
2113
2114
2115
2116
2117
2118
2119 /*************************************************
2120 *           Read and expand substrings           *
2121 *************************************************/
2122
2123 /* This function is called to read and expand argument substrings for various
2124 expansion items. Some have a minimum requirement that is less than the maximum;
2125 in these cases, the first non-present one is set to NULL.
2126
2127 Arguments:
2128   sub        points to vector of pointers to set
2129   n          maximum number of substrings
2130   m          minimum required
2131   sptr       points to current string pointer
2132   skipping   the skipping flag
2133   check_end  if TRUE, check for final '}'
2134   name       name of item, for error message
2135   resetok    if not NULL, pointer to flag - write FALSE if unsafe to reset
2136              the store.
2137
2138 Returns:     0 OK; string pointer updated
2139              1 curly bracketing error (too few arguments)
2140              2 too many arguments (only if check_end is set); message set
2141              3 other error (expansion failure)
2142 */
2143
2144 static int
2145 read_subs(uschar **sub, int n, int m, const uschar **sptr, BOOL skipping,
2146   BOOL check_end, uschar *name, BOOL *resetok)
2147 {
2148 const uschar *s = *sptr;
2149
2150 Uskip_whitespace(&s);
2151 for (int i = 0; i < n; i++)
2152   {
2153   if (*s != '{')
2154     {
2155     if (i < m)
2156       {
2157       expand_string_message = string_sprintf("Not enough arguments for '%s' "
2158         "(min is %d)", name, m);
2159       return 1;
2160       }
2161     sub[i] = NULL;
2162     break;
2163     }
2164   if (!(sub[i] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, resetok)))
2165     return 3;
2166   if (*s++ != '}') return 1;
2167   Uskip_whitespace(&s);
2168   }
2169 if (check_end && *s++ != '}')
2170   {
2171   if (s[-1] == '{')
2172     {
2173     expand_string_message = string_sprintf("Too many arguments for '%s' "
2174       "(max is %d)", name, n);
2175     return 2;
2176     }
2177   expand_string_message = string_sprintf("missing '}' after '%s'", name);
2178   return 1;
2179   }
2180
2181 *sptr = s;
2182 return 0;
2183 }
2184
2185
2186
2187
2188 /*************************************************
2189 *     Elaborate message for bad variable         *
2190 *************************************************/
2191
2192 /* For the "unknown variable" message, take a look at the variable's name, and
2193 give additional information about possible ACL variables. The extra information
2194 is added on to expand_string_message.
2195
2196 Argument:   the name of the variable
2197 Returns:    nothing
2198 */
2199
2200 static void
2201 check_variable_error_message(uschar *name)
2202 {
2203 if (Ustrncmp(name, "acl_", 4) == 0)
2204   expand_string_message = string_sprintf("%s (%s)", expand_string_message,
2205     (name[4] == 'c' || name[4] == 'm')?
2206       (isalpha(name[5])?
2207         US"6th character of a user-defined ACL variable must be a digit or underscore" :
2208         US"strict_acl_vars is set"    /* Syntax is OK, it has to be this */
2209       ) :
2210       US"user-defined ACL variables must start acl_c or acl_m");
2211 }
2212
2213
2214
2215 /*
2216 Load args from sub array to globals, and call acl_check().
2217 Sub array will be corrupted on return.
2218
2219 Returns:       OK         access is granted by an ACCEPT verb
2220                DISCARD    access is (apparently) granted by a DISCARD verb
2221                FAIL       access is denied
2222                FAIL_DROP  access is denied; drop the connection
2223                DEFER      can't tell at the moment
2224                ERROR      disaster
2225 */
2226 static int
2227 eval_acl(uschar ** sub, int nsub, uschar ** user_msgp)
2228 {
2229 int i;
2230 int sav_narg = acl_narg;
2231 int ret;
2232 uschar * dummy_logmsg;
2233 extern int acl_where;
2234
2235 if(--nsub > nelem(acl_arg)) nsub = nelem(acl_arg);
2236 for (i = 0; i < nsub && sub[i+1]; i++)
2237   {
2238   uschar * tmp = acl_arg[i];
2239   acl_arg[i] = sub[i+1];        /* place callers args in the globals */
2240   sub[i+1] = tmp;               /* stash the old args using our caller's storage */
2241   }
2242 acl_narg = i;
2243 while (i < nsub)
2244   {
2245   sub[i+1] = acl_arg[i];
2246   acl_arg[i++] = NULL;
2247   }
2248
2249 DEBUG(D_expand)
2250   debug_printf_indent("expanding: acl: %s  arg: %s%s\n",
2251     sub[0],
2252     acl_narg>0 ? acl_arg[0] : US"<none>",
2253     acl_narg>1 ? " +more"   : "");
2254
2255 ret = acl_eval(acl_where, sub[0], user_msgp, &dummy_logmsg);
2256
2257 for (i = 0; i < nsub; i++)
2258   acl_arg[i] = sub[i+1];        /* restore old args */
2259 acl_narg = sav_narg;
2260
2261 return ret;
2262 }
2263
2264
2265
2266
2267 /* Return pointer to dewrapped string, with enclosing specified chars removed.
2268 The given string is modified on return.  Leading whitespace is skipped while
2269 looking for the opening wrap character, then the rest is scanned for the trailing
2270 (non-escaped) wrap character.  A backslash in the string will act as an escape.
2271
2272 A nul is written over the trailing wrap, and a pointer to the char after the
2273 leading wrap is returned.
2274
2275 Arguments:
2276   s     String for de-wrapping
2277   wrap  Two-char string, the first being the opener, second the closer wrapping
2278         character
2279 Return:
2280   Pointer to de-wrapped string, or NULL on error (with expand_string_message set).
2281 */
2282
2283 static uschar *
2284 dewrap(uschar * s, const uschar * wrap)
2285 {
2286 uschar * p = s;
2287 unsigned depth = 0;
2288 BOOL quotesmode = wrap[0] == wrap[1];
2289
2290 if (Uskip_whitespace(&p) == *wrap)
2291   {
2292   s = ++p;
2293   wrap++;
2294   while (*p)
2295     {
2296     if (*p == '\\') p++;
2297     else if (!quotesmode && *p == wrap[-1]) depth++;
2298     else if (*p == *wrap)
2299       if (depth == 0)
2300         {
2301         *p = '\0';
2302         return s;
2303         }
2304       else
2305         depth--;
2306     p++;
2307     }
2308   }
2309 expand_string_message = string_sprintf("missing '%c'", *wrap);
2310 return NULL;
2311 }
2312
2313
2314 /* Pull off the leading array or object element, returning
2315 a copy in an allocated string.  Update the list pointer.
2316
2317 The element may itself be an abject or array.
2318 Return NULL when the list is empty.
2319 */
2320
2321 static uschar *
2322 json_nextinlist(const uschar ** list)
2323 {
2324 unsigned array_depth = 0, object_depth = 0;
2325 const uschar * s = *list, * item;
2326
2327 skip_whitespace(&s);
2328
2329 for (item = s;
2330      *s && (*s != ',' || array_depth != 0 || object_depth != 0);
2331      s++)
2332   switch (*s)
2333     {
2334     case '[': array_depth++; break;
2335     case ']': array_depth--; break;
2336     case '{': object_depth++; break;
2337     case '}': object_depth--; break;
2338     }
2339 *list = *s ? s+1 : s;
2340 if (item == s) return NULL;
2341 item = string_copyn(item, s - item);
2342 DEBUG(D_expand) debug_printf_indent("  json ele: '%s'\n", item);
2343 return US item;
2344 }
2345
2346
2347
2348 /************************************************/
2349 /*  Return offset in ops table, or -1 if not found.
2350 Repoint to just after the operator in the string.
2351
2352 Argument:
2353  ss     string representation of operator
2354  opname split-out operator name
2355 */
2356
2357 static int
2358 identify_operator(const uschar ** ss, uschar ** opname)
2359 {
2360 const uschar * s = *ss;
2361 uschar name[256];
2362
2363 /* Numeric comparisons are symbolic */
2364
2365 if (*s == '=' || *s == '>' || *s == '<')
2366   {
2367   int p = 0;
2368   name[p++] = *s++;
2369   if (*s == '=')
2370     {
2371     name[p++] = '=';
2372     s++;
2373     }
2374   name[p] = 0;
2375   }
2376
2377 /* All other conditions are named */
2378
2379 else
2380   s = read_name(name, sizeof(name), s, US"_");
2381 *ss = s;
2382
2383 /* If we haven't read a name, it means some non-alpha character is first. */
2384
2385 if (!name[0])
2386   {
2387   expand_string_message = string_sprintf("condition name expected, "
2388     "but found \"%.16s\"", s);
2389   return -1;
2390   }
2391 if (opname)
2392   *opname = string_copy(name);
2393
2394 return chop_match(name, cond_table, nelem(cond_table));
2395 }
2396
2397
2398 /*************************************************
2399 *    Handle MD5 or SHA-1 computation for HMAC    *
2400 *************************************************/
2401
2402 /* These are some wrapping functions that enable the HMAC code to be a bit
2403 cleaner. A good compiler will spot the tail recursion.
2404
2405 Arguments:
2406   type         HMAC_MD5 or HMAC_SHA1
2407   remaining    are as for the cryptographic hash functions
2408
2409 Returns:       nothing
2410 */
2411
2412 static void
2413 chash_start(int type, void * base)
2414 {
2415 if (type == HMAC_MD5)
2416   md5_start((md5 *)base);
2417 else
2418   sha1_start((hctx *)base);
2419 }
2420
2421 static void
2422 chash_mid(int type, void * base, const uschar * string)
2423 {
2424 if (type == HMAC_MD5)
2425   md5_mid((md5 *)base, string);
2426 else
2427   sha1_mid((hctx *)base, string);
2428 }
2429
2430 static void
2431 chash_end(int type, void * base, const uschar * string, int length,
2432   uschar * digest)
2433 {
2434 if (type == HMAC_MD5)
2435   md5_end((md5 *)base, string, length, digest);
2436 else
2437   sha1_end((hctx *)base, string, length, digest);
2438 }
2439
2440
2441
2442
2443 #ifdef SUPPORT_SRS
2444 /* Do an hmac_md5.  The result is _not_ nul-terminated, and is sized as
2445 the smaller of a full hmac_md5 result (16 bytes) or the supplied output buffer.
2446
2447 Arguments:
2448         key     encoding key, nul-terminated
2449         src     data to be hashed, nul-terminated
2450         buf     output buffer
2451         len     size of output buffer
2452 */
2453
2454 static void
2455 hmac_md5(const uschar * key, const uschar * src, uschar * buf, unsigned len)
2456 {
2457 md5 md5_base;
2458 const uschar * keyptr;
2459 uschar * p;
2460 unsigned int keylen;
2461
2462 #define MD5_HASHLEN      16
2463 #define MD5_HASHBLOCKLEN 64
2464
2465 uschar keyhash[MD5_HASHLEN];
2466 uschar innerhash[MD5_HASHLEN];
2467 uschar finalhash[MD5_HASHLEN];
2468 uschar innerkey[MD5_HASHBLOCKLEN];
2469 uschar outerkey[MD5_HASHBLOCKLEN];
2470
2471 keyptr = key;
2472 keylen = Ustrlen(keyptr);
2473
2474 /* If the key is longer than the hash block length, then hash the key
2475 first */
2476
2477 if (keylen > MD5_HASHBLOCKLEN)
2478   {
2479   chash_start(HMAC_MD5, &md5_base);
2480   chash_end(HMAC_MD5, &md5_base, keyptr, keylen, keyhash);
2481   keyptr = keyhash;
2482   keylen = MD5_HASHLEN;
2483   }
2484
2485 /* Now make the inner and outer key values */
2486
2487 memset(innerkey, 0x36, MD5_HASHBLOCKLEN);
2488 memset(outerkey, 0x5c, MD5_HASHBLOCKLEN);
2489
2490 for (int i = 0; i < keylen; i++)
2491   {
2492   innerkey[i] ^= keyptr[i];
2493   outerkey[i] ^= keyptr[i];
2494   }
2495
2496 /* Now do the hashes */
2497
2498 chash_start(HMAC_MD5, &md5_base);
2499 chash_mid(HMAC_MD5, &md5_base, innerkey);
2500 chash_end(HMAC_MD5, &md5_base, src, Ustrlen(src), innerhash);
2501
2502 chash_start(HMAC_MD5, &md5_base);
2503 chash_mid(HMAC_MD5, &md5_base, outerkey);
2504 chash_end(HMAC_MD5, &md5_base, innerhash, MD5_HASHLEN, finalhash);
2505
2506 /* Encode the final hash as a hex string, limited by output buffer size */
2507
2508 p = buf;
2509 for (int i = 0, j = len; i < MD5_HASHLEN; i++)
2510   {
2511   if (j-- <= 0) break;
2512   *p++ = hex_digits[(finalhash[i] & 0xf0) >> 4];
2513   if (j-- <= 0) break;
2514   *p++ = hex_digits[finalhash[i] & 0x0f];
2515   }
2516 return;
2517 }
2518 #endif /*SUPPORT_SRS*/
2519
2520
2521 /*************************************************
2522 *        Read and evaluate a condition           *
2523 *************************************************/
2524
2525 /*
2526 Arguments:
2527   s        points to the start of the condition text
2528   resetok  points to a BOOL which is written false if it is unsafe to
2529            free memory. Certain condition types (acl) may have side-effect
2530            allocation which must be preserved.
2531   yield    points to a BOOL to hold the result of the condition test;
2532            if NULL, we are just reading through a condition that is
2533            part of an "or" combination to check syntax, or in a state
2534            where the answer isn't required
2535
2536 Returns:   a pointer to the first character after the condition, or
2537            NULL after an error
2538 */
2539
2540 static const uschar *
2541 eval_condition(const uschar *s, BOOL *resetok, BOOL *yield)
2542 {
2543 BOOL testfor = TRUE;
2544 BOOL tempcond, combined_cond;
2545 BOOL *subcondptr;
2546 BOOL sub2_honour_dollar = TRUE;
2547 BOOL is_forany, is_json, is_jsons;
2548 int rc, cond_type, roffset;
2549 int_eximarith_t num[2];
2550 struct stat statbuf;
2551 uschar * opname;
2552 uschar name[256];
2553 const uschar *sub[10];
2554
2555 const pcre *re;
2556 const uschar *rerror;
2557
2558 for (;;)
2559   if (Uskip_whitespace(&s) == '!') { testfor = !testfor; s++; } else break;
2560
2561 switch(cond_type = identify_operator(&s, &opname))
2562   {
2563   /* def: tests for a non-empty variable, or for the existence of a header. If
2564   yield == NULL we are in a skipping state, and don't care about the answer. */
2565
2566   case ECOND_DEF:
2567     {
2568     uschar * t;
2569
2570     if (*s != ':')
2571       {
2572       expand_string_message = US"\":\" expected after \"def\"";
2573       return NULL;
2574       }
2575
2576     s = read_name(name, sizeof(name), s+1, US"_");
2577
2578     /* Test for a header's existence. If the name contains a closing brace
2579     character, this may be a user error where the terminating colon has been
2580     omitted. Set a flag to adjust a subsequent error message in this case. */
2581
2582     if (  ( *(t = name) == 'h'
2583           || (*t == 'r' || *t == 'l' || *t == 'b') && *++t == 'h'
2584           )
2585        && (*++t == '_' || Ustrncmp(t, "eader_", 6) == 0)
2586        )
2587       {
2588       s = read_header_name(name, sizeof(name), s);
2589       /* {-for-text-editors */
2590       if (Ustrchr(name, '}') != NULL) malformed_header = TRUE;
2591       if (yield) *yield =
2592         (find_header(name, NULL, FH_EXISTS_ONLY, NULL) != NULL) == testfor;
2593       }
2594
2595     /* Test for a variable's having a non-empty value. A non-existent variable
2596     causes an expansion failure. */
2597
2598     else
2599       {
2600       if (!(t = find_variable(name, TRUE, yield == NULL, NULL)))
2601         {
2602         expand_string_message = name[0]
2603           ? string_sprintf("unknown variable \"%s\" after \"def:\"", name)
2604           : US"variable name omitted after \"def:\"";
2605         check_variable_error_message(name);
2606         return NULL;
2607         }
2608       if (yield) *yield = (t[0] != 0) == testfor;
2609       }
2610
2611     return s;
2612     }
2613
2614
2615   /* first_delivery tests for first delivery attempt */
2616
2617   case ECOND_FIRST_DELIVERY:
2618   if (yield) *yield = f.deliver_firsttime == testfor;
2619   return s;
2620
2621
2622   /* queue_running tests for any process started by a queue runner */
2623
2624   case ECOND_QUEUE_RUNNING:
2625   if (yield) *yield = (queue_run_pid != (pid_t)0) == testfor;
2626   return s;
2627
2628
2629   /* exists:  tests for file existence
2630        isip:  tests for any IP address
2631       isip4:  tests for an IPv4 address
2632       isip6:  tests for an IPv6 address
2633         pam:  does PAM authentication
2634      radius:  does RADIUS authentication
2635    ldapauth:  does LDAP authentication
2636     pwcheck:  does Cyrus SASL pwcheck authentication
2637   */
2638
2639   case ECOND_EXISTS:
2640   case ECOND_ISIP:
2641   case ECOND_ISIP4:
2642   case ECOND_ISIP6:
2643   case ECOND_PAM:
2644   case ECOND_RADIUS:
2645   case ECOND_LDAPAUTH:
2646   case ECOND_PWCHECK:
2647
2648   if (Uskip_whitespace(&s) != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2649
2650   sub[0] = expand_string_internal(s+1, TRUE, &s, yield == NULL, TRUE, resetok);
2651   if (!sub[0]) return NULL;
2652   /* {-for-text-editors */
2653   if (*s++ != '}') goto COND_FAILED_CURLY_END;
2654
2655   if (!yield) return s;   /* No need to run the test if skipping */
2656
2657   switch(cond_type)
2658     {
2659     case ECOND_EXISTS:
2660     if ((expand_forbid & RDO_EXISTS) != 0)
2661       {
2662       expand_string_message = US"File existence tests are not permitted";
2663       return NULL;
2664       }
2665     *yield = (Ustat(sub[0], &statbuf) == 0) == testfor;
2666     break;
2667
2668     case ECOND_ISIP:
2669     case ECOND_ISIP4:
2670     case ECOND_ISIP6:
2671     rc = string_is_ip_address(sub[0], NULL);
2672     *yield = ((cond_type == ECOND_ISIP)? (rc != 0) :
2673              (cond_type == ECOND_ISIP4)? (rc == 4) : (rc == 6)) == testfor;
2674     break;
2675
2676     /* Various authentication tests - all optionally compiled */
2677
2678     case ECOND_PAM:
2679     #ifdef SUPPORT_PAM
2680     rc = auth_call_pam(sub[0], &expand_string_message);
2681     goto END_AUTH;
2682     #else
2683     goto COND_FAILED_NOT_COMPILED;
2684     #endif  /* SUPPORT_PAM */
2685
2686     case ECOND_RADIUS:
2687     #ifdef RADIUS_CONFIG_FILE
2688     rc = auth_call_radius(sub[0], &expand_string_message);
2689     goto END_AUTH;
2690     #else
2691     goto COND_FAILED_NOT_COMPILED;
2692     #endif  /* RADIUS_CONFIG_FILE */
2693
2694     case ECOND_LDAPAUTH:
2695     #ifdef LOOKUP_LDAP
2696       {
2697       /* Just to keep the interface the same */
2698       BOOL do_cache;
2699       int old_pool = store_pool;
2700       store_pool = POOL_SEARCH;
2701       rc = eldapauth_find((void *)(-1), NULL, sub[0], Ustrlen(sub[0]), NULL,
2702         &expand_string_message, &do_cache);
2703       store_pool = old_pool;
2704       }
2705     goto END_AUTH;
2706     #else
2707     goto COND_FAILED_NOT_COMPILED;
2708     #endif  /* LOOKUP_LDAP */
2709
2710     case ECOND_PWCHECK:
2711     #ifdef CYRUS_PWCHECK_SOCKET
2712     rc = auth_call_pwcheck(sub[0], &expand_string_message);
2713     goto END_AUTH;
2714     #else
2715     goto COND_FAILED_NOT_COMPILED;
2716     #endif  /* CYRUS_PWCHECK_SOCKET */
2717
2718     #if defined(SUPPORT_PAM) || defined(RADIUS_CONFIG_FILE) || \
2719         defined(LOOKUP_LDAP) || defined(CYRUS_PWCHECK_SOCKET)
2720     END_AUTH:
2721     if (rc == ERROR || rc == DEFER) return NULL;
2722     *yield = (rc == OK) == testfor;
2723     #endif
2724     }
2725   return s;
2726
2727
2728   /* call ACL (in a conditional context).  Accept true, deny false.
2729   Defer is a forced-fail.  Anything set by message= goes to $value.
2730   Up to ten parameters are used; we use the braces round the name+args
2731   like the saslauthd condition does, to permit a variable number of args.
2732   See also the expansion-item version EITEM_ACL and the traditional
2733   acl modifier ACLC_ACL.
2734   Since the ACL may allocate new global variables, tell our caller to not
2735   reclaim memory.
2736   */
2737
2738   case ECOND_ACL:
2739     /* ${if acl {{name}{arg1}{arg2}...}  {yes}{no}} */
2740     {
2741     uschar *sub[10];
2742     uschar *user_msg;
2743     BOOL cond = FALSE;
2744
2745     Uskip_whitespace(&s);
2746     if (*s++ != '{') goto COND_FAILED_CURLY_START;      /*}*/
2747
2748     switch(read_subs(sub, nelem(sub), 1,
2749       &s, yield == NULL, TRUE, name, resetok))
2750       {
2751       case 1: expand_string_message = US"too few arguments or bracketing "
2752         "error for acl";
2753       case 2:
2754       case 3: return NULL;
2755       }
2756
2757     if (yield)
2758       {
2759       int rc;
2760       *resetok = FALSE; /* eval_acl() might allocate; do not reclaim */
2761       switch(rc = eval_acl(sub, nelem(sub), &user_msg))
2762         {
2763         case OK:
2764           cond = TRUE;
2765         case FAIL:
2766           lookup_value = NULL;
2767           if (user_msg)
2768             lookup_value = string_copy(user_msg);
2769           *yield = cond == testfor;
2770           break;
2771
2772         case DEFER:
2773           f.expand_string_forcedfail = TRUE;
2774           /*FALLTHROUGH*/
2775         default:
2776           expand_string_message = string_sprintf("%s from acl \"%s\"",
2777             rc_names[rc], sub[0]);
2778           return NULL;
2779         }
2780       }
2781     return s;
2782     }
2783
2784
2785   /* saslauthd: does Cyrus saslauthd authentication. Four parameters are used:
2786
2787      ${if saslauthd {{username}{password}{service}{realm}}  {yes}{no}}
2788
2789   However, the last two are optional. That is why the whole set is enclosed
2790   in their own set of braces. */
2791
2792   case ECOND_SASLAUTHD:
2793 #ifndef CYRUS_SASLAUTHD_SOCKET
2794     goto COND_FAILED_NOT_COMPILED;
2795 #else
2796     {
2797     uschar *sub[4];
2798     Uskip_whitespace(&s);
2799     if (*s++ != '{') goto COND_FAILED_CURLY_START;      /* }-for-text-editors */
2800     switch(read_subs(sub, nelem(sub), 2, &s, yield == NULL, TRUE, name,
2801                     resetok))
2802       {
2803       case 1: expand_string_message = US"too few arguments or bracketing "
2804         "error for saslauthd";
2805       case 2:
2806       case 3: return NULL;
2807       }
2808     if (!sub[2]) sub[3] = NULL;  /* realm if no service */
2809     if (yield)
2810       {
2811       int rc = auth_call_saslauthd(sub[0], sub[1], sub[2], sub[3],
2812         &expand_string_message);
2813       if (rc == ERROR || rc == DEFER) return NULL;
2814       *yield = (rc == OK) == testfor;
2815       }
2816     return s;
2817     }
2818 #endif /* CYRUS_SASLAUTHD_SOCKET */
2819
2820
2821   /* symbolic operators for numeric and string comparison, and a number of
2822   other operators, all requiring two arguments.
2823
2824   crypteq:           encrypts plaintext and compares against an encrypted text,
2825                        using crypt(), crypt16(), MD5 or SHA-1
2826   inlist/inlisti:    checks if first argument is in the list of the second
2827   match:             does a regular expression match and sets up the numerical
2828                        variables if it succeeds
2829   match_address:     matches in an address list
2830   match_domain:      matches in a domain list
2831   match_ip:          matches a host list that is restricted to IP addresses
2832   match_local_part:  matches in a local part list
2833   */
2834
2835   case ECOND_MATCH_ADDRESS:
2836   case ECOND_MATCH_DOMAIN:
2837   case ECOND_MATCH_IP:
2838   case ECOND_MATCH_LOCAL_PART:
2839 #ifndef EXPAND_LISTMATCH_RHS
2840     sub2_honour_dollar = FALSE;
2841 #endif
2842     /* FALLTHROUGH */
2843
2844   case ECOND_CRYPTEQ:
2845   case ECOND_INLIST:
2846   case ECOND_INLISTI:
2847   case ECOND_MATCH:
2848
2849   case ECOND_NUM_L:     /* Numerical comparisons */
2850   case ECOND_NUM_LE:
2851   case ECOND_NUM_E:
2852   case ECOND_NUM_EE:
2853   case ECOND_NUM_G:
2854   case ECOND_NUM_GE:
2855
2856   case ECOND_STR_LT:    /* String comparisons */
2857   case ECOND_STR_LTI:
2858   case ECOND_STR_LE:
2859   case ECOND_STR_LEI:
2860   case ECOND_STR_EQ:
2861   case ECOND_STR_EQI:
2862   case ECOND_STR_GT:
2863   case ECOND_STR_GTI:
2864   case ECOND_STR_GE:
2865   case ECOND_STR_GEI:
2866
2867   for (int i = 0; i < 2; i++)
2868     {
2869     /* Sometimes, we don't expand substrings; too many insecure configurations
2870     created using match_address{}{} and friends, where the second param
2871     includes information from untrustworthy sources. */
2872     BOOL honour_dollar = TRUE;
2873     if ((i > 0) && !sub2_honour_dollar)
2874       honour_dollar = FALSE;
2875
2876     if (Uskip_whitespace(&s) != '{')
2877       {
2878       if (i == 0) goto COND_FAILED_CURLY_START;
2879       expand_string_message = string_sprintf("missing 2nd string in {} "
2880         "after \"%s\"", opname);
2881       return NULL;
2882       }
2883     if (!(sub[i] = expand_string_internal(s+1, TRUE, &s, yield == NULL,
2884         honour_dollar, resetok)))
2885       return NULL;
2886     DEBUG(D_expand) if (i == 1 && !sub2_honour_dollar && Ustrchr(sub[1], '$'))
2887       debug_printf_indent("WARNING: the second arg is NOT expanded,"
2888                         " for security reasons\n");
2889     if (*s++ != '}') goto COND_FAILED_CURLY_END;
2890
2891     /* Convert to numerical if required; we know that the names of all the
2892     conditions that compare numbers do not start with a letter. This just saves
2893     checking for them individually. */
2894
2895     if (!isalpha(opname[0]) && yield)
2896       if (sub[i][0] == 0)
2897         {
2898         num[i] = 0;
2899         DEBUG(D_expand)
2900           debug_printf_indent("empty string cast to zero for numerical comparison\n");
2901         }
2902       else
2903         {
2904         num[i] = expanded_string_integer(sub[i], FALSE);
2905         if (expand_string_message) return NULL;
2906         }
2907     }
2908
2909   /* Result not required */
2910
2911   if (!yield) return s;
2912
2913   /* Do an appropriate comparison */
2914
2915   switch(cond_type)
2916     {
2917     case ECOND_NUM_E:
2918     case ECOND_NUM_EE:
2919     tempcond = (num[0] == num[1]);
2920     break;
2921
2922     case ECOND_NUM_G:
2923     tempcond = (num[0] > num[1]);
2924     break;
2925
2926     case ECOND_NUM_GE:
2927     tempcond = (num[0] >= num[1]);
2928     break;
2929
2930     case ECOND_NUM_L:
2931     tempcond = (num[0] < num[1]);
2932     break;
2933
2934     case ECOND_NUM_LE:
2935     tempcond = (num[0] <= num[1]);
2936     break;
2937
2938     case ECOND_STR_LT:
2939     tempcond = (Ustrcmp(sub[0], sub[1]) < 0);
2940     break;
2941
2942     case ECOND_STR_LTI:
2943     tempcond = (strcmpic(sub[0], sub[1]) < 0);
2944     break;
2945
2946     case ECOND_STR_LE:
2947     tempcond = (Ustrcmp(sub[0], sub[1]) <= 0);
2948     break;
2949
2950     case ECOND_STR_LEI:
2951     tempcond = (strcmpic(sub[0], sub[1]) <= 0);
2952     break;
2953
2954     case ECOND_STR_EQ:
2955     tempcond = (Ustrcmp(sub[0], sub[1]) == 0);
2956     break;
2957
2958     case ECOND_STR_EQI:
2959     tempcond = (strcmpic(sub[0], sub[1]) == 0);
2960     break;
2961
2962     case ECOND_STR_GT:
2963     tempcond = (Ustrcmp(sub[0], sub[1]) > 0);
2964     break;
2965
2966     case ECOND_STR_GTI:
2967     tempcond = (strcmpic(sub[0], sub[1]) > 0);
2968     break;
2969
2970     case ECOND_STR_GE:
2971     tempcond = (Ustrcmp(sub[0], sub[1]) >= 0);
2972     break;
2973
2974     case ECOND_STR_GEI:
2975     tempcond = (strcmpic(sub[0], sub[1]) >= 0);
2976     break;
2977
2978     case ECOND_MATCH:   /* Regular expression match */
2979     if (!(re = pcre_compile(CS sub[1], PCRE_COPT, CCSS &rerror,
2980                             &roffset, NULL)))
2981       {
2982       expand_string_message = string_sprintf("regular expression error in "
2983         "\"%s\": %s at offset %d", sub[1], rerror, roffset);
2984       return NULL;
2985       }
2986     tempcond = regex_match_and_setup(re, sub[0], 0, -1);
2987     break;
2988
2989     case ECOND_MATCH_ADDRESS:  /* Match in an address list */
2990     rc = match_address_list(sub[0], TRUE, FALSE, &(sub[1]), NULL, -1, 0, NULL);
2991     goto MATCHED_SOMETHING;
2992
2993     case ECOND_MATCH_DOMAIN:   /* Match in a domain list */
2994     rc = match_isinlist(sub[0], &(sub[1]), 0, &domainlist_anchor, NULL,
2995       MCL_DOMAIN + MCL_NOEXPAND, TRUE, NULL);
2996     goto MATCHED_SOMETHING;
2997
2998     case ECOND_MATCH_IP:       /* Match IP address in a host list */
2999     if (sub[0][0] != 0 && string_is_ip_address(sub[0], NULL) == 0)
3000       {
3001       expand_string_message = string_sprintf("\"%s\" is not an IP address",
3002         sub[0]);
3003       return NULL;
3004       }
3005     else
3006       {
3007       unsigned int *nullcache = NULL;
3008       check_host_block cb;
3009
3010       cb.host_name = US"";
3011       cb.host_address = sub[0];
3012
3013       /* If the host address starts off ::ffff: it is an IPv6 address in
3014       IPv4-compatible mode. Find the IPv4 part for checking against IPv4
3015       addresses. */
3016
3017       cb.host_ipv4 = (Ustrncmp(cb.host_address, "::ffff:", 7) == 0)?
3018         cb.host_address + 7 : cb.host_address;
3019
3020       rc = match_check_list(
3021              &sub[1],                   /* the list */
3022              0,                         /* separator character */
3023              &hostlist_anchor,          /* anchor pointer */
3024              &nullcache,                /* cache pointer */
3025              check_host,                /* function for testing */
3026              &cb,                       /* argument for function */
3027              MCL_HOST,                  /* type of check */
3028              sub[0],                    /* text for debugging */
3029              NULL);                     /* where to pass back data */
3030       }
3031     goto MATCHED_SOMETHING;
3032
3033     case ECOND_MATCH_LOCAL_PART:
3034     rc = match_isinlist(sub[0], &(sub[1]), 0, &localpartlist_anchor, NULL,
3035       MCL_LOCALPART + MCL_NOEXPAND, TRUE, NULL);
3036     /* Fall through */
3037     /* VVVVVVVVVVVV */
3038     MATCHED_SOMETHING:
3039     switch(rc)
3040       {
3041       case OK:
3042       tempcond = TRUE;
3043       break;
3044
3045       case FAIL:
3046       tempcond = FALSE;
3047       break;
3048
3049       case DEFER:
3050       expand_string_message = string_sprintf("unable to complete match "
3051         "against \"%s\": %s", sub[1], search_error_message);
3052       return NULL;
3053       }
3054
3055     break;
3056
3057     /* Various "encrypted" comparisons. If the second string starts with
3058     "{" then an encryption type is given. Default to crypt() or crypt16()
3059     (build-time choice). */
3060     /* }-for-text-editors */
3061
3062     case ECOND_CRYPTEQ:
3063     #ifndef SUPPORT_CRYPTEQ
3064     goto COND_FAILED_NOT_COMPILED;
3065     #else
3066     if (strncmpic(sub[1], US"{md5}", 5) == 0)
3067       {
3068       int sublen = Ustrlen(sub[1]+5);
3069       md5 base;
3070       uschar digest[16];
3071
3072       md5_start(&base);
3073       md5_end(&base, sub[0], Ustrlen(sub[0]), digest);
3074
3075       /* If the length that we are comparing against is 24, the MD5 digest
3076       is expressed as a base64 string. This is the way LDAP does it. However,
3077       some other software uses a straightforward hex representation. We assume
3078       this if the length is 32. Other lengths fail. */
3079
3080       if (sublen == 24)
3081         {
3082         uschar *coded = b64encode(CUS digest, 16);
3083         DEBUG(D_auth) debug_printf("crypteq: using MD5+B64 hashing\n"
3084           "  subject=%s\n  crypted=%s\n", coded, sub[1]+5);
3085         tempcond = (Ustrcmp(coded, sub[1]+5) == 0);
3086         }
3087       else if (sublen == 32)
3088         {
3089         uschar coded[36];
3090         for (int i = 0; i < 16; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
3091         coded[32] = 0;
3092         DEBUG(D_auth) debug_printf("crypteq: using MD5+hex hashing\n"
3093           "  subject=%s\n  crypted=%s\n", coded, sub[1]+5);
3094         tempcond = (strcmpic(coded, sub[1]+5) == 0);
3095         }
3096       else
3097         {
3098         DEBUG(D_auth) debug_printf("crypteq: length for MD5 not 24 or 32: "
3099           "fail\n  crypted=%s\n", sub[1]+5);
3100         tempcond = FALSE;
3101         }
3102       }
3103
3104     else if (strncmpic(sub[1], US"{sha1}", 6) == 0)
3105       {
3106       int sublen = Ustrlen(sub[1]+6);
3107       hctx h;
3108       uschar digest[20];
3109
3110       sha1_start(&h);
3111       sha1_end(&h, sub[0], Ustrlen(sub[0]), digest);
3112
3113       /* If the length that we are comparing against is 28, assume the SHA1
3114       digest is expressed as a base64 string. If the length is 40, assume a
3115       straightforward hex representation. Other lengths fail. */
3116
3117       if (sublen == 28)
3118         {
3119         uschar *coded = b64encode(CUS digest, 20);
3120         DEBUG(D_auth) debug_printf("crypteq: using SHA1+B64 hashing\n"
3121           "  subject=%s\n  crypted=%s\n", coded, sub[1]+6);
3122         tempcond = (Ustrcmp(coded, sub[1]+6) == 0);
3123         }
3124       else if (sublen == 40)
3125         {
3126         uschar coded[44];
3127         for (int i = 0; i < 20; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
3128         coded[40] = 0;
3129         DEBUG(D_auth) debug_printf("crypteq: using SHA1+hex hashing\n"
3130           "  subject=%s\n  crypted=%s\n", coded, sub[1]+6);
3131         tempcond = (strcmpic(coded, sub[1]+6) == 0);
3132         }
3133       else
3134         {
3135         DEBUG(D_auth) debug_printf("crypteq: length for SHA-1 not 28 or 40: "
3136           "fail\n  crypted=%s\n", sub[1]+6);
3137         tempcond = FALSE;
3138         }
3139       }
3140
3141     else   /* {crypt} or {crypt16} and non-{ at start */
3142            /* }-for-text-editors */
3143       {
3144       int which = 0;
3145       uschar *coded;
3146
3147       if (strncmpic(sub[1], US"{crypt}", 7) == 0)
3148         {
3149         sub[1] += 7;
3150         which = 1;
3151         }
3152       else if (strncmpic(sub[1], US"{crypt16}", 9) == 0)
3153         {
3154         sub[1] += 9;
3155         which = 2;
3156         }
3157       else if (sub[1][0] == '{')                /* }-for-text-editors */
3158         {
3159         expand_string_message = string_sprintf("unknown encryption mechanism "
3160           "in \"%s\"", sub[1]);
3161         return NULL;
3162         }
3163
3164       switch(which)
3165         {
3166         case 0:  coded = US DEFAULT_CRYPT(CS sub[0], CS sub[1]); break;
3167         case 1:  coded = US crypt(CS sub[0], CS sub[1]); break;
3168         default: coded = US crypt16(CS sub[0], CS sub[1]); break;
3169         }
3170
3171       #define STR(s) # s
3172       #define XSTR(s) STR(s)
3173       DEBUG(D_auth) debug_printf("crypteq: using %s()\n"
3174         "  subject=%s\n  crypted=%s\n",
3175         which == 0 ? XSTR(DEFAULT_CRYPT) : which == 1 ? "crypt" : "crypt16",
3176         coded, sub[1]);
3177       #undef STR
3178       #undef XSTR
3179
3180       /* If the encrypted string contains fewer than two characters (for the
3181       salt), force failure. Otherwise we get false positives: with an empty
3182       string the yield of crypt() is an empty string! */
3183
3184       if (coded)
3185         tempcond = Ustrlen(sub[1]) < 2 ? FALSE : Ustrcmp(coded, sub[1]) == 0;
3186       else if (errno == EINVAL)
3187         tempcond = FALSE;
3188       else
3189         {
3190         expand_string_message = string_sprintf("crypt error: %s\n",
3191           US strerror(errno));
3192         return NULL;
3193         }
3194       }
3195     break;
3196     #endif  /* SUPPORT_CRYPTEQ */
3197
3198     case ECOND_INLIST:
3199     case ECOND_INLISTI:
3200       {
3201       const uschar * list = sub[1];
3202       int sep = 0;
3203       uschar *save_iterate_item = iterate_item;
3204       int (*compare)(const uschar *, const uschar *);
3205
3206       DEBUG(D_expand) debug_printf_indent("condition: %s  item: %s\n", opname, sub[0]);
3207
3208       tempcond = FALSE;
3209       compare = cond_type == ECOND_INLISTI
3210         ? strcmpic : (int (*)(const uschar *, const uschar *)) strcmp;
3211
3212       while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)))
3213         {
3214         DEBUG(D_expand) debug_printf_indent(" compare %s\n", iterate_item);
3215         if (compare(sub[0], iterate_item) == 0)
3216           {
3217           tempcond = TRUE;
3218           break;
3219           }
3220         }
3221       iterate_item = save_iterate_item;
3222       }
3223
3224     }   /* Switch for comparison conditions */
3225
3226   *yield = tempcond == testfor;
3227   return s;    /* End of comparison conditions */
3228
3229
3230   /* and/or: computes logical and/or of several conditions */
3231
3232   case ECOND_AND:
3233   case ECOND_OR:
3234   subcondptr = (yield == NULL) ? NULL : &tempcond;
3235   combined_cond = (cond_type == ECOND_AND);
3236
3237   Uskip_whitespace(&s);
3238   if (*s++ != '{') goto COND_FAILED_CURLY_START;        /* }-for-text-editors */
3239
3240   for (;;)
3241     {
3242     /* {-for-text-editors */
3243     if (Uskip_whitespace(&s) == '}') break;
3244     if (*s != '{')                                      /* }-for-text-editors */
3245       {
3246       expand_string_message = string_sprintf("each subcondition "
3247         "inside an \"%s{...}\" condition must be in its own {}", opname);
3248       return NULL;
3249       }
3250
3251     if (!(s = eval_condition(s+1, resetok, subcondptr)))
3252       {
3253       expand_string_message = string_sprintf("%s inside \"%s{...}\" condition",
3254         expand_string_message, opname);
3255       return NULL;
3256       }
3257     Uskip_whitespace(&s);
3258
3259     /* {-for-text-editors */
3260     if (*s++ != '}')
3261       {
3262       /* {-for-text-editors */
3263       expand_string_message = string_sprintf("missing } at end of condition "
3264         "inside \"%s\" group", opname);
3265       return NULL;
3266       }
3267
3268     if (yield)
3269       if (cond_type == ECOND_AND)
3270         {
3271         combined_cond &= tempcond;
3272         if (!combined_cond) subcondptr = NULL;  /* once false, don't */
3273         }                                       /* evaluate any more */
3274       else
3275         {
3276         combined_cond |= tempcond;
3277         if (combined_cond) subcondptr = NULL;   /* once true, don't */
3278         }                                       /* evaluate any more */
3279     }
3280
3281   if (yield) *yield = (combined_cond == testfor);
3282   return ++s;
3283
3284
3285   /* forall/forany: iterates a condition with different values */
3286
3287   case ECOND_FORALL:      is_forany = FALSE;  is_json = FALSE; is_jsons = FALSE; goto FORMANY;
3288   case ECOND_FORANY:      is_forany = TRUE;   is_json = FALSE; is_jsons = FALSE; goto FORMANY;
3289   case ECOND_FORALL_JSON: is_forany = FALSE;  is_json = TRUE;  is_jsons = FALSE; goto FORMANY;
3290   case ECOND_FORANY_JSON: is_forany = TRUE;   is_json = TRUE;  is_jsons = FALSE; goto FORMANY;
3291   case ECOND_FORALL_JSONS: is_forany = FALSE; is_json = TRUE;  is_jsons = TRUE;  goto FORMANY;
3292   case ECOND_FORANY_JSONS: is_forany = TRUE;  is_json = TRUE;  is_jsons = TRUE;  goto FORMANY;
3293
3294   FORMANY:
3295     {
3296     const uschar * list;
3297     int sep = 0;
3298     uschar *save_iterate_item = iterate_item;
3299
3300     DEBUG(D_expand) debug_printf_indent("condition: %s\n", opname);
3301
3302     Uskip_whitespace(&s);
3303     if (*s++ != '{') goto COND_FAILED_CURLY_START;      /* }-for-text-editors */
3304     if (!(sub[0] = expand_string_internal(s, TRUE, &s, yield == NULL, TRUE, resetok)))
3305       return NULL;
3306     /* {-for-text-editors */
3307     if (*s++ != '}') goto COND_FAILED_CURLY_END;
3308
3309     Uskip_whitespace(&s);
3310     if (*s++ != '{') goto COND_FAILED_CURLY_START;      /* }-for-text-editors */
3311
3312     sub[1] = s;
3313
3314     /* Call eval_condition once, with result discarded (as if scanning a
3315     "false" part). This allows us to find the end of the condition, because if
3316     the list it empty, we won't actually evaluate the condition for real. */
3317
3318     if (!(s = eval_condition(sub[1], resetok, NULL)))
3319       {
3320       expand_string_message = string_sprintf("%s inside \"%s\" condition",
3321         expand_string_message, opname);
3322       return NULL;
3323       }
3324     Uskip_whitespace(&s);
3325
3326     /* {-for-text-editors */
3327     if (*s++ != '}')
3328       {
3329       /* {-for-text-editors */
3330       expand_string_message = string_sprintf("missing } at end of condition "
3331         "inside \"%s\"", opname);
3332       return NULL;
3333       }
3334
3335     if (yield) *yield = !testfor;
3336     list = sub[0];
3337     if (is_json) list = dewrap(string_copy(list), US"[]");
3338     while ((iterate_item = is_json
3339       ? json_nextinlist(&list) : string_nextinlist(&list, &sep, NULL, 0)))
3340       {
3341       if (is_jsons)
3342         if (!(iterate_item = dewrap(iterate_item, US"\"\"")))
3343           {
3344           expand_string_message =
3345             string_sprintf("%s wrapping string result for extract jsons",
3346               expand_string_message);
3347           iterate_item = save_iterate_item;
3348           return NULL;
3349           }
3350
3351       DEBUG(D_expand) debug_printf_indent("%s: $item = \"%s\"\n", opname, iterate_item);
3352       if (!eval_condition(sub[1], resetok, &tempcond))
3353         {
3354         expand_string_message = string_sprintf("%s inside \"%s\" condition",
3355           expand_string_message, opname);
3356         iterate_item = save_iterate_item;
3357         return NULL;
3358         }
3359       DEBUG(D_expand) debug_printf_indent("%s: condition evaluated to %s\n", opname,
3360         tempcond? "true":"false");
3361
3362       if (yield) *yield = (tempcond == testfor);
3363       if (tempcond == is_forany) break;
3364       }
3365
3366     iterate_item = save_iterate_item;
3367     return s;
3368     }
3369
3370
3371   /* The bool{} expansion condition maps a string to boolean.
3372   The values supported should match those supported by the ACL condition
3373   (acl.c, ACLC_CONDITION) so that we keep to a minimum the different ideas
3374   of true/false.  Note that Router "condition" rules have a different
3375   interpretation, where general data can be used and only a few values
3376   map to FALSE.
3377   Note that readconf.c boolean matching, for boolean configuration options,
3378   only matches true/yes/false/no.
3379   The bool_lax{} condition matches the Router logic, which is much more
3380   liberal. */
3381   case ECOND_BOOL:
3382   case ECOND_BOOL_LAX:
3383     {
3384     uschar *sub_arg[1];
3385     uschar *t, *t2;
3386     uschar *ourname;
3387     size_t len;
3388     BOOL boolvalue = FALSE;
3389
3390     if (Uskip_whitespace(&s) != '{') goto COND_FAILED_CURLY_START;      /* }-for-text-editors */
3391     ourname = cond_type == ECOND_BOOL_LAX ? US"bool_lax" : US"bool";
3392     switch(read_subs(sub_arg, 1, 1, &s, yield == NULL, FALSE, ourname, resetok))
3393       {
3394       case 1: expand_string_message = string_sprintf(
3395                   "too few arguments or bracketing error for %s",
3396                   ourname);
3397       /*FALLTHROUGH*/
3398       case 2:
3399       case 3: return NULL;
3400       }
3401     t = sub_arg[0];
3402     Uskip_whitespace(&t);
3403     if ((len = Ustrlen(t)))
3404       {
3405       /* trailing whitespace: seems like a good idea to ignore it too */
3406       t2 = t + len - 1;
3407       while (isspace(*t2)) t2--;
3408       if (t2 != (t + len))
3409         {
3410         *++t2 = '\0';
3411         len = t2 - t;
3412         }
3413       }
3414     DEBUG(D_expand)
3415       debug_printf_indent("considering %s: %s\n", ourname, len ? t : US"<empty>");
3416     /* logic for the lax case from expand_check_condition(), which also does
3417     expands, and the logic is both short and stable enough that there should
3418     be no maintenance burden from replicating it. */
3419     if (len == 0)
3420       boolvalue = FALSE;
3421     else if (*t == '-'
3422              ? Ustrspn(t+1, "0123456789") == len-1
3423              : Ustrspn(t,   "0123456789") == len)
3424       {
3425       boolvalue = (Uatoi(t) == 0) ? FALSE : TRUE;
3426       /* expand_check_condition only does a literal string "0" check */
3427       if ((cond_type == ECOND_BOOL_LAX) && (len > 1))
3428         boolvalue = TRUE;
3429       }
3430     else if (strcmpic(t, US"true") == 0 || strcmpic(t, US"yes") == 0)
3431       boolvalue = TRUE;
3432     else if (strcmpic(t, US"false") == 0 || strcmpic(t, US"no") == 0)
3433       boolvalue = FALSE;
3434     else if (cond_type == ECOND_BOOL_LAX)
3435       boolvalue = TRUE;
3436     else
3437       {
3438       expand_string_message = string_sprintf("unrecognised boolean "
3439        "value \"%s\"", t);
3440       return NULL;
3441       }
3442     DEBUG(D_expand) debug_printf_indent("%s: condition evaluated to %s\n", ourname,
3443         boolvalue? "true":"false");
3444     if (yield) *yield = (boolvalue == testfor);
3445     return s;
3446     }
3447
3448 #ifdef SUPPORT_SRS
3449   case ECOND_INBOUND_SRS:
3450     /* ${if inbound_srs {local_part}{secret}  {yes}{no}} */
3451     {
3452     uschar * sub[2];
3453     const pcre * re;
3454     int ovec[3*(4+1)];
3455     int n, quoting = 0;
3456     uschar cksum[4];
3457     BOOL boolvalue = FALSE;
3458
3459     switch(read_subs(sub, 2, 2, CUSS &s, yield == NULL, FALSE, name, resetok))
3460       {
3461       case 1: expand_string_message = US"too few arguments or bracketing "
3462         "error for inbound_srs";
3463       case 2:
3464       case 3: return NULL;
3465       }
3466
3467     /* Match the given local_part against the SRS-encoded pattern */
3468
3469     re = regex_must_compile(US"^(?i)SRS0=([^=]+)=([A-Z2-7]+)=([^=]*)=(.*)$",
3470                             TRUE, FALSE);
3471     if (pcre_exec(re, NULL, CS sub[0], Ustrlen(sub[0]), 0, PCRE_EOPT,
3472                   ovec, nelem(ovec)) < 0)
3473       {
3474       DEBUG(D_expand) debug_printf("no match for SRS'd local-part pattern\n");
3475       goto srs_result;
3476       }
3477
3478     if (sub[0][0] == '"')
3479       quoting = 1;
3480     else for (uschar * s = sub[0]; *s; s++)
3481       if (!isalnum(*s) && Ustrchr(".!#$%&'*+-/=?^_`{|}~", *s) == NULL)
3482         { quoting = 1; break; }
3483     if (quoting)
3484       DEBUG(D_expand) debug_printf_indent("auto-quoting local part\n");
3485
3486     /* Record the (quoted, if needed) decoded recipient as $srs_recipient */
3487
3488     srs_recipient = string_sprintf("%.*s%.*S%.*s@%.*S",         /* lowercased */
3489                       quoting, "\"",
3490                       ovec[9]-ovec[8], sub[0] + ovec[8],        /* substring 4 */
3491                       quoting, "\"",
3492                       ovec[7]-ovec[6], sub[0] + ovec[6]);       /* substring 3 */
3493
3494     /* If a zero-length secret was given, we're done.  Otherwise carry on
3495     and validate the given SRS local_part againt our secret. */
3496
3497     if (!*sub[1])
3498       {
3499       boolvalue = TRUE;
3500       goto srs_result;
3501       }
3502
3503     /* check the timestamp */
3504       {
3505       struct timeval now;
3506       uschar * ss = sub[0] + ovec[4];   /* substring 2, the timestamp */
3507       long d;
3508
3509       gettimeofday(&now, NULL);
3510       now.tv_sec /= 86400;              /* days since epoch */
3511
3512       /* Decode substring 2 from base32 to a number */
3513
3514       for (d = 0, n = ovec[5]-ovec[4]; n; n--)
3515         {
3516         uschar * t = Ustrchr(base32_chars, *ss++);
3517         d = d * 32 + (t - base32_chars);
3518         }
3519
3520       if (((now.tv_sec - d) & 0x3ff) > 10)      /* days since SRS generated */
3521         {
3522         DEBUG(D_expand) debug_printf("SRS too old\n");
3523         goto srs_result;
3524         }
3525       }
3526
3527     /* check length of substring 1, the offered checksum */
3528
3529     if (ovec[3]-ovec[2] != 4)
3530       {
3531       DEBUG(D_expand) debug_printf("SRS checksum wrong size\n");
3532       goto srs_result;
3533       }
3534
3535     /* Hash the address with our secret, and compare that computed checksum
3536     with the one extracted from the arg */
3537
3538     hmac_md5(sub[1], srs_recipient, cksum, sizeof(cksum));
3539     if (Ustrncmp(cksum, sub[0] + ovec[2], 4) != 0)
3540       {
3541       DEBUG(D_expand) debug_printf("SRS checksum mismatch\n");
3542       goto srs_result;
3543       }
3544     boolvalue = TRUE;
3545
3546 srs_result:
3547     if (yield) *yield = (boolvalue == testfor);
3548     return s;
3549     }
3550 #endif /*SUPPORT_SRS*/
3551
3552   /* Unknown condition */
3553
3554   default:
3555     if (!expand_string_message || !*expand_string_message)
3556       expand_string_message = string_sprintf("unknown condition \"%s\"", opname);
3557     return NULL;
3558   }   /* End switch on condition type */
3559
3560 /* Missing braces at start and end of data */
3561
3562 COND_FAILED_CURLY_START:
3563 expand_string_message = string_sprintf("missing { after \"%s\"", opname);
3564 return NULL;
3565
3566 COND_FAILED_CURLY_END:
3567 expand_string_message = string_sprintf("missing } at end of \"%s\" condition",
3568   opname);
3569 return NULL;
3570
3571 /* A condition requires code that is not compiled */
3572
3573 #if !defined(SUPPORT_PAM) || !defined(RADIUS_CONFIG_FILE) || \
3574     !defined(LOOKUP_LDAP) || !defined(CYRUS_PWCHECK_SOCKET) || \
3575     !defined(SUPPORT_CRYPTEQ) || !defined(CYRUS_SASLAUTHD_SOCKET)
3576 COND_FAILED_NOT_COMPILED:
3577 expand_string_message = string_sprintf("support for \"%s\" not compiled",
3578   opname);
3579 return NULL;
3580 #endif
3581 }
3582
3583
3584
3585
3586 /*************************************************
3587 *          Save numerical variables              *
3588 *************************************************/
3589
3590 /* This function is called from items such as "if" that want to preserve and
3591 restore the numbered variables.
3592
3593 Arguments:
3594   save_expand_string    points to an array of pointers to set
3595   save_expand_nlength   points to an array of ints for the lengths
3596
3597 Returns:                the value of expand max to save
3598 */
3599
3600 static int
3601 save_expand_strings(uschar **save_expand_nstring, int *save_expand_nlength)
3602 {
3603 for (int i = 0; i <= expand_nmax; i++)
3604   {
3605   save_expand_nstring[i] = expand_nstring[i];
3606   save_expand_nlength[i] = expand_nlength[i];
3607   }
3608 return expand_nmax;
3609 }
3610
3611
3612
3613 /*************************************************
3614 *           Restore numerical variables          *
3615 *************************************************/
3616
3617 /* This function restored saved values of numerical strings.
3618
3619 Arguments:
3620   save_expand_nmax      the number of strings to restore
3621   save_expand_string    points to an array of pointers
3622   save_expand_nlength   points to an array of ints
3623
3624 Returns:                nothing
3625 */
3626
3627 static void
3628 restore_expand_strings(int save_expand_nmax, uschar **save_expand_nstring,
3629   int *save_expand_nlength)
3630 {
3631 expand_nmax = save_expand_nmax;
3632 for (int i = 0; i <= expand_nmax; i++)
3633   {
3634   expand_nstring[i] = save_expand_nstring[i];
3635   expand_nlength[i] = save_expand_nlength[i];
3636   }
3637 }
3638
3639
3640
3641
3642
3643 /*************************************************
3644 *            Handle yes/no substrings            *
3645 *************************************************/
3646
3647 /* This function is used by ${if}, ${lookup} and ${extract} to handle the
3648 alternative substrings that depend on whether or not the condition was true,
3649 or the lookup or extraction succeeded. The substrings always have to be
3650 expanded, to check their syntax, but "skipping" is set when the result is not
3651 needed - this avoids unnecessary nested lookups.
3652
3653 Arguments:
3654   skipping       TRUE if we were skipping when this item was reached
3655   yes            TRUE if the first string is to be used, else use the second
3656   save_lookup    a value to put back into lookup_value before the 2nd expansion
3657   sptr           points to the input string pointer
3658   yieldptr       points to the output growable-string pointer
3659   type           "lookup", "if", "extract", "run", "env", "listextract" or
3660                  "certextract" for error message
3661   resetok        if not NULL, pointer to flag - write FALSE if unsafe to reset
3662                 the store.
3663
3664 Returns:         0 OK; lookup_value has been reset to save_lookup
3665                  1 expansion failed
3666                  2 expansion failed because of bracketing error
3667 */
3668
3669 static int
3670 process_yesno(BOOL skipping, BOOL yes, uschar *save_lookup, const uschar **sptr,
3671   gstring ** yieldptr, uschar *type, BOOL *resetok)
3672 {
3673 int rc = 0;
3674 const uschar *s = *sptr;    /* Local value */
3675 uschar *sub1, *sub2;
3676 const uschar * errwhere;
3677
3678 /* If there are no following strings, we substitute the contents of $value for
3679 lookups and for extractions in the success case. For the ${if item, the string
3680 "true" is substituted. In the fail case, nothing is substituted for all three
3681 items. */
3682
3683 if (skip_whitespace(&s) == '}')
3684   {
3685   if (type[0] == 'i')
3686     {
3687     if (yes && !skipping)
3688       *yieldptr = string_catn(*yieldptr, US"true", 4);
3689     }
3690   else
3691     {
3692     if (yes && lookup_value && !skipping)
3693       *yieldptr = string_cat(*yieldptr, lookup_value);
3694     lookup_value = save_lookup;
3695     }
3696   s++;
3697   goto RETURN;
3698   }
3699
3700 /* The first following string must be braced. */
3701
3702 if (*s++ != '{')
3703   {
3704   errwhere = US"'yes' part did not start with '{'";
3705   goto FAILED_CURLY;
3706   }
3707
3708 /* Expand the first substring. Forced failures are noticed only if we actually
3709 want this string. Set skipping in the call in the fail case (this will always
3710 be the case if we were already skipping). */
3711
3712 sub1 = expand_string_internal(s, TRUE, &s, !yes, TRUE, resetok);
3713 if (sub1 == NULL && (yes || !f.expand_string_forcedfail)) goto FAILED;
3714 f.expand_string_forcedfail = FALSE;
3715 if (*s++ != '}')
3716   {
3717   errwhere = US"'yes' part did not end with '}'";
3718   goto FAILED_CURLY;
3719   }
3720
3721 /* If we want the first string, add it to the output */
3722
3723 if (yes)
3724   *yieldptr = string_cat(*yieldptr, sub1);
3725
3726 /* If this is called from a lookup/env or a (cert)extract, we want to restore
3727 $value to what it was at the start of the item, so that it has this value
3728 during the second string expansion. For the call from "if" or "run" to this
3729 function, save_lookup is set to lookup_value, so that this statement does
3730 nothing. */
3731
3732 lookup_value = save_lookup;
3733
3734 /* There now follows either another substring, or "fail", or nothing. This
3735 time, forced failures are noticed only if we want the second string. We must
3736 set skipping in the nested call if we don't want this string, or if we were
3737 already skipping. */
3738
3739 if (skip_whitespace(&s) == '{')
3740   {
3741   sub2 = expand_string_internal(s+1, TRUE, &s, yes || skipping, TRUE, resetok);
3742   if (sub2 == NULL && (!yes || !f.expand_string_forcedfail)) goto FAILED;
3743   f.expand_string_forcedfail = FALSE;
3744   if (*s++ != '}')
3745     {
3746     errwhere = US"'no' part did not start with '{'";
3747     goto FAILED_CURLY;
3748     }
3749
3750   /* If we want the second string, add it to the output */
3751
3752   if (!yes)
3753     *yieldptr = string_cat(*yieldptr, sub2);
3754   }
3755
3756 /* If there is no second string, but the word "fail" is present when the use of
3757 the second string is wanted, set a flag indicating it was a forced failure
3758 rather than a syntactic error. Swallow the terminating } in case this is nested
3759 inside another lookup or if or extract. */
3760
3761 else if (*s != '}')
3762   {
3763   uschar name[256];
3764   /* deconst cast ok here as source is s anyway */
3765   s = US read_name(name, sizeof(name), s, US"_");
3766   if (Ustrcmp(name, "fail") == 0)
3767     {
3768     if (!yes && !skipping)
3769       {
3770       Uskip_whitespace(&s);
3771       if (*s++ != '}')
3772         {
3773         errwhere = US"did not close with '}' after forcedfail";
3774         goto FAILED_CURLY;
3775         }
3776       expand_string_message =
3777         string_sprintf("\"%s\" failed and \"fail\" requested", type);
3778       f.expand_string_forcedfail = TRUE;
3779       goto FAILED;
3780       }
3781     }
3782   else
3783     {
3784     expand_string_message =
3785       string_sprintf("syntax error in \"%s\" item - \"fail\" expected", type);
3786     goto FAILED;
3787     }
3788   }
3789
3790 /* All we have to do now is to check on the final closing brace. */
3791
3792 skip_whitespace(&s);
3793 if (*s++ != '}')
3794   {
3795   errwhere = US"did not close with '}'";
3796   goto FAILED_CURLY;
3797   }
3798
3799
3800 RETURN:
3801 /* Update the input pointer value before returning */
3802 *sptr = s;
3803 return rc;
3804
3805 FAILED_CURLY:
3806   /* Get here if there is a bracketing failure */
3807   expand_string_message = string_sprintf(
3808     "curly-bracket problem in conditional yes/no parsing: %s\n"
3809     " remaining string is '%s'", errwhere, --s);
3810   rc = 2;
3811   goto RETURN;
3812
3813 FAILED:
3814   /* Get here for other failures */
3815   rc = 1;
3816   goto RETURN;
3817 }
3818
3819
3820
3821
3822 /********************************************************
3823 * prvs: Get last three digits of days since Jan 1, 1970 *
3824 ********************************************************/
3825
3826 /* This is needed to implement the "prvs" BATV reverse
3827    path signing scheme
3828
3829 Argument: integer "days" offset to add or substract to
3830           or from the current number of days.
3831
3832 Returns:  pointer to string containing the last three
3833           digits of the number of days since Jan 1, 1970,
3834           modified by the offset argument, NULL if there
3835           was an error in the conversion.
3836
3837 */
3838
3839 static uschar *
3840 prvs_daystamp(int day_offset)
3841 {
3842 uschar *days = store_get(32, FALSE);         /* Need at least 24 for cases */
3843 (void)string_format(days, 32, TIME_T_FMT,    /* where TIME_T_FMT is %lld */
3844   (time(NULL) + day_offset*86400)/86400);
3845 return (Ustrlen(days) >= 3) ? &days[Ustrlen(days)-3] : US"100";
3846 }
3847
3848
3849
3850 /********************************************************
3851 *   prvs: perform HMAC-SHA1 computation of prvs bits    *
3852 ********************************************************/
3853
3854 /* This is needed to implement the "prvs" BATV reverse
3855    path signing scheme
3856
3857 Arguments:
3858   address RFC2821 Address to use
3859       key The key to use (must be less than 64 characters
3860           in size)
3861   key_num Single-digit key number to use. Defaults to
3862           '0' when NULL.
3863
3864 Returns:  pointer to string containing the first three
3865           bytes of the final hash in hex format, NULL if
3866           there was an error in the process.
3867 */
3868
3869 static uschar *
3870 prvs_hmac_sha1(uschar *address, uschar *key, uschar *key_num, uschar *daystamp)
3871 {
3872 gstring * hash_source;
3873 uschar * p;
3874 hctx h;
3875 uschar innerhash[20];
3876 uschar finalhash[20];
3877 uschar innerkey[64];
3878 uschar outerkey[64];
3879 uschar *finalhash_hex;
3880
3881 if (!key_num)
3882   key_num = US"0";
3883
3884 if (Ustrlen(key) > 64)
3885   return NULL;
3886
3887 hash_source = string_catn(NULL, key_num, 1);
3888 hash_source = string_catn(hash_source, daystamp, 3);
3889 hash_source = string_cat(hash_source, address);
3890 (void) string_from_gstring(hash_source);
3891
3892 DEBUG(D_expand)
3893   debug_printf_indent("prvs: hash source is '%s'\n", hash_source->s);
3894
3895 memset(innerkey, 0x36, 64);
3896 memset(outerkey, 0x5c, 64);
3897
3898 for (int i = 0; i < Ustrlen(key); i++)
3899   {
3900   innerkey[i] ^= key[i];
3901   outerkey[i] ^= key[i];
3902   }
3903
3904 chash_start(HMAC_SHA1, &h);
3905 chash_mid(HMAC_SHA1, &h, innerkey);
3906 chash_end(HMAC_SHA1, &h, hash_source->s, hash_source->ptr, innerhash);
3907
3908 chash_start(HMAC_SHA1, &h);
3909 chash_mid(HMAC_SHA1, &h, outerkey);
3910 chash_end(HMAC_SHA1, &h, innerhash, 20, finalhash);
3911
3912 /* Hashing is deemed sufficient to de-taint any input data */
3913
3914 p = finalhash_hex = store_get(40, FALSE);
3915 for (int i = 0; i < 3; i++)
3916   {
3917   *p++ = hex_digits[(finalhash[i] & 0xf0) >> 4];
3918   *p++ = hex_digits[finalhash[i] & 0x0f];
3919   }
3920 *p = '\0';
3921
3922 return finalhash_hex;
3923 }
3924
3925
3926
3927
3928 /*************************************************
3929 *        Join a file onto the output string      *
3930 *************************************************/
3931
3932 /* This is used for readfile/readsock and after a run expansion.
3933 It joins the contents of a file onto the output string, globally replacing
3934 newlines with a given string (optionally).
3935
3936 Arguments:
3937   f            the FILE
3938   yield        pointer to the expandable string struct
3939   eol          newline replacement string, or NULL
3940
3941 Returns:       new pointer for expandable string, terminated if non-null
3942 */
3943
3944 gstring *
3945 cat_file(FILE *f, gstring *yield, uschar *eol)
3946 {
3947 uschar buffer[1024];
3948
3949 while (Ufgets(buffer, sizeof(buffer), f))
3950   {
3951   int len = Ustrlen(buffer);
3952   if (eol && buffer[len-1] == '\n') len--;
3953   yield = string_catn(yield, buffer, len);
3954   if (eol && buffer[len])
3955     yield = string_cat(yield, eol);
3956   }
3957
3958 (void) string_from_gstring(yield);
3959 return yield;
3960 }
3961
3962
3963 #ifndef DISABLE_TLS
3964 gstring *
3965 cat_file_tls(void * tls_ctx, gstring * yield, uschar * eol)
3966 {
3967 int rc;
3968 uschar buffer[1024];
3969
3970 /*XXX could we read direct into a pre-grown string? */
3971
3972 while ((rc = tls_read(tls_ctx, buffer, sizeof(buffer))) > 0)
3973   for (uschar * s = buffer; rc--; s++)
3974     yield = eol && *s == '\n'
3975       ? string_cat(yield, eol) : string_catn(yield, s, 1);
3976
3977 /* We assume that all errors, and any returns of zero bytes,
3978 are actually EOF. */
3979
3980 (void) string_from_gstring(yield);
3981 return yield;
3982 }
3983 #endif
3984
3985
3986 /*************************************************
3987 *          Evaluate numeric expression           *
3988 *************************************************/
3989
3990 /* This is a set of mutually recursive functions that evaluate an arithmetic
3991 expression involving + - * / % & | ^ ~ << >> and parentheses. The only one of
3992 these functions that is called from elsewhere is eval_expr, whose interface is:
3993
3994 Arguments:
3995   sptr        pointer to the pointer to the string - gets updated
3996   decimal     TRUE if numbers are to be assumed decimal
3997   error       pointer to where to put an error message - must be NULL on input
3998   endket      TRUE if ')' must terminate - FALSE for external call
3999
4000 Returns:      on success: the value of the expression, with *error still NULL
4001               on failure: an undefined value, with *error = a message
4002 */
4003
4004 static int_eximarith_t eval_op_or(uschar **, BOOL, uschar **);
4005
4006
4007 static int_eximarith_t
4008 eval_expr(uschar **sptr, BOOL decimal, uschar **error, BOOL endket)
4009 {
4010 uschar *s = *sptr;
4011 int_eximarith_t x = eval_op_or(&s, decimal, error);
4012
4013 if (!*error)
4014   if (endket)
4015     if (*s != ')')
4016       *error = US"expecting closing parenthesis";
4017     else
4018       while (isspace(*++s));
4019   else if (*s)
4020     *error = US"expecting operator";
4021 *sptr = s;
4022 return x;
4023 }
4024
4025
4026 static int_eximarith_t
4027 eval_number(uschar **sptr, BOOL decimal, uschar **error)
4028 {
4029 int c;
4030 int_eximarith_t n;
4031 uschar *s = *sptr;
4032
4033 if (isdigit((c = Uskip_whitespace(&s))))
4034   {
4035   int count;
4036   (void)sscanf(CS s, (decimal? SC_EXIM_DEC "%n" : SC_EXIM_ARITH "%n"), &n, &count);
4037   s += count;
4038   switch (tolower(*s))
4039     {
4040     default: break;
4041     case 'k': n *= 1024; s++; break;
4042     case 'm': n *= 1024*1024; s++; break;
4043     case 'g': n *= 1024*1024*1024; s++; break;
4044     }
4045   Uskip_whitespace(&s);
4046   }
4047 else if (c == '(')
4048   {
4049   s++;
4050   n = eval_expr(&s, decimal, error, 1);
4051   }
4052 else
4053   {
4054   *error = US"expecting number or opening parenthesis";
4055   n = 0;
4056   }
4057 *sptr = s;
4058 return n;
4059 }
4060
4061
4062 static int_eximarith_t
4063 eval_op_unary(uschar **sptr, BOOL decimal, uschar **error)
4064 {
4065 uschar *s = *sptr;
4066 int_eximarith_t x;
4067 Uskip_whitespace(&s);
4068 if (*s == '+' || *s == '-' || *s == '~')
4069   {
4070   int op = *s++;
4071   x = eval_op_unary(&s, decimal, error);
4072   if (op == '-') x = -x;
4073     else if (op == '~') x = ~x;
4074   }
4075 else
4076   x = eval_number(&s, decimal, error);
4077
4078 *sptr = s;
4079 return x;
4080 }
4081
4082
4083 static int_eximarith_t
4084 eval_op_mult(uschar **sptr, BOOL decimal, uschar **error)
4085 {
4086 uschar *s = *sptr;
4087 int_eximarith_t x = eval_op_unary(&s, decimal, error);
4088 if (!*error)
4089   {
4090   while (*s == '*' || *s == '/' || *s == '%')
4091     {
4092     int op = *s++;
4093     int_eximarith_t y = eval_op_unary(&s, decimal, error);
4094     if (*error) break;
4095     /* SIGFPE both on div/mod by zero and on INT_MIN / -1, which would give
4096      * a value of INT_MAX+1. Note that INT_MIN * -1 gives INT_MIN for me, which
4097      * is a bug somewhere in [gcc 4.2.1, FreeBSD, amd64].  In fact, -N*-M where
4098      * -N*M is INT_MIN will yield INT_MIN.
4099      * Since we don't support floating point, this is somewhat simpler.
4100      * Ideally, we'd return an error, but since we overflow for all other
4101      * arithmetic, consistency suggests otherwise, but what's the correct value
4102      * to use?  There is none.
4103      * The C standard guarantees overflow for unsigned arithmetic but signed
4104      * overflow invokes undefined behaviour; in practice, this is overflow
4105      * except for converting INT_MIN to INT_MAX+1.  We also can't guarantee
4106      * that long/longlong larger than int are available, or we could just work
4107      * with larger types.  We should consider whether to guarantee 32bit eval
4108      * and 64-bit working variables, with errors returned.  For now ...
4109      * So, the only SIGFPEs occur with a non-shrinking div/mod, thus -1; we
4110      * can just let the other invalid results occur otherwise, as they have
4111      * until now.  For this one case, we can coerce.
4112      */
4113     if (y == -1 && x == EXIM_ARITH_MIN && op != '*')
4114       {
4115       DEBUG(D_expand)
4116         debug_printf("Integer exception dodging: " PR_EXIM_ARITH "%c-1 coerced to " PR_EXIM_ARITH "\n",
4117             EXIM_ARITH_MIN, op, EXIM_ARITH_MAX);
4118       x = EXIM_ARITH_MAX;
4119       continue;
4120       }
4121     if (op == '*')
4122       x *= y;
4123     else
4124       {
4125       if (y == 0)
4126         {
4127         *error = (op == '/') ? US"divide by zero" : US"modulo by zero";
4128         x = 0;
4129         break;
4130         }
4131       if (op == '/')
4132         x /= y;
4133       else
4134         x %= y;
4135       }
4136     }
4137   }
4138 *sptr = s;
4139 return x;
4140 }
4141
4142
4143 static int_eximarith_t
4144 eval_op_sum(uschar **sptr, BOOL decimal, uschar **error)
4145 {
4146 uschar *s = *sptr;
4147 int_eximarith_t x = eval_op_mult(&s, decimal, error);
4148 if (!*error)
4149   {
4150   while (*s == '+' || *s == '-')
4151     {
4152     int op = *s++;
4153     int_eximarith_t y = eval_op_mult(&s, decimal, error);
4154     if (*error) break;
4155     if (  (x >=   EXIM_ARITH_MAX/2  && x >=   EXIM_ARITH_MAX/2)
4156        || (x <= -(EXIM_ARITH_MAX/2) && y <= -(EXIM_ARITH_MAX/2)))
4157       {                 /* over-conservative check */
4158       *error = op == '+'
4159         ? US"overflow in sum" : US"overflow in difference";
4160       break;
4161       }
4162     if (op == '+') x += y; else x -= y;
4163     }
4164   }
4165 *sptr = s;
4166 return x;
4167 }
4168
4169
4170 static int_eximarith_t
4171 eval_op_shift(uschar **sptr, BOOL decimal, uschar **error)
4172 {
4173 uschar *s = *sptr;
4174 int_eximarith_t x = eval_op_sum(&s, decimal, error);
4175 if (!*error)
4176   {
4177   while ((*s == '<' || *s == '>') && s[1] == s[0])
4178     {
4179     int_eximarith_t y;
4180     int op = *s++;
4181     s++;
4182     y = eval_op_sum(&s, decimal, error);
4183     if (*error) break;
4184     if (op == '<') x <<= y; else x >>= y;
4185     }
4186   }
4187 *sptr = s;
4188 return x;
4189 }
4190
4191
4192 static int_eximarith_t
4193 eval_op_and(uschar **sptr, BOOL decimal, uschar **error)
4194 {
4195 uschar *s = *sptr;
4196 int_eximarith_t x = eval_op_shift(&s, decimal, error);
4197 if (!*error)
4198   {
4199   while (*s == '&')
4200     {
4201     int_eximarith_t y;
4202     s++;
4203     y = eval_op_shift(&s, decimal, error);
4204     if (*error) break;
4205     x &= y;
4206     }
4207   }
4208 *sptr = s;
4209 return x;
4210 }
4211
4212
4213 static int_eximarith_t
4214 eval_op_xor(uschar **sptr, BOOL decimal, uschar **error)
4215 {
4216 uschar *s = *sptr;
4217 int_eximarith_t x = eval_op_and(&s, decimal, error);
4218 if (!*error)
4219   {
4220   while (*s == '^')
4221     {
4222     int_eximarith_t y;
4223     s++;
4224     y = eval_op_and(&s, decimal, error);
4225     if (*error) break;
4226     x ^= y;
4227     }
4228   }
4229 *sptr = s;
4230 return x;
4231 }
4232
4233
4234 static int_eximarith_t
4235 eval_op_or(uschar **sptr, BOOL decimal, uschar **error)
4236 {
4237 uschar *s = *sptr;
4238 int_eximarith_t x = eval_op_xor(&s, decimal, error);
4239 if (!*error)
4240   {
4241   while (*s == '|')
4242     {
4243     int_eximarith_t y;
4244     s++;
4245     y = eval_op_xor(&s, decimal, error);
4246     if (*error) break;
4247     x |= y;
4248     }
4249   }
4250 *sptr = s;
4251 return x;
4252 }
4253
4254
4255
4256 /************************************************/
4257 /* Comparison operation for sort expansion.  We need to avoid
4258 re-expanding the fields being compared, so need a custom routine.
4259
4260 Arguments:
4261  cond_type              Comparison operator code
4262  leftarg, rightarg      Arguments for comparison
4263
4264 Return true iff (leftarg compare rightarg)
4265 */
4266
4267 static BOOL
4268 sortsbefore(int cond_type, BOOL alpha_cond,
4269   const uschar * leftarg, const uschar * rightarg)
4270 {
4271 int_eximarith_t l_num, r_num;
4272
4273 if (!alpha_cond)
4274   {
4275   l_num = expanded_string_integer(leftarg, FALSE);
4276   if (expand_string_message) return FALSE;
4277   r_num = expanded_string_integer(rightarg, FALSE);
4278   if (expand_string_message) return FALSE;
4279
4280   switch (cond_type)
4281     {
4282     case ECOND_NUM_G:   return l_num >  r_num;
4283     case ECOND_NUM_GE:  return l_num >= r_num;
4284     case ECOND_NUM_L:   return l_num <  r_num;
4285     case ECOND_NUM_LE:  return l_num <= r_num;
4286     default: break;
4287     }
4288   }
4289 else
4290   switch (cond_type)
4291     {
4292     case ECOND_STR_LT:  return Ustrcmp (leftarg, rightarg) <  0;
4293     case ECOND_STR_LTI: return strcmpic(leftarg, rightarg) <  0;
4294     case ECOND_STR_LE:  return Ustrcmp (leftarg, rightarg) <= 0;
4295     case ECOND_STR_LEI: return strcmpic(leftarg, rightarg) <= 0;
4296     case ECOND_STR_GT:  return Ustrcmp (leftarg, rightarg) >  0;
4297     case ECOND_STR_GTI: return strcmpic(leftarg, rightarg) >  0;
4298     case ECOND_STR_GE:  return Ustrcmp (leftarg, rightarg) >= 0;
4299     case ECOND_STR_GEI: return strcmpic(leftarg, rightarg) >= 0;
4300     default: break;
4301     }
4302 return FALSE;   /* should not happen */
4303 }
4304
4305
4306 /*************************************************
4307 *                 Expand string                  *
4308 *************************************************/
4309
4310 /* Returns either an unchanged string, or the expanded string in stacking pool
4311 store. Interpreted sequences are:
4312
4313    \...                    normal escaping rules
4314    $name                   substitutes the variable
4315    ${name}                 ditto
4316    ${op:string}            operates on the expanded string value
4317    ${item{arg1}{arg2}...}  expands the args and then does the business
4318                              some literal args are not enclosed in {}
4319
4320 There are now far too many operators and item types to make it worth listing
4321 them here in detail any more.
4322
4323 We use an internal routine recursively to handle embedded substrings. The
4324 external function follows. The yield is NULL if the expansion failed, and there
4325 are two cases: if something collapsed syntactically, or if "fail" was given
4326 as the action on a lookup failure. These can be distinguished by looking at the
4327 variable expand_string_forcedfail, which is TRUE in the latter case.
4328
4329 The skipping flag is set true when expanding a substring that isn't actually
4330 going to be used (after "if" or "lookup") and it prevents lookups from
4331 happening lower down.
4332
4333 Store usage: At start, a store block of the length of the input plus 64
4334 is obtained. This is expanded as necessary by string_cat(), which might have to
4335 get a new block, or might be able to expand the original. At the end of the
4336 function we can release any store above that portion of the yield block that
4337 was actually used. In many cases this will be optimal.
4338
4339 However: if the first item in the expansion is a variable name or header name,
4340 we reset the store before processing it; if the result is in fresh store, we
4341 use that without copying. This is helpful for expanding strings like
4342 $message_headers which can get very long.
4343
4344 There's a problem if a ${dlfunc item has side-effects that cause allocation,
4345 since resetting the store at the end of the expansion will free store that was
4346 allocated by the plugin code as well as the slop after the expanded string. So
4347 we skip any resets if ${dlfunc } has been used. The same applies for ${acl }
4348 and, given the acl condition, ${if }. This is an unfortunate consequence of
4349 string expansion becoming too powerful.
4350
4351 Arguments:
4352   string         the string to be expanded
4353   ket_ends       true if expansion is to stop at }
4354   left           if not NULL, a pointer to the first character after the
4355                  expansion is placed here (typically used with ket_ends)
4356   skipping       TRUE for recursive calls when the value isn't actually going
4357                  to be used (to allow for optimisation)
4358   honour_dollar  TRUE if $ is to be expanded,
4359                  FALSE if it's just another character
4360   resetok_p      if not NULL, pointer to flag - write FALSE if unsafe to reset
4361                  the store.
4362
4363 Returns:         NULL if expansion fails:
4364                    expand_string_forcedfail is set TRUE if failure was forced
4365                    expand_string_message contains a textual error message
4366                  a pointer to the expanded string on success
4367 */
4368
4369 static uschar *
4370 expand_string_internal(const uschar *string, BOOL ket_ends, const uschar **left,
4371   BOOL skipping, BOOL honour_dollar, BOOL *resetok_p)
4372 {
4373 rmark reset_point = store_mark();
4374 gstring * yield = string_get(Ustrlen(string) + 64);
4375 int item_type;
4376 const uschar *s = string;
4377 uschar *save_expand_nstring[EXPAND_MAXN+1];
4378 int save_expand_nlength[EXPAND_MAXN+1];
4379 BOOL resetok = TRUE;
4380
4381 expand_level++;
4382 DEBUG(D_expand)
4383   DEBUG(D_noutf8)
4384     debug_printf_indent("/%s: %s\n",
4385       skipping ? "---scanning" : "considering", string);
4386   else
4387     debug_printf_indent(UTF8_DOWN_RIGHT "%s: %s\n",
4388       skipping
4389       ? UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ "scanning"
4390       : "considering",
4391       string);
4392
4393 f.expand_string_forcedfail = FALSE;
4394 expand_string_message = US"";
4395
4396 if (is_tainted(string))
4397   {
4398   expand_string_message =
4399     string_sprintf("attempt to expand tainted string '%s'", s);
4400   log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message);
4401   goto EXPAND_FAILED;
4402   }
4403
4404 while (*s)
4405   {
4406   uschar *value;
4407   uschar name[256];
4408
4409   /* \ escapes the next character, which must exist, or else
4410   the expansion fails. There's a special escape, \N, which causes
4411   copying of the subject verbatim up to the next \N. Otherwise,
4412   the escapes are the standard set. */
4413
4414   if (*s == '\\')
4415     {
4416     if (s[1] == 0)
4417       {
4418       expand_string_message = US"\\ at end of string";
4419       goto EXPAND_FAILED;
4420       }
4421
4422     if (s[1] == 'N')
4423       {
4424       const uschar * t = s + 2;
4425       for (s = t; *s != 0; s++) if (*s == '\\' && s[1] == 'N') break;
4426       yield = string_catn(yield, t, s - t);
4427       if (*s != 0) s += 2;
4428       }
4429
4430     else
4431       {
4432       uschar ch[1];
4433       ch[0] = string_interpret_escape(&s);
4434       s++;
4435       yield = string_catn(yield, ch, 1);
4436       }
4437
4438     continue;
4439     }
4440
4441   /*{*/
4442   /* Anything other than $ is just copied verbatim, unless we are
4443   looking for a terminating } character. */
4444
4445   /*{*/
4446   if (ket_ends && *s == '}') break;
4447
4448   if (*s != '$' || !honour_dollar)
4449     {
4450     yield = string_catn(yield, s++, 1);
4451     continue;
4452     }
4453
4454   /* No { after the $ - must be a plain name or a number for string
4455   match variable. There has to be a fudge for variables that are the
4456   names of header fields preceded by "$header_" because header field
4457   names can contain any printing characters except space and colon.
4458   For those that don't like typing this much, "$h_" is a synonym for
4459   "$header_". A non-existent header yields a NULL value; nothing is
4460   inserted. */  /*}*/
4461
4462   if (isalpha((*(++s))))
4463     {
4464     int len;
4465     int newsize = 0;
4466     gstring * g = NULL;
4467     uschar * t;
4468
4469     s = read_name(name, sizeof(name), s, US"_");
4470
4471     /* If this is the first thing to be expanded, release the pre-allocated
4472     buffer. */
4473
4474     if (!yield)
4475       g = store_get(sizeof(gstring), FALSE);
4476     else if (yield->ptr == 0)
4477       {
4478       if (resetok) reset_point = store_reset(reset_point);
4479       yield = NULL;
4480       reset_point = store_mark();
4481       g = store_get(sizeof(gstring), FALSE);    /* alloc _before_ calling find_variable() */
4482       }
4483
4484     /* Header */
4485
4486     if (  ( *(t = name) == 'h'
4487           || (*t == 'r' || *t == 'l' || *t == 'b') && *++t == 'h'
4488           )
4489        && (*++t == '_' || Ustrncmp(t, "eader_", 6) == 0)
4490        )
4491       {
4492       unsigned flags = *name == 'r' ? FH_WANT_RAW
4493                       : *name == 'l' ? FH_WANT_RAW|FH_WANT_LIST
4494                       : 0;
4495       uschar * charset = *name == 'b' ? NULL : headers_charset;
4496
4497       s = read_header_name(name, sizeof(name), s);
4498       value = find_header(name, &newsize, flags, charset);
4499
4500       /* If we didn't find the header, and the header contains a closing brace
4501       character, this may be a user error where the terminating colon
4502       has been omitted. Set a flag to adjust the error message in this case.
4503       But there is no error here - nothing gets inserted. */
4504
4505       if (!value)
4506         {
4507         if (Ustrchr(name, '}')) malformed_header = TRUE;
4508         continue;
4509         }
4510       }
4511
4512     /* Variable */
4513
4514     else if (!(value = find_variable(name, FALSE, skipping, &newsize)))
4515       {
4516       expand_string_message =
4517         string_sprintf("unknown variable name \"%s\"", name);
4518         check_variable_error_message(name);
4519       goto EXPAND_FAILED;
4520       }
4521
4522     /* If the data is known to be in a new buffer, newsize will be set to the
4523     size of that buffer. If this is the first thing in an expansion string,
4524     yield will be NULL; just point it at the new store instead of copying. Many
4525     expansion strings contain just one reference, so this is a useful
4526     optimization, especially for humungous headers.  We need to use a gstring
4527     structure that is not allocated after that new-buffer, else a later store
4528     reset in the middle of the buffer will make it inaccessible. */
4529
4530     len = Ustrlen(value);
4531     if (!yield && newsize != 0)
4532       {
4533       yield = g;
4534       yield->size = newsize;
4535       yield->ptr = len;
4536       yield->s = value;
4537       }
4538     else
4539       yield = string_catn(yield, value, len);
4540
4541     continue;
4542     }
4543
4544   if (isdigit(*s))
4545     {
4546     int n;
4547     s = read_cnumber(&n, s);
4548     if (n >= 0 && n <= expand_nmax)
4549       yield = string_catn(yield, expand_nstring[n], expand_nlength[n]);
4550     continue;
4551     }
4552
4553   /* Otherwise, if there's no '{' after $ it's an error. */             /*}*/
4554
4555   if (*s != '{')                                                        /*}*/
4556     {
4557     expand_string_message = US"$ not followed by letter, digit, or {";  /*}*/
4558     goto EXPAND_FAILED;
4559     }
4560
4561   /* After { there can be various things, but they all start with
4562   an initial word, except for a number for a string match variable. */
4563
4564   if (isdigit((*(++s))))
4565     {
4566     int n;
4567     s = read_cnumber(&n, s);            /*{*/
4568     if (*s++ != '}')
4569       {                                 /*{*/
4570       expand_string_message = US"} expected after number";
4571       goto EXPAND_FAILED;
4572       }
4573     if (n >= 0 && n <= expand_nmax)
4574       yield = string_catn(yield, expand_nstring[n], expand_nlength[n]);
4575     continue;
4576     }
4577
4578   if (!isalpha(*s))
4579     {
4580     expand_string_message = US"letter or digit expected after ${";      /*}*/
4581     goto EXPAND_FAILED;
4582     }
4583
4584   /* Allow "-" in names to cater for substrings with negative
4585   arguments. Since we are checking for known names after { this is
4586   OK. */
4587
4588   s = read_name(name, sizeof(name), s, US"_-");
4589   item_type = chop_match(name, item_table, nelem(item_table));
4590
4591   switch(item_type)
4592     {
4593     /* Call an ACL from an expansion.  We feed data in via $acl_arg1 - $acl_arg9.
4594     If the ACL returns accept or reject we return content set by "message ="
4595     There is currently no limit on recursion; this would have us call
4596     acl_check_internal() directly and get a current level from somewhere.
4597     See also the acl expansion condition ECOND_ACL and the traditional
4598     acl modifier ACLC_ACL.
4599     Assume that the function has side-effects on the store that must be preserved.
4600     */
4601
4602     case EITEM_ACL:
4603       /* ${acl {name} {arg1}{arg2}...} */
4604       {
4605       uschar *sub[10];  /* name + arg1-arg9 (which must match number of acl_arg[]) */
4606       uschar *user_msg;
4607       int rc;
4608
4609       switch(read_subs(sub, nelem(sub), 1, &s, skipping, TRUE, name,
4610                       &resetok))
4611         {
4612         case 1: goto EXPAND_FAILED_CURLY;
4613         case 2:
4614         case 3: goto EXPAND_FAILED;
4615         }
4616       if (skipping) continue;
4617
4618       resetok = FALSE;
4619       switch(rc = eval_acl(sub, nelem(sub), &user_msg))
4620         {
4621         case OK:
4622         case FAIL:
4623           DEBUG(D_expand)
4624             debug_printf_indent("acl expansion yield: %s\n", user_msg);
4625           if (user_msg)
4626             yield = string_cat(yield, user_msg);
4627           continue;
4628
4629         case DEFER:
4630           f.expand_string_forcedfail = TRUE;
4631           /*FALLTHROUGH*/
4632         default:
4633           expand_string_message = string_sprintf("%s from acl \"%s\"",
4634             rc_names[rc], sub[0]);
4635           goto EXPAND_FAILED;
4636         }
4637       }
4638
4639     case EITEM_AUTHRESULTS:
4640       /* ${authresults {mysystemname}} */
4641       {
4642       uschar *sub_arg[1];
4643
4644       switch(read_subs(sub_arg, nelem(sub_arg), 1, &s, skipping, TRUE, name,
4645                       &resetok))
4646         {
4647         case 1: goto EXPAND_FAILED_CURLY;
4648         case 2:
4649         case 3: goto EXPAND_FAILED;
4650         }
4651
4652       yield = string_append(yield, 3,
4653                         US"Authentication-Results: ", sub_arg[0], US"; none");
4654       yield->ptr -= 6;
4655
4656       yield = authres_local(yield, sub_arg[0]);
4657       yield = authres_iprev(yield);
4658       yield = authres_smtpauth(yield);
4659 #ifdef SUPPORT_SPF
4660       yield = authres_spf(yield);
4661 #endif
4662 #ifndef DISABLE_DKIM
4663       yield = authres_dkim(yield);
4664 #endif
4665 #ifdef SUPPORT_DMARC
4666       yield = authres_dmarc(yield);
4667 #endif
4668 #ifdef EXPERIMENTAL_ARC
4669       yield = authres_arc(yield);
4670 #endif
4671       continue;
4672       }
4673
4674     /* Handle conditionals - preserve the values of the numerical expansion
4675     variables in case they get changed by a regular expression match in the
4676     condition. If not, they retain their external settings. At the end
4677     of this "if" section, they get restored to their previous values. */
4678
4679     case EITEM_IF:
4680       {
4681       BOOL cond = FALSE;
4682       const uschar *next_s;
4683       int save_expand_nmax =
4684         save_expand_strings(save_expand_nstring, save_expand_nlength);
4685
4686       Uskip_whitespace(&s);
4687       if (!(next_s = eval_condition(s, &resetok, skipping ? NULL : &cond)))
4688         goto EXPAND_FAILED;  /* message already set */
4689
4690       DEBUG(D_expand)
4691         DEBUG(D_noutf8)
4692           {
4693           debug_printf_indent("|--condition: %.*s\n", (int)(next_s - s), s);
4694           debug_printf_indent("|-----result: %s\n", cond ? "true" : "false");
4695           }
4696         else
4697           {
4698           debug_printf_indent(UTF8_VERT_RIGHT UTF8_HORIZ UTF8_HORIZ
4699             "condition: %.*s\n",
4700             (int)(next_s - s), s);
4701           debug_printf_indent(UTF8_VERT_RIGHT UTF8_HORIZ UTF8_HORIZ
4702             UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ
4703             "result: %s\n",
4704             cond ? "true" : "false");
4705           }
4706
4707       s = next_s;
4708
4709       /* The handling of "yes" and "no" result strings is now in a separate
4710       function that is also used by ${lookup} and ${extract} and ${run}. */
4711
4712       switch(process_yesno(
4713                skipping,                     /* were previously skipping */
4714                cond,                         /* success/failure indicator */
4715                lookup_value,                 /* value to reset for string2 */
4716                &s,                           /* input pointer */
4717                &yield,                       /* output pointer */
4718                US"if",                       /* condition type */
4719                &resetok))
4720         {
4721         case 1: goto EXPAND_FAILED;          /* when all is well, the */
4722         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
4723         }
4724
4725       /* Restore external setting of expansion variables for continuation
4726       at this level. */
4727
4728       restore_expand_strings(save_expand_nmax, save_expand_nstring,
4729         save_expand_nlength);
4730       continue;
4731       }
4732
4733 #ifdef SUPPORT_I18N
4734     case EITEM_IMAPFOLDER:
4735       {                         /* ${imapfolder {name}{sep]{specials}} */
4736       uschar *sub_arg[3];
4737       uschar *encoded;
4738
4739       switch(read_subs(sub_arg, nelem(sub_arg), 1, &s, skipping, TRUE, name,
4740                       &resetok))
4741         {
4742         case 1: goto EXPAND_FAILED_CURLY;
4743         case 2:
4744         case 3: goto EXPAND_FAILED;
4745         }
4746
4747       if (!sub_arg[1])                  /* One argument */
4748         {
4749         sub_arg[1] = US"/";             /* default separator */
4750         sub_arg[2] = NULL;
4751         }
4752       else if (Ustrlen(sub_arg[1]) != 1)
4753         {
4754         expand_string_message =
4755           string_sprintf(
4756                 "IMAP folder separator must be one character, found \"%s\"",
4757                 sub_arg[1]);
4758         goto EXPAND_FAILED;
4759         }
4760
4761       if (!skipping)
4762         {
4763         if (!(encoded = imap_utf7_encode(sub_arg[0], headers_charset,
4764                             sub_arg[1][0], sub_arg[2], &expand_string_message)))
4765           goto EXPAND_FAILED;
4766         yield = string_cat(yield, encoded);
4767         }
4768       continue;
4769       }
4770 #endif
4771
4772     /* Handle database lookups unless locked out. If "skipping" is TRUE, we are
4773     expanding an internal string that isn't actually going to be used. All we
4774     need to do is check the syntax, so don't do a lookup at all. Preserve the
4775     values of the numerical expansion variables in case they get changed by a
4776     partial lookup. If not, they retain their external settings. At the end
4777     of this "lookup" section, they get restored to their previous values. */
4778
4779     case EITEM_LOOKUP:
4780       {
4781       int stype, partial, affixlen, starflags;
4782       int expand_setup = 0;
4783       int nameptr = 0;
4784       uschar *key, *filename;
4785       const uschar * affix, * opts;
4786       uschar *save_lookup_value = lookup_value;
4787       int save_expand_nmax =
4788         save_expand_strings(save_expand_nstring, save_expand_nlength);
4789
4790       if (expand_forbid & RDO_LOOKUP)
4791         {
4792         expand_string_message = US"lookup expansions are not permitted";
4793         goto EXPAND_FAILED;
4794         }
4795
4796       /* Get the key we are to look up for single-key+file style lookups.
4797       Otherwise set the key NULL pro-tem. */
4798
4799       if (Uskip_whitespace(&s) == '{')                                  /*}*/
4800         {
4801         key = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok);
4802         if (!key) goto EXPAND_FAILED;                   /*{{*/
4803         if (*s++ != '}')
4804           {
4805           expand_string_message = US"missing '}' after lookup key";
4806           goto EXPAND_FAILED_CURLY;
4807           }
4808         Uskip_whitespace(&s);
4809         }
4810       else key = NULL;
4811
4812       /* Find out the type of database */
4813
4814       if (!isalpha(*s))
4815         {
4816         expand_string_message = US"missing lookup type";
4817         goto EXPAND_FAILED;
4818         }
4819
4820       /* The type is a string that may contain special characters of various
4821       kinds. Allow everything except space or { to appear; the actual content
4822       is checked by search_findtype_partial. */         /*}*/
4823
4824       while (*s && *s != '{' && !isspace(*s))           /*}*/
4825         {
4826         if (nameptr < sizeof(name) - 1) name[nameptr++] = *s;
4827         s++;
4828         }
4829       name[nameptr] = '\0';
4830       Uskip_whitespace(&s);
4831
4832       /* Now check for the individual search type and any partial or default
4833       options. Only those types that are actually in the binary are valid. */
4834
4835       if ((stype = search_findtype_partial(name, &partial, &affix, &affixlen,
4836           &starflags, &opts)) < 0)
4837         {
4838         expand_string_message = search_error_message;
4839         goto EXPAND_FAILED;
4840         }
4841
4842       /* Check that a key was provided for those lookup types that need it,
4843       and was not supplied for those that use the query style. */
4844
4845       if (!mac_islookup(stype, lookup_querystyle|lookup_absfilequery))
4846         {
4847         if (!key)
4848           {
4849           expand_string_message = string_sprintf("missing {key} for single-"
4850             "key \"%s\" lookup", name);
4851           goto EXPAND_FAILED;
4852           }
4853         }
4854       else
4855         {
4856         if (key)
4857           {
4858           expand_string_message = string_sprintf("a single key was given for "
4859             "lookup type \"%s\", which is not a single-key lookup type", name);
4860           goto EXPAND_FAILED;
4861           }
4862         }
4863
4864       /* Get the next string in brackets and expand it. It is the file name for
4865       single-key+file lookups, and the whole query otherwise. In the case of
4866       queries that also require a file name (e.g. sqlite), the file name comes
4867       first. */
4868
4869       if (*s != '{')
4870         {
4871         expand_string_message = US"missing '{' for lookup file-or-query arg";
4872         goto EXPAND_FAILED_CURLY;
4873         }
4874       if (!(filename = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok)))
4875         goto EXPAND_FAILED;
4876       if (*s++ != '}')
4877         {
4878         expand_string_message = US"missing '}' closing lookup file-or-query arg";
4879         goto EXPAND_FAILED_CURLY;
4880         }
4881       Uskip_whitespace(&s);
4882
4883       /* If this isn't a single-key+file lookup, re-arrange the variables
4884       to be appropriate for the search_ functions. For query-style lookups,
4885       there is just a "key", and no file name. For the special query-style +
4886       file types, the query (i.e. "key") starts with a file name. */
4887
4888       if (!key)
4889         key = search_args(stype, name, filename, &filename, opts);
4890
4891       /* If skipping, don't do the next bit - just lookup_value == NULL, as if
4892       the entry was not found. Note that there is no search_close() function.
4893       Files are left open in case of re-use. At suitable places in higher logic,
4894       search_tidyup() is called to tidy all open files. This can save opening
4895       the same file several times. However, files may also get closed when
4896       others are opened, if too many are open at once. The rule is that a
4897       handle should not be used after a second search_open().
4898
4899       Request that a partial search sets up $1 and maybe $2 by passing
4900       expand_setup containing zero. If its value changes, reset expand_nmax,
4901       since new variables will have been set. Note that at the end of this
4902       "lookup" section, the old numeric variables are restored. */
4903
4904       if (skipping)
4905         lookup_value = NULL;
4906       else
4907         {
4908         void *handle = search_open(filename, stype, 0, NULL, NULL);
4909         if (!handle)
4910           {
4911           expand_string_message = search_error_message;
4912           goto EXPAND_FAILED;
4913           }
4914         lookup_value = search_find(handle, filename, key, partial, affix,
4915           affixlen, starflags, &expand_setup, opts);
4916         if (f.search_find_defer)
4917           {
4918           expand_string_message =
4919             string_sprintf("lookup of \"%s\" gave DEFER: %s",
4920               string_printing2(key, SP_TAB), search_error_message);
4921           goto EXPAND_FAILED;
4922           }
4923         if (expand_setup > 0) expand_nmax = expand_setup;
4924         }
4925
4926       /* The handling of "yes" and "no" result strings is now in a separate
4927       function that is also used by ${if} and ${extract}. */
4928
4929       switch(process_yesno(
4930                skipping,                     /* were previously skipping */
4931                lookup_value != NULL,         /* success/failure indicator */
4932                save_lookup_value,            /* value to reset for string2 */
4933                &s,                           /* input pointer */
4934                &yield,                       /* output pointer */
4935                US"lookup",                   /* condition type */
4936                &resetok))
4937         {
4938         case 1: goto EXPAND_FAILED;          /* when all is well, the */
4939         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
4940         }
4941
4942       /* Restore external setting of expansion variables for carrying on
4943       at this level, and continue. */
4944
4945       restore_expand_strings(save_expand_nmax, save_expand_nstring,
4946         save_expand_nlength);
4947       continue;
4948       }
4949
4950     /* If Perl support is configured, handle calling embedded perl subroutines,
4951     unless locked out at this time. Syntax is ${perl{sub}} or ${perl{sub}{arg}}
4952     or ${perl{sub}{arg1}{arg2}} or up to a maximum of EXIM_PERL_MAX_ARGS
4953     arguments (defined below). */
4954
4955     #define EXIM_PERL_MAX_ARGS 8
4956
4957     case EITEM_PERL:
4958     #ifndef EXIM_PERL
4959     expand_string_message = US"\"${perl\" encountered, but this facility "      /*}*/
4960       "is not included in this binary";
4961     goto EXPAND_FAILED;
4962
4963     #else   /* EXIM_PERL */
4964       {
4965       uschar *sub_arg[EXIM_PERL_MAX_ARGS + 2];
4966       gstring *new_yield;
4967
4968       if ((expand_forbid & RDO_PERL) != 0)
4969         {
4970         expand_string_message = US"Perl calls are not permitted";
4971         goto EXPAND_FAILED;
4972         }
4973
4974       switch(read_subs(sub_arg, EXIM_PERL_MAX_ARGS + 1, 1, &s, skipping, TRUE,
4975            name, &resetok))
4976         {
4977         case 1: goto EXPAND_FAILED_CURLY;
4978         case 2:
4979         case 3: goto EXPAND_FAILED;
4980         }
4981
4982       /* If skipping, we don't actually do anything */
4983
4984       if (skipping) continue;
4985
4986       /* Start the interpreter if necessary */
4987
4988       if (!opt_perl_started)
4989         {
4990         uschar *initerror;
4991         if (!opt_perl_startup)
4992           {
4993           expand_string_message = US"A setting of perl_startup is needed when "
4994             "using the Perl interpreter";
4995           goto EXPAND_FAILED;
4996           }
4997         DEBUG(D_any) debug_printf("Starting Perl interpreter\n");
4998         if ((initerror = init_perl(opt_perl_startup)))
4999           {
5000           expand_string_message =
5001             string_sprintf("error in perl_startup code: %s\n", initerror);
5002           goto EXPAND_FAILED;
5003           }
5004         opt_perl_started = TRUE;
5005         }
5006
5007       /* Call the function */
5008
5009       sub_arg[EXIM_PERL_MAX_ARGS + 1] = NULL;
5010       new_yield = call_perl_cat(yield, &expand_string_message,
5011         sub_arg[0], sub_arg + 1);
5012
5013       /* NULL yield indicates failure; if the message pointer has been set to
5014       NULL, the yield was undef, indicating a forced failure. Otherwise the
5015       message will indicate some kind of Perl error. */
5016
5017       if (!new_yield)
5018         {
5019         if (!expand_string_message)
5020           {
5021           expand_string_message =
5022             string_sprintf("Perl subroutine \"%s\" returned undef to force "
5023               "failure", sub_arg[0]);
5024           f.expand_string_forcedfail = TRUE;
5025           }
5026         goto EXPAND_FAILED;
5027         }
5028
5029       /* Yield succeeded. Ensure forcedfail is unset, just in case it got
5030       set during a callback from Perl. */
5031
5032       f.expand_string_forcedfail = FALSE;
5033       yield = new_yield;
5034       continue;
5035       }
5036     #endif /* EXIM_PERL */
5037
5038     /* Transform email address to "prvs" scheme to use
5039        as BATV-signed return path */
5040
5041     case EITEM_PRVS:
5042       {
5043       uschar *sub_arg[3];
5044       uschar *p,*domain;
5045
5046       switch(read_subs(sub_arg, 3, 2, &s, skipping, TRUE, name, &resetok))
5047         {
5048         case 1: goto EXPAND_FAILED_CURLY;
5049         case 2:
5050         case 3: goto EXPAND_FAILED;
5051         }
5052
5053       /* If skipping, we don't actually do anything */
5054       if (skipping) continue;
5055
5056       /* sub_arg[0] is the address */
5057       if (  !(domain = Ustrrchr(sub_arg[0],'@'))
5058          || domain == sub_arg[0] || Ustrlen(domain) == 1)
5059         {
5060         expand_string_message = US"prvs first argument must be a qualified email address";
5061         goto EXPAND_FAILED;
5062         }
5063
5064       /* Calculate the hash. The third argument must be a single-digit
5065       key number, or unset. */
5066
5067       if (  sub_arg[2]
5068          && (!isdigit(sub_arg[2][0]) || sub_arg[2][1] != 0))
5069         {
5070         expand_string_message = US"prvs third argument must be a single digit";
5071         goto EXPAND_FAILED;
5072         }
5073
5074       p = prvs_hmac_sha1(sub_arg[0], sub_arg[1], sub_arg[2], prvs_daystamp(7));
5075       if (!p)
5076         {
5077         expand_string_message = US"prvs hmac-sha1 conversion failed";
5078         goto EXPAND_FAILED;
5079         }
5080
5081       /* Now separate the domain from the local part */
5082       *domain++ = '\0';
5083
5084       yield = string_catn(yield, US"prvs=", 5);
5085       yield = string_catn(yield, sub_arg[2] ? sub_arg[2] : US"0", 1);
5086       yield = string_catn(yield, prvs_daystamp(7), 3);
5087       yield = string_catn(yield, p, 6);
5088       yield = string_catn(yield, US"=", 1);
5089       yield = string_cat (yield, sub_arg[0]);
5090       yield = string_catn(yield, US"@", 1);
5091       yield = string_cat (yield, domain);
5092
5093       continue;
5094       }
5095
5096     /* Check a prvs-encoded address for validity */
5097
5098     case EITEM_PRVSCHECK:
5099       {
5100       uschar *sub_arg[3];
5101       gstring * g;
5102       const pcre *re;
5103       uschar *p;
5104
5105       /* TF: Ugliness: We want to expand parameter 1 first, then set
5106          up expansion variables that are used in the expansion of
5107          parameter 2. So we clone the string for the first
5108          expansion, where we only expand parameter 1.
5109
5110          PH: Actually, that isn't necessary. The read_subs() function is
5111          designed to work this way for the ${if and ${lookup expansions. I've
5112          tidied the code.
5113       */
5114
5115       /* Reset expansion variables */
5116       prvscheck_result = NULL;
5117       prvscheck_address = NULL;
5118       prvscheck_keynum = NULL;
5119
5120       switch(read_subs(sub_arg, 1, 1, &s, skipping, FALSE, name, &resetok))
5121         {
5122         case 1: goto EXPAND_FAILED_CURLY;
5123         case 2:
5124         case 3: goto EXPAND_FAILED;
5125         }
5126
5127       re = regex_must_compile(US"^prvs\\=([0-9])([0-9]{3})([A-F0-9]{6})\\=(.+)\\@(.+)$",
5128                               TRUE,FALSE);
5129
5130       if (regex_match_and_setup(re,sub_arg[0],0,-1))
5131         {
5132         uschar *local_part = string_copyn(expand_nstring[4],expand_nlength[4]);
5133         uschar *key_num = string_copyn(expand_nstring[1],expand_nlength[1]);
5134         uschar *daystamp = string_copyn(expand_nstring[2],expand_nlength[2]);
5135         uschar *hash = string_copyn(expand_nstring[3],expand_nlength[3]);
5136         uschar *domain = string_copyn(expand_nstring[5],expand_nlength[5]);
5137
5138         DEBUG(D_expand) debug_printf_indent("prvscheck localpart: %s\n", local_part);
5139         DEBUG(D_expand) debug_printf_indent("prvscheck key number: %s\n", key_num);
5140         DEBUG(D_expand) debug_printf_indent("prvscheck daystamp: %s\n", daystamp);
5141         DEBUG(D_expand) debug_printf_indent("prvscheck hash: %s\n", hash);
5142         DEBUG(D_expand) debug_printf_indent("prvscheck domain: %s\n", domain);
5143
5144         /* Set up expansion variables */
5145         g = string_cat (NULL, local_part);
5146         g = string_catn(g, US"@", 1);
5147         g = string_cat (g, domain);
5148         prvscheck_address = string_from_gstring(g);
5149         prvscheck_keynum = string_copy(key_num);
5150
5151         /* Now expand the second argument */
5152         switch(read_subs(sub_arg, 1, 1, &s, skipping, FALSE, name, &resetok))
5153           {
5154           case 1: goto EXPAND_FAILED_CURLY;
5155           case 2:
5156           case 3: goto EXPAND_FAILED;
5157           }
5158
5159         /* Now we have the key and can check the address. */
5160
5161         p = prvs_hmac_sha1(prvscheck_address, sub_arg[0], prvscheck_keynum,
5162           daystamp);
5163
5164         if (!p)
5165           {
5166           expand_string_message = US"hmac-sha1 conversion failed";
5167           goto EXPAND_FAILED;
5168           }
5169
5170         DEBUG(D_expand) debug_printf_indent("prvscheck: received hash is %s\n", hash);
5171         DEBUG(D_expand) debug_printf_indent("prvscheck:      own hash is %s\n", p);
5172
5173         if (Ustrcmp(p,hash) == 0)
5174           {
5175           /* Success, valid BATV address. Now check the expiry date. */
5176           uschar *now = prvs_daystamp(0);
5177           unsigned int inow = 0,iexpire = 1;
5178
5179           (void)sscanf(CS now,"%u",&inow);
5180           (void)sscanf(CS daystamp,"%u",&iexpire);
5181
5182           /* When "iexpire" is < 7, a "flip" has occurred.
5183              Adjust "inow" accordingly. */
5184           if ( (iexpire < 7) && (inow >= 993) ) inow = 0;
5185
5186           if (iexpire >= inow)
5187             {
5188             prvscheck_result = US"1";
5189             DEBUG(D_expand) debug_printf_indent("prvscheck: success, $pvrs_result set to 1\n");
5190             }
5191           else
5192             {
5193             prvscheck_result = NULL;
5194             DEBUG(D_expand) debug_printf_indent("prvscheck: signature expired, $pvrs_result unset\n");
5195             }
5196           }
5197         else
5198           {
5199           prvscheck_result = NULL;
5200           DEBUG(D_expand) debug_printf_indent("prvscheck: hash failure, $pvrs_result unset\n");
5201           }
5202
5203         /* Now expand the final argument. We leave this till now so that
5204         it can include $prvscheck_result. */
5205
5206         switch(read_subs(sub_arg, 1, 0, &s, skipping, TRUE, name, &resetok))
5207           {
5208           case 1: goto EXPAND_FAILED_CURLY;
5209           case 2:
5210           case 3: goto EXPAND_FAILED;
5211           }
5212
5213         yield = string_cat(yield,
5214           !sub_arg[0] || !*sub_arg[0] ? prvscheck_address : sub_arg[0]);
5215
5216         /* Reset the "internal" variables afterwards, because they are in
5217         dynamic store that will be reclaimed if the expansion succeeded. */
5218
5219         prvscheck_address = NULL;
5220         prvscheck_keynum = NULL;
5221         }
5222       else
5223         /* Does not look like a prvs encoded address, return the empty string.
5224            We need to make sure all subs are expanded first, so as to skip over
5225            the entire item. */
5226
5227         switch(read_subs(sub_arg, 2, 1, &s, skipping, TRUE, name, &resetok))
5228           {
5229           case 1: goto EXPAND_FAILED_CURLY;
5230           case 2:
5231           case 3: goto EXPAND_FAILED;
5232           }
5233
5234       continue;
5235       }
5236
5237     /* Handle "readfile" to insert an entire file */
5238
5239     case EITEM_READFILE:
5240       {
5241       FILE *f;
5242       uschar *sub_arg[2];
5243
5244       if ((expand_forbid & RDO_READFILE) != 0)
5245         {
5246         expand_string_message = US"file insertions are not permitted";
5247         goto EXPAND_FAILED;
5248         }
5249
5250       switch(read_subs(sub_arg, 2, 1, &s, skipping, TRUE, name, &resetok))
5251         {
5252         case 1: goto EXPAND_FAILED_CURLY;
5253         case 2:
5254         case 3: goto EXPAND_FAILED;
5255         }
5256
5257       /* If skipping, we don't actually do anything */
5258
5259       if (skipping) continue;
5260
5261       /* Open the file and read it */
5262
5263       if (!(f = Ufopen(sub_arg[0], "rb")))
5264         {
5265         expand_string_message = string_open_failed("%s", sub_arg[0]);
5266         goto EXPAND_FAILED;
5267         }
5268
5269       yield = cat_file(f, yield, sub_arg[1]);
5270       (void)fclose(f);
5271       continue;
5272       }
5273
5274     /* Handle "readsocket" to insert data from a socket, either
5275     Inet or Unix domain */
5276
5277     case EITEM_READSOCK:
5278       {
5279       uschar * arg;
5280       uschar * sub_arg[4];
5281
5282       if (expand_forbid & RDO_READSOCK)
5283         {
5284         expand_string_message = US"socket insertions are not permitted";
5285         goto EXPAND_FAILED;
5286         }
5287
5288       /* Read up to 4 arguments, but don't do the end of item check afterwards,
5289       because there may be a string for expansion on failure. */
5290
5291       switch(read_subs(sub_arg, 4, 2, &s, skipping, FALSE, name, &resetok))
5292         {
5293         case 1: goto EXPAND_FAILED_CURLY;
5294         case 2:                             /* Won't occur: no end check */
5295         case 3: goto EXPAND_FAILED;
5296         }
5297
5298       /* If skipping, we don't actually do anything. Otherwise, arrange to
5299       connect to either an IP or a Unix socket. */
5300
5301       if (!skipping)
5302         {
5303         int stype = search_findtype(US"readsock", 8);
5304         gstring * g = NULL;
5305         void * handle;
5306         int expand_setup = -1;
5307         uschar * s;
5308
5309         /* If the reqstr is empty, flag that and set a dummy */
5310
5311         if (!sub_arg[1][0])
5312           {
5313           g = string_append_listele(g, ',', US"send=no");
5314           sub_arg[1] = US"DUMMY";
5315           }
5316
5317         /* Re-marshall the options */
5318
5319         if (sub_arg[2])
5320           {
5321           const uschar * list = sub_arg[2];
5322           uschar * item;
5323           int sep = 0;
5324
5325           /* First option has no tag and is timeout */
5326           if ((item = string_nextinlist(&list, &sep, NULL, 0)))
5327             g = string_append_listele(g, ',',
5328                   string_sprintf("timeout=%s", item));
5329
5330           /* The rest of the options from the expansion */
5331           while ((item = string_nextinlist(&list, &sep, NULL, 0)))
5332             g = string_append_listele(g, ',', item);
5333
5334           /* possibly plus an EOL string.  Process with escapes, to protect
5335           from list-processing.  The only current user of eol= in search
5336           options is the readsock expansion. */
5337
5338           if (sub_arg[3] && *sub_arg[3])
5339             g = string_append_listele(g, ',',
5340                   string_sprintf("eol=%s",
5341                     string_printing2(sub_arg[3], SP_TAB|SP_SPACE)));
5342           }
5343
5344         /* Gat a (possibly cached) handle for the connection */
5345
5346         if (!(handle = search_open(sub_arg[0], stype, 0, NULL, NULL)))
5347           {
5348           if (*expand_string_message) goto EXPAND_FAILED;
5349           expand_string_message = search_error_message;
5350           search_error_message = NULL;
5351           goto SOCK_FAIL;
5352           }
5353
5354         /* Get (possibly cached) results for the lookup */
5355         /* sspec: sub_arg[0]  req: sub_arg[1]  opts: g */
5356
5357         if ((s = search_find(handle, sub_arg[0], sub_arg[1], -1, NULL, 0, 0,
5358                                     &expand_setup, string_from_gstring(g))))
5359           yield = string_cat(yield, s);
5360         else if (f.search_find_defer)
5361           {
5362           expand_string_message = search_error_message;
5363           search_error_message = NULL;
5364           goto SOCK_FAIL;
5365           }
5366         else
5367           {     /* should not happen, at present */
5368           expand_string_message = search_error_message;
5369           search_error_message = NULL;
5370           goto SOCK_FAIL;
5371           }
5372         }
5373
5374       /* The whole thing has worked (or we were skipping). If there is a
5375       failure string following, we need to skip it. */
5376
5377       if (*s == '{')
5378         {
5379         if (!expand_string_internal(s+1, TRUE, &s, TRUE, TRUE, &resetok))
5380           goto EXPAND_FAILED;
5381         if (*s++ != '}')
5382           {
5383           expand_string_message = US"missing '}' closing failstring for readsocket";
5384           goto EXPAND_FAILED_CURLY;
5385           }
5386         Uskip_whitespace(&s);
5387         }
5388
5389     READSOCK_DONE:
5390       if (*s++ != '}')
5391         {
5392         expand_string_message = US"missing '}' closing readsocket";
5393         goto EXPAND_FAILED_CURLY;
5394         }
5395       continue;
5396
5397       /* Come here on failure to create socket, connect socket, write to the
5398       socket, or timeout on reading. If another substring follows, expand and
5399       use it. Otherwise, those conditions give expand errors. */
5400
5401     SOCK_FAIL:
5402       if (*s != '{') goto EXPAND_FAILED;
5403       DEBUG(D_any) debug_printf("%s\n", expand_string_message);
5404       if (!(arg = expand_string_internal(s+1, TRUE, &s, FALSE, TRUE, &resetok)))
5405         goto EXPAND_FAILED;
5406       yield = string_cat(yield, arg);
5407       if (*s++ != '}')
5408         {
5409         expand_string_message = US"missing '}' closing failstring for readsocket";
5410         goto EXPAND_FAILED_CURLY;
5411         }
5412       Uskip_whitespace(&s);
5413       goto READSOCK_DONE;
5414       }
5415
5416     /* Handle "run" to execute a program. */
5417
5418     case EITEM_RUN:
5419       {
5420       FILE *f;
5421       uschar *arg;
5422       const uschar **argv;
5423       pid_t pid;
5424       int fd_in, fd_out;
5425
5426       if ((expand_forbid & RDO_RUN) != 0)
5427         {
5428         expand_string_message = US"running a command is not permitted";
5429         goto EXPAND_FAILED;
5430         }
5431
5432       Uskip_whitespace(&s);
5433       if (*s != '{')
5434         {
5435         expand_string_message = US"missing '{' for command arg of run";
5436         goto EXPAND_FAILED_CURLY;
5437         }
5438       if (!(arg = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok)))
5439         goto EXPAND_FAILED;
5440       Uskip_whitespace(&s);
5441       if (*s++ != '}')
5442         {
5443         expand_string_message = US"missing '}' closing command arg of run";
5444         goto EXPAND_FAILED_CURLY;
5445         }
5446
5447       if (skipping)   /* Just pretend it worked when we're skipping */
5448         {
5449         runrc = 0;
5450         lookup_value = NULL;
5451         }
5452       else
5453         {
5454         if (!transport_set_up_command(&argv,    /* anchor for arg list */
5455             arg,                                /* raw command */
5456             FALSE,                              /* don't expand the arguments */
5457             0,                                  /* not relevant when... */
5458             NULL,                               /* no transporting address */
5459             US"${run} expansion",               /* for error messages */
5460             &expand_string_message))            /* where to put error message */
5461           goto EXPAND_FAILED;
5462
5463         /* Create the child process, making it a group leader. */
5464
5465         if ((pid = child_open(USS argv, NULL, 0077, &fd_in, &fd_out, TRUE,
5466                               US"expand-run")) < 0)
5467           {
5468           expand_string_message =
5469             string_sprintf("couldn't create child process: %s", strerror(errno));
5470           goto EXPAND_FAILED;
5471           }
5472
5473         /* Nothing is written to the standard input. */
5474
5475         (void)close(fd_in);
5476
5477         /* Read the pipe to get the command's output into $value (which is kept
5478         in lookup_value). Read during execution, so that if the output exceeds
5479         the OS pipe buffer limit, we don't block forever. Remember to not release
5480         memory just allocated for $value. */
5481
5482         resetok = FALSE;
5483         f = fdopen(fd_out, "rb");
5484         sigalrm_seen = FALSE;
5485         ALARM(60);
5486         lookup_value = string_from_gstring(cat_file(f, NULL, NULL));
5487         ALARM_CLR(0);
5488         (void)fclose(f);
5489
5490         /* Wait for the process to finish, applying the timeout, and inspect its
5491         return code for serious disasters. Simple non-zero returns are passed on.
5492         */
5493
5494         if (sigalrm_seen || (runrc = child_close(pid, 30)) < 0)
5495           {
5496           if (sigalrm_seen || runrc == -256)
5497             {
5498             expand_string_message = US"command timed out";
5499             killpg(pid, SIGKILL);       /* Kill the whole process group */
5500             }
5501
5502           else if (runrc == -257)
5503             expand_string_message = string_sprintf("wait() failed: %s",
5504               strerror(errno));
5505
5506           else
5507             expand_string_message = string_sprintf("command killed by signal %d",
5508               -runrc);
5509
5510           goto EXPAND_FAILED;
5511           }
5512         }
5513
5514       /* Process the yes/no strings; $value may be useful in both cases */
5515
5516       switch(process_yesno(
5517                skipping,                     /* were previously skipping */
5518                runrc == 0,                   /* success/failure indicator */
5519                lookup_value,                 /* value to reset for string2 */
5520                &s,                           /* input pointer */
5521                &yield,                       /* output pointer */
5522                US"run",                      /* condition type */
5523                &resetok))
5524         {
5525         case 1: goto EXPAND_FAILED;          /* when all is well, the */
5526         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
5527         }
5528
5529       continue;
5530       }
5531
5532     /* Handle character translation for "tr" */
5533
5534     case EITEM_TR:
5535       {
5536       int oldptr = gstring_length(yield);
5537       int o2m;
5538       uschar *sub[3];
5539
5540       switch(read_subs(sub, 3, 3, &s, skipping, TRUE, name, &resetok))
5541         {
5542         case 1: goto EXPAND_FAILED_CURLY;
5543         case 2:
5544         case 3: goto EXPAND_FAILED;
5545         }
5546
5547       yield = string_cat(yield, sub[0]);
5548       o2m = Ustrlen(sub[2]) - 1;
5549
5550       if (o2m >= 0) for (; oldptr < yield->ptr; oldptr++)
5551         {
5552         uschar *m = Ustrrchr(sub[1], yield->s[oldptr]);
5553         if (m)
5554           {
5555           int o = m - sub[1];
5556           yield->s[oldptr] = sub[2][(o < o2m)? o : o2m];
5557           }
5558         }
5559
5560       continue;
5561       }
5562
5563     /* Handle "hash", "length", "nhash", and "substr" when they are given with
5564     expanded arguments. */
5565
5566     case EITEM_HASH:
5567     case EITEM_LENGTH:
5568     case EITEM_NHASH:
5569     case EITEM_SUBSTR:
5570       {
5571       int len;
5572       uschar *ret;
5573       int val[2] = { 0, -1 };
5574       uschar *sub[3];
5575
5576       /* "length" takes only 2 arguments whereas the others take 2 or 3.
5577       Ensure that sub[2] is set in the ${length } case. */
5578
5579       sub[2] = NULL;
5580       switch(read_subs(sub, (item_type == EITEM_LENGTH)? 2:3, 2, &s, skipping,
5581              TRUE, name, &resetok))
5582         {
5583         case 1: goto EXPAND_FAILED_CURLY;
5584         case 2:
5585         case 3: goto EXPAND_FAILED;
5586         }
5587
5588       /* Juggle the arguments if there are only two of them: always move the
5589       string to the last position and make ${length{n}{str}} equivalent to
5590       ${substr{0}{n}{str}}. See the defaults for val[] above. */
5591
5592       if (!sub[2])
5593         {
5594         sub[2] = sub[1];
5595         sub[1] = NULL;
5596         if (item_type == EITEM_LENGTH)
5597           {
5598           sub[1] = sub[0];
5599           sub[0] = NULL;
5600           }
5601         }
5602
5603       for (int i = 0; i < 2; i++) if (sub[i])
5604         {
5605         val[i] = (int)Ustrtol(sub[i], &ret, 10);
5606         if (*ret != 0 || (i != 0 && val[i] < 0))
5607           {
5608           expand_string_message = string_sprintf("\"%s\" is not a%s number "
5609             "(in \"%s\" expansion)", sub[i], (i != 0)? " positive" : "", name);
5610           goto EXPAND_FAILED;
5611           }
5612         }
5613
5614       ret =
5615         item_type == EITEM_HASH
5616         ?  compute_hash(sub[2], val[0], val[1], &len)
5617         : item_type == EITEM_NHASH
5618         ? compute_nhash(sub[2], val[0], val[1], &len)
5619         : extract_substr(sub[2], val[0], val[1], &len);
5620       if (!ret)
5621         goto EXPAND_FAILED;
5622       yield = string_catn(yield, ret, len);
5623       continue;
5624       }
5625
5626     /* Handle HMAC computation: ${hmac{<algorithm>}{<secret>}{<text>}}
5627     This code originally contributed by Steve Haslam. It currently supports
5628     the use of MD5 and SHA-1 hashes.
5629
5630     We need some workspace that is large enough to handle all the supported
5631     hash types. Use macros to set the sizes rather than be too elaborate. */
5632
5633     #define MAX_HASHLEN      20
5634     #define MAX_HASHBLOCKLEN 64
5635
5636     case EITEM_HMAC:
5637       {
5638       uschar *sub[3];
5639       md5 md5_base;
5640       hctx sha1_ctx;
5641       void *use_base;
5642       int type;
5643       int hashlen;      /* Number of octets for the hash algorithm's output */
5644       int hashblocklen; /* Number of octets the hash algorithm processes */
5645       uschar *keyptr, *p;
5646       unsigned int keylen;
5647
5648       uschar keyhash[MAX_HASHLEN];
5649       uschar innerhash[MAX_HASHLEN];
5650       uschar finalhash[MAX_HASHLEN];
5651       uschar finalhash_hex[2*MAX_HASHLEN];
5652       uschar innerkey[MAX_HASHBLOCKLEN];
5653       uschar outerkey[MAX_HASHBLOCKLEN];
5654
5655       switch (read_subs(sub, 3, 3, &s, skipping, TRUE, name, &resetok))
5656         {
5657         case 1: goto EXPAND_FAILED_CURLY;
5658         case 2:
5659         case 3: goto EXPAND_FAILED;
5660         }
5661
5662       if (!skipping)
5663         {
5664         if (Ustrcmp(sub[0], "md5") == 0)
5665           {
5666           type = HMAC_MD5;
5667           use_base = &md5_base;
5668           hashlen = 16;
5669           hashblocklen = 64;
5670           }
5671         else if (Ustrcmp(sub[0], "sha1") == 0)
5672           {
5673           type = HMAC_SHA1;
5674           use_base = &sha1_ctx;
5675           hashlen = 20;
5676           hashblocklen = 64;
5677           }
5678         else
5679           {
5680           expand_string_message =
5681             string_sprintf("hmac algorithm \"%s\" is not recognised", sub[0]);
5682           goto EXPAND_FAILED;
5683           }
5684
5685         keyptr = sub[1];
5686         keylen = Ustrlen(keyptr);
5687
5688         /* If the key is longer than the hash block length, then hash the key
5689         first */
5690
5691         if (keylen > hashblocklen)
5692           {
5693           chash_start(type, use_base);
5694           chash_end(type, use_base, keyptr, keylen, keyhash);
5695           keyptr = keyhash;
5696           keylen = hashlen;
5697           }
5698
5699         /* Now make the inner and outer key values */
5700
5701         memset(innerkey, 0x36, hashblocklen);
5702         memset(outerkey, 0x5c, hashblocklen);
5703
5704         for (int i = 0; i < keylen; i++)
5705           {
5706           innerkey[i] ^= keyptr[i];
5707           outerkey[i] ^= keyptr[i];
5708           }
5709
5710         /* Now do the hashes */
5711
5712         chash_start(type, use_base);
5713         chash_mid(type, use_base, innerkey);
5714         chash_end(type, use_base, sub[2], Ustrlen(sub[2]), innerhash);
5715
5716         chash_start(type, use_base);
5717         chash_mid(type, use_base, outerkey);
5718         chash_end(type, use_base, innerhash, hashlen, finalhash);
5719
5720         /* Encode the final hash as a hex string */
5721
5722         p = finalhash_hex;
5723         for (int i = 0; i < hashlen; i++)
5724           {
5725           *p++ = hex_digits[(finalhash[i] & 0xf0) >> 4];
5726           *p++ = hex_digits[finalhash[i] & 0x0f];
5727           }
5728
5729         DEBUG(D_any) debug_printf("HMAC[%s](%.*s,%s)=%.*s\n",
5730           sub[0], (int)keylen, keyptr, sub[2], hashlen*2, finalhash_hex);
5731
5732         yield = string_catn(yield, finalhash_hex, hashlen*2);
5733         }
5734       continue;
5735       }
5736
5737     /* Handle global substitution for "sg" - like Perl's s/xxx/yyy/g operator.
5738     We have to save the numerical variables and restore them afterwards. */
5739
5740     case EITEM_SG:
5741       {
5742       const pcre *re;
5743       int moffset, moffsetextra, slen;
5744       int roffset;
5745       int emptyopt;
5746       const uschar *rerror;
5747       uschar *subject;
5748       uschar *sub[3];
5749       int save_expand_nmax =
5750         save_expand_strings(save_expand_nstring, save_expand_nlength);
5751
5752       switch(read_subs(sub, 3, 3, &s, skipping, TRUE, name, &resetok))
5753         {
5754         case 1: goto EXPAND_FAILED_CURLY;
5755         case 2:
5756         case 3: goto EXPAND_FAILED;
5757         }
5758
5759       /* Compile the regular expression */
5760
5761       if (!(re = pcre_compile(CS sub[1], PCRE_COPT, CCSS &rerror,
5762                               &roffset, NULL)))
5763         {
5764         expand_string_message = string_sprintf("regular expression error in "
5765           "\"%s\": %s at offset %d", sub[1], rerror, roffset);
5766         goto EXPAND_FAILED;
5767         }
5768
5769       /* Now run a loop to do the substitutions as often as necessary. It ends
5770       when there are no more matches. Take care over matches of the null string;
5771       do the same thing as Perl does. */
5772
5773       subject = sub[0];
5774       slen = Ustrlen(sub[0]);
5775       moffset = moffsetextra = 0;
5776       emptyopt = 0;
5777
5778       for (;;)
5779         {
5780         int ovector[3*(EXPAND_MAXN+1)];
5781         int n = pcre_exec(re, NULL, CS subject, slen, moffset + moffsetextra,
5782           PCRE_EOPT | emptyopt, ovector, nelem(ovector));
5783         uschar *insert;
5784
5785         /* No match - if we previously set PCRE_NOTEMPTY after a null match, this
5786         is not necessarily the end. We want to repeat the match from one
5787         character further along, but leaving the basic offset the same (for
5788         copying below). We can't be at the end of the string - that was checked
5789         before setting PCRE_NOTEMPTY. If PCRE_NOTEMPTY is not set, we are
5790         finished; copy the remaining string and end the loop. */
5791
5792         if (n < 0)
5793           {
5794           if (emptyopt != 0)
5795             {
5796             moffsetextra = 1;
5797             emptyopt = 0;
5798             continue;
5799             }
5800           yield = string_catn(yield, subject+moffset, slen-moffset);
5801           break;
5802           }
5803
5804         /* Match - set up for expanding the replacement. */
5805
5806         if (n == 0) n = EXPAND_MAXN + 1;
5807         expand_nmax = 0;
5808         for (int nn = 0; nn < n*2; nn += 2)
5809           {
5810           expand_nstring[expand_nmax] = subject + ovector[nn];
5811           expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
5812           }
5813         expand_nmax--;
5814
5815         /* Copy the characters before the match, plus the expanded insertion. */
5816
5817         yield = string_catn(yield, subject + moffset, ovector[0] - moffset);
5818         if (!(insert = expand_string(sub[2])))
5819           goto EXPAND_FAILED;
5820         yield = string_cat(yield, insert);
5821
5822         moffset = ovector[1];
5823         moffsetextra = 0;
5824         emptyopt = 0;
5825
5826         /* If we have matched an empty string, first check to see if we are at
5827         the end of the subject. If so, the loop is over. Otherwise, mimic
5828         what Perl's /g options does. This turns out to be rather cunning. First
5829         we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match a non-empty
5830         string at the same point. If this fails (picked up above) we advance to
5831         the next character. */
5832
5833         if (ovector[0] == ovector[1])
5834           {
5835           if (ovector[0] == slen) break;
5836           emptyopt = PCRE_NOTEMPTY | PCRE_ANCHORED;
5837           }
5838         }
5839
5840       /* All done - restore numerical variables. */
5841
5842       restore_expand_strings(save_expand_nmax, save_expand_nstring,
5843         save_expand_nlength);
5844       continue;
5845       }
5846
5847     /* Handle keyed and numbered substring extraction. If the first argument
5848     consists entirely of digits, then a numerical extraction is assumed. */
5849
5850     case EITEM_EXTRACT:
5851       {
5852       int field_number = 1;
5853       BOOL field_number_set = FALSE;
5854       uschar *save_lookup_value = lookup_value;
5855       uschar *sub[3];
5856       int save_expand_nmax =
5857         save_expand_strings(save_expand_nstring, save_expand_nlength);
5858
5859       /* On reflection the original behaviour of extract-json for a string
5860       result, leaving it quoted, was a mistake.  But it was already published,
5861       hence the addition of jsons.  In a future major version, make json
5862       work like josons, and withdraw jsons. */
5863
5864       enum {extract_basic, extract_json, extract_jsons} fmt = extract_basic;
5865
5866       /* Check for a format-variant specifier */
5867
5868       if (Uskip_whitespace(&s) != '{')                                  /*}*/
5869         if (Ustrncmp(s, "json", 4) == 0)
5870           if (*(s += 4) == 's')
5871             {fmt = extract_jsons; s++;}
5872           else
5873             fmt = extract_json;
5874
5875       /* While skipping we cannot rely on the data for expansions being
5876       available (eg. $item) hence cannot decide on numeric vs. keyed.
5877       Read a maximum of 5 arguments (including the yes/no) */
5878
5879       if (skipping)
5880         {
5881         for (int j = 5; j > 0 && *s == '{'; j--)                /*'}'*/
5882           {
5883           if (!expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok))
5884             goto EXPAND_FAILED;                                 /*'{'*/
5885           if (*s++ != '}')
5886             {
5887             expand_string_message = US"missing '{' for arg of extract";
5888             goto EXPAND_FAILED_CURLY;
5889             }
5890           Uskip_whitespace(&s);
5891           }
5892         if (  Ustrncmp(s, "fail", 4) == 0                       /*'{'*/
5893            && (s[4] == '}' || s[4] == ' ' || s[4] == '\t' || !s[4])
5894            )
5895           {
5896           s += 4;
5897           Uskip_whitespace(&s);
5898           }                                                     /*'{'*/
5899         if (*s != '}')
5900           {
5901           expand_string_message = US"missing '}' closing extract";
5902           goto EXPAND_FAILED_CURLY;
5903           }
5904         }
5905
5906       else for (int i = 0, j = 2; i < j; i++) /* Read the proper number of arguments */
5907         {
5908         if (Uskip_whitespace(&s) == '{')                                                /*'}'*/
5909           {
5910           if (!(sub[i] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok)))
5911             goto EXPAND_FAILED;                                 /*'{'*/
5912           if (*s++ != '}')
5913             {
5914             expand_string_message = string_sprintf(
5915               "missing '}' closing arg %d of extract", i+1);
5916             goto EXPAND_FAILED_CURLY;
5917             }
5918
5919           /* After removal of leading and trailing white space, the first
5920           argument must not be empty; if it consists entirely of digits
5921           (optionally preceded by a minus sign), this is a numerical
5922           extraction, and we expect 3 arguments (normal) or 2 (json). */
5923
5924           if (i == 0)
5925             {
5926             int len;
5927             int x = 0;
5928             uschar *p = sub[0];
5929
5930             Uskip_whitespace(&p);
5931             sub[0] = p;
5932
5933             len = Ustrlen(p);
5934             while (len > 0 && isspace(p[len-1])) len--;
5935             p[len] = 0;
5936
5937             if (*p == 0)
5938               {
5939               expand_string_message = US"first argument of \"extract\" must "
5940                 "not be empty";
5941               goto EXPAND_FAILED;
5942               }
5943
5944             if (*p == '-')
5945               {
5946               field_number = -1;
5947               p++;
5948               }
5949             while (*p != 0 && isdigit(*p)) x = x * 10 + *p++ - '0';
5950             if (*p == 0)
5951               {
5952               field_number *= x;
5953               if (fmt == extract_basic) j = 3;               /* Need 3 args */
5954               field_number_set = TRUE;
5955               }
5956             }
5957           }
5958         else
5959           {
5960           expand_string_message = string_sprintf(
5961             "missing '{' for arg %d of extract", i+1);
5962           goto EXPAND_FAILED_CURLY;
5963           }
5964         }
5965
5966       /* Extract either the numbered or the keyed substring into $value. If
5967       skipping, just pretend the extraction failed. */
5968
5969       if (skipping)
5970         lookup_value = NULL;
5971       else switch (fmt)
5972         {
5973         case extract_basic:
5974           lookup_value = field_number_set
5975             ? expand_gettokened(field_number, sub[1], sub[2])
5976             : expand_getkeyed(sub[0], sub[1]);
5977           break;
5978
5979         case extract_json:
5980         case extract_jsons:
5981           {
5982           uschar * s, * item;
5983           const uschar * list;
5984
5985           /* Array: Bracket-enclosed and comma-separated.
5986           Object: Brace-enclosed, comma-sep list of name:value pairs */
5987
5988           if (!(s = dewrap(sub[1], field_number_set ? US"[]" : US"{}")))
5989             {
5990             expand_string_message =
5991               string_sprintf("%s wrapping %s for extract json",
5992                 expand_string_message,
5993                 field_number_set ? "array" : "object");
5994             goto EXPAND_FAILED_CURLY;
5995             }
5996
5997           list = s;
5998           if (field_number_set)
5999             {
6000             if (field_number <= 0)
6001               {
6002               expand_string_message = US"first argument of \"extract\" must "
6003                 "be greater than zero";
6004               goto EXPAND_FAILED;
6005               }
6006             while (field_number > 0 && (item = json_nextinlist(&list)))
6007               field_number--;
6008             if ((lookup_value = s = item))
6009               {
6010               while (*s) s++;
6011               while (--s >= lookup_value && isspace(*s)) *s = '\0';
6012               }
6013             }
6014           else
6015             {
6016             lookup_value = NULL;
6017             while ((item = json_nextinlist(&list)))
6018               {
6019               /* Item is:  string name-sep value.  string is quoted.
6020               Dequote the string and compare with the search key. */
6021
6022               if (!(item = dewrap(item, US"\"\"")))
6023                 {
6024                 expand_string_message =
6025                   string_sprintf("%s wrapping string key for extract json",
6026                     expand_string_message);
6027                 goto EXPAND_FAILED_CURLY;
6028                 }
6029               if (Ustrcmp(item, sub[0]) == 0)   /*XXX should be a UTF8-compare */
6030                 {
6031                 s = item + Ustrlen(item) + 1;
6032                 if (Uskip_whitespace(&s) != ':')
6033                   {
6034                   expand_string_message =
6035                     US"missing object value-separator for extract json";
6036                   goto EXPAND_FAILED_CURLY;
6037                   }
6038                 s++;
6039                 Uskip_whitespace(&s);
6040                 lookup_value = s;
6041                 break;
6042                 }
6043               }
6044             }
6045           }
6046
6047           if (  fmt == extract_jsons
6048              && lookup_value
6049              && !(lookup_value = dewrap(lookup_value, US"\"\"")))
6050             {
6051             expand_string_message =
6052               string_sprintf("%s wrapping string result for extract jsons",
6053                 expand_string_message);
6054             goto EXPAND_FAILED_CURLY;
6055             }
6056           break;        /* json/s */
6057         }
6058
6059       /* If no string follows, $value gets substituted; otherwise there can
6060       be yes/no strings, as for lookup or if. */
6061
6062       switch(process_yesno(
6063                skipping,                     /* were previously skipping */
6064                lookup_value != NULL,         /* success/failure indicator */
6065                save_lookup_value,            /* value to reset for string2 */
6066                &s,                           /* input pointer */
6067                &yield,                       /* output pointer */
6068                US"extract",                  /* condition type */
6069                &resetok))
6070         {
6071         case 1: goto EXPAND_FAILED;          /* when all is well, the */
6072         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
6073         }
6074
6075       /* All done - restore numerical variables. */
6076
6077       restore_expand_strings(save_expand_nmax, save_expand_nstring,
6078         save_expand_nlength);
6079
6080       continue;
6081       }
6082
6083     /* return the Nth item from a list */
6084
6085     case EITEM_LISTEXTRACT:
6086       {
6087       int field_number = 1;
6088       uschar *save_lookup_value = lookup_value;
6089       uschar *sub[2];
6090       int save_expand_nmax =
6091         save_expand_strings(save_expand_nstring, save_expand_nlength);
6092
6093       /* Read the field & list arguments */
6094
6095       for (int i = 0; i < 2; i++)
6096         {
6097         if (Uskip_whitespace(&s) != '{')                                        /*'}'*/
6098           {
6099           expand_string_message = string_sprintf(
6100             "missing '{' for arg %d of listextract", i+1);
6101           goto EXPAND_FAILED_CURLY;
6102           }
6103
6104         sub[i] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok);
6105         if (!sub[i])     goto EXPAND_FAILED;            /*{*/
6106         if (*s++ != '}')
6107           {
6108           expand_string_message = string_sprintf(
6109             "missing '}' closing arg %d of listextract", i+1);
6110           goto EXPAND_FAILED_CURLY;
6111           }
6112
6113         /* After removal of leading and trailing white space, the first
6114         argument must be numeric and nonempty. */
6115
6116         if (i == 0)
6117           {
6118           int len;
6119           int x = 0;
6120           uschar *p = sub[0];
6121
6122           Uskip_whitespace(&p);
6123           sub[0] = p;
6124
6125           len = Ustrlen(p);
6126           while (len > 0 && isspace(p[len-1])) len--;
6127           p[len] = 0;
6128
6129           if (!*p && !skipping)
6130             {
6131             expand_string_message = US"first argument of \"listextract\" must "
6132               "not be empty";
6133             goto EXPAND_FAILED;
6134             }
6135
6136           if (*p == '-')
6137             {
6138             field_number = -1;
6139             p++;
6140             }
6141           while (*p && isdigit(*p)) x = x * 10 + *p++ - '0';
6142           if (*p)
6143             {
6144             expand_string_message = US"first argument of \"listextract\" must "
6145               "be numeric";
6146             goto EXPAND_FAILED;
6147             }
6148           field_number *= x;
6149           }
6150         }
6151
6152       /* Extract the numbered element into $value. If
6153       skipping, just pretend the extraction failed. */
6154
6155       lookup_value = skipping ? NULL : expand_getlistele(field_number, sub[1]);
6156
6157       /* If no string follows, $value gets substituted; otherwise there can
6158       be yes/no strings, as for lookup or if. */
6159
6160       switch(process_yesno(
6161                skipping,                     /* were previously skipping */
6162                lookup_value != NULL,         /* success/failure indicator */
6163                save_lookup_value,            /* value to reset for string2 */
6164                &s,                           /* input pointer */
6165                &yield,                       /* output pointer */
6166                US"listextract",              /* condition type */
6167                &resetok))
6168         {
6169         case 1: goto EXPAND_FAILED;          /* when all is well, the */
6170         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
6171         }
6172
6173       /* All done - restore numerical variables. */
6174
6175       restore_expand_strings(save_expand_nmax, save_expand_nstring,
6176         save_expand_nlength);
6177
6178       continue;
6179       }
6180
6181     case EITEM_LISTQUOTE:
6182       {
6183       uschar * sub[2];
6184       switch(read_subs(sub, 2, 2, &s, skipping, TRUE, name, &resetok))
6185         {
6186         case 1: goto EXPAND_FAILED_CURLY;
6187         case 2:
6188         case 3: goto EXPAND_FAILED;
6189         }
6190       if (*sub[1]) for (uschar sep = *sub[0], c; c = *sub[1]; sub[1]++)
6191         {
6192         if (c == sep) yield = string_catn(yield, sub[1], 1);
6193         yield = string_catn(yield, sub[1], 1);
6194         }
6195       else yield = string_catn(yield, US" ", 1);
6196       continue;
6197       }
6198
6199 #ifndef DISABLE_TLS
6200     case EITEM_CERTEXTRACT:
6201       {
6202       uschar *save_lookup_value = lookup_value;
6203       uschar *sub[2];
6204       int save_expand_nmax =
6205         save_expand_strings(save_expand_nstring, save_expand_nlength);
6206
6207       /* Read the field argument */
6208       if (Uskip_whitespace(&s) != '{')                                  /*}*/
6209         {
6210         expand_string_message = US"missing '{' for field arg of certextract";
6211         goto EXPAND_FAILED_CURLY;
6212         }
6213       sub[0] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok);
6214       if (!sub[0])     goto EXPAND_FAILED;              /*{*/
6215       if (*s++ != '}')
6216         {
6217         expand_string_message = US"missing '}' closing field arg of certextract";
6218         goto EXPAND_FAILED_CURLY;
6219         }
6220       /* strip spaces fore & aft */
6221       {
6222       int len;
6223       uschar *p = sub[0];
6224
6225       Uskip_whitespace(&p);
6226       sub[0] = p;
6227
6228       len = Ustrlen(p);
6229       while (len > 0 && isspace(p[len-1])) len--;
6230       p[len] = 0;
6231       }
6232
6233       /* inspect the cert argument */
6234       if (Uskip_whitespace(&s) != '{')                                  /*}*/
6235         {
6236         expand_string_message = US"missing '{' for cert variable arg of certextract";
6237         goto EXPAND_FAILED_CURLY;
6238         }
6239       if (*++s != '$')
6240         {
6241         expand_string_message = US"second argument of \"certextract\" must "
6242           "be a certificate variable";
6243         goto EXPAND_FAILED;
6244         }
6245       sub[1] = expand_string_internal(s+1, TRUE, &s, skipping, FALSE, &resetok);
6246       if (!sub[1])     goto EXPAND_FAILED;              /*{*/
6247       if (*s++ != '}')
6248         {
6249         expand_string_message = US"missing '}' closing cert variable arg of certextract";
6250         goto EXPAND_FAILED_CURLY;
6251         }
6252
6253       if (skipping)
6254         lookup_value = NULL;
6255       else
6256         {
6257         lookup_value = expand_getcertele(sub[0], sub[1]);
6258         if (*expand_string_message) goto EXPAND_FAILED;
6259         }
6260       switch(process_yesno(
6261                skipping,                     /* were previously skipping */
6262                lookup_value != NULL,         /* success/failure indicator */
6263                save_lookup_value,            /* value to reset for string2 */
6264                &s,                           /* input pointer */
6265                &yield,                       /* output pointer */
6266                US"certextract",              /* condition type */
6267                &resetok))
6268         {
6269         case 1: goto EXPAND_FAILED;          /* when all is well, the */
6270         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
6271         }
6272
6273       restore_expand_strings(save_expand_nmax, save_expand_nstring,
6274         save_expand_nlength);
6275       continue;
6276       }
6277 #endif  /*DISABLE_TLS*/
6278
6279     /* Handle list operations */
6280
6281     case EITEM_FILTER:
6282     case EITEM_MAP:
6283     case EITEM_REDUCE:
6284       {
6285       int sep = 0;
6286       int save_ptr = gstring_length(yield);
6287       uschar outsep[2] = { '\0', '\0' };
6288       const uschar *list, *expr, *temp;
6289       uschar *save_iterate_item = iterate_item;
6290       uschar *save_lookup_value = lookup_value;
6291
6292       Uskip_whitespace(&s);
6293       if (*s++ != '{')
6294         {
6295         expand_string_message =
6296           string_sprintf("missing '{' for first arg of %s", name);
6297         goto EXPAND_FAILED_CURLY;
6298         }
6299
6300       if (!(list = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok)))
6301         goto EXPAND_FAILED;
6302       if (*s++ != '}')
6303         {
6304         expand_string_message =
6305           string_sprintf("missing '}' closing first arg of %s", name);
6306         goto EXPAND_FAILED_CURLY;
6307         }
6308
6309       if (item_type == EITEM_REDUCE)
6310         {
6311         uschar * t;
6312         Uskip_whitespace(&s);
6313         if (*s++ != '{')
6314           {
6315           expand_string_message = US"missing '{' for second arg of reduce";
6316           goto EXPAND_FAILED_CURLY;
6317           }
6318         t = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok);
6319         if (!t) goto EXPAND_FAILED;
6320         lookup_value = t;
6321         if (*s++ != '}')
6322           {
6323           expand_string_message = US"missing '}' closing second arg of reduce";
6324           goto EXPAND_FAILED_CURLY;
6325           }
6326         }
6327
6328       Uskip_whitespace(&s);
6329       if (*s++ != '{')
6330         {
6331         expand_string_message =
6332           string_sprintf("missing '{' for last arg of %s", name);
6333         goto EXPAND_FAILED_CURLY;
6334         }
6335
6336       expr = s;
6337
6338       /* For EITEM_FILTER, call eval_condition once, with result discarded (as
6339       if scanning a "false" part). This allows us to find the end of the
6340       condition, because if the list is empty, we won't actually evaluate the
6341       condition for real. For EITEM_MAP and EITEM_REDUCE, do the same, using
6342       the normal internal expansion function. */
6343
6344       if (item_type == EITEM_FILTER)
6345         {
6346         if ((temp = eval_condition(expr, &resetok, NULL)))
6347           s = temp;
6348         }
6349       else
6350         temp = expand_string_internal(s, TRUE, &s, TRUE, TRUE, &resetok);
6351
6352       if (!temp)
6353         {
6354         expand_string_message = string_sprintf("%s inside \"%s\" item",
6355           expand_string_message, name);
6356         goto EXPAND_FAILED;
6357         }
6358
6359       Uskip_whitespace(&s);
6360       if (*s++ != '}')
6361         {                                               /*{*/
6362         expand_string_message = string_sprintf("missing } at end of condition "
6363           "or expression inside \"%s\"; could be an unquoted } in the content",
6364           name);
6365         goto EXPAND_FAILED;
6366         }
6367
6368       Uskip_whitespace(&s);                             /*{*/
6369       if (*s++ != '}')
6370         {                                               /*{*/
6371         expand_string_message = string_sprintf("missing } at end of \"%s\"",
6372           name);
6373         goto EXPAND_FAILED;
6374         }
6375
6376       /* If we are skipping, we can now just move on to the next item. When
6377       processing for real, we perform the iteration. */
6378
6379       if (skipping) continue;
6380       while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)))
6381         {
6382         *outsep = (uschar)sep;      /* Separator as a string */
6383
6384         DEBUG(D_expand) debug_printf_indent("%s: $item = '%s'  $value = '%s'\n",
6385                           name, iterate_item, lookup_value);
6386
6387         if (item_type == EITEM_FILTER)
6388           {
6389           BOOL condresult;
6390           if (!eval_condition(expr, &resetok, &condresult))
6391             {
6392             iterate_item = save_iterate_item;
6393             lookup_value = save_lookup_value;
6394             expand_string_message = string_sprintf("%s inside \"%s\" condition",
6395               expand_string_message, name);
6396             goto EXPAND_FAILED;
6397             }
6398           DEBUG(D_expand) debug_printf_indent("%s: condition is %s\n", name,
6399             condresult? "true":"false");
6400           if (condresult)
6401             temp = iterate_item;    /* TRUE => include this item */
6402           else
6403             continue;               /* FALSE => skip this item */
6404           }
6405
6406         /* EITEM_MAP and EITEM_REDUCE */
6407
6408         else
6409           {
6410           uschar * t = expand_string_internal(expr, TRUE, NULL, skipping, TRUE, &resetok);
6411           temp = t;
6412           if (!temp)
6413             {
6414             iterate_item = save_iterate_item;
6415             expand_string_message = string_sprintf("%s inside \"%s\" item",
6416               expand_string_message, name);
6417             goto EXPAND_FAILED;
6418             }
6419           if (item_type == EITEM_REDUCE)
6420             {
6421             lookup_value = t;         /* Update the value of $value */
6422             continue;                 /* and continue the iteration */
6423             }
6424           }
6425
6426         /* We reach here for FILTER if the condition is true, always for MAP,
6427         and never for REDUCE. The value in "temp" is to be added to the output
6428         list that is being created, ensuring that any occurrences of the
6429         separator character are doubled. Unless we are dealing with the first
6430         item of the output list, add in a space if the new item begins with the
6431         separator character, or is an empty string. */
6432
6433         if (  yield && yield->ptr != save_ptr
6434            && (temp[0] == *outsep || temp[0] == 0))
6435           yield = string_catn(yield, US" ", 1);
6436
6437         /* Add the string in "temp" to the output list that we are building,
6438         This is done in chunks by searching for the separator character. */
6439
6440         for (;;)
6441           {
6442           size_t seglen = Ustrcspn(temp, outsep);
6443
6444           yield = string_catn(yield, temp, seglen + 1);
6445
6446           /* If we got to the end of the string we output one character
6447           too many; backup and end the loop. Otherwise arrange to double the
6448           separator. */
6449
6450           if (temp[seglen] == '\0') { yield->ptr--; break; }
6451           yield = string_catn(yield, outsep, 1);
6452           temp += seglen + 1;
6453           }
6454
6455         /* Output a separator after the string: we will remove the redundant
6456         final one at the end. */
6457
6458         yield = string_catn(yield, outsep, 1);
6459         }   /* End of iteration over the list loop */
6460
6461       /* REDUCE has generated no output above: output the final value of
6462       $value. */
6463
6464       if (item_type == EITEM_REDUCE)
6465         {
6466         yield = string_cat(yield, lookup_value);
6467         lookup_value = save_lookup_value;  /* Restore $value */
6468         }
6469
6470       /* FILTER and MAP generate lists: if they have generated anything, remove
6471       the redundant final separator. Even though an empty item at the end of a
6472       list does not count, this is tidier. */
6473
6474       else if (yield && yield->ptr != save_ptr) yield->ptr--;
6475
6476       /* Restore preserved $item */
6477
6478       iterate_item = save_iterate_item;
6479       continue;
6480       }
6481
6482     case EITEM_SORT:
6483       {
6484       int cond_type;
6485       int sep = 0;
6486       const uschar *srclist, *cmp, *xtract;
6487       uschar * opname, * srcitem;
6488       const uschar *dstlist = NULL, *dstkeylist = NULL;
6489       uschar * tmp;
6490       uschar *save_iterate_item = iterate_item;
6491
6492       Uskip_whitespace(&s);
6493       if (*s++ != '{')
6494         {
6495         expand_string_message = US"missing '{' for list arg of sort";
6496         goto EXPAND_FAILED_CURLY;
6497         }
6498
6499       srclist = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok);
6500       if (!srclist) goto EXPAND_FAILED;
6501       if (*s++ != '}')
6502         {
6503         expand_string_message = US"missing '}' closing list arg of sort";
6504         goto EXPAND_FAILED_CURLY;
6505         }
6506
6507       Uskip_whitespace(&s);
6508       if (*s++ != '{')
6509         {
6510         expand_string_message = US"missing '{' for comparator arg of sort";
6511         goto EXPAND_FAILED_CURLY;
6512         }
6513
6514       cmp = expand_string_internal(s, TRUE, &s, skipping, FALSE, &resetok);
6515       if (!cmp) goto EXPAND_FAILED;
6516       if (*s++ != '}')
6517         {
6518         expand_string_message = US"missing '}' closing comparator arg of sort";
6519         goto EXPAND_FAILED_CURLY;
6520         }
6521
6522       if ((cond_type = identify_operator(&cmp, &opname)) == -1)
6523         {
6524         if (!expand_string_message)
6525           expand_string_message = string_sprintf("unknown condition \"%s\"", s);
6526         goto EXPAND_FAILED;
6527         }
6528       switch(cond_type)
6529         {
6530         case ECOND_NUM_L: case ECOND_NUM_LE:
6531         case ECOND_NUM_G: case ECOND_NUM_GE:
6532         case ECOND_STR_GE: case ECOND_STR_GEI: case ECOND_STR_GT: case ECOND_STR_GTI:
6533         case ECOND_STR_LE: case ECOND_STR_LEI: case ECOND_STR_LT: case ECOND_STR_LTI:
6534           break;
6535
6536         default:
6537           expand_string_message = US"comparator not handled for sort";
6538           goto EXPAND_FAILED;
6539         }
6540
6541       Uskip_whitespace(&s);
6542       if (*s++ != '{')
6543         {
6544         expand_string_message = US"missing '{' for extractor arg of sort";
6545         goto EXPAND_FAILED_CURLY;
6546         }
6547
6548       xtract = s;
6549       if (!(tmp = expand_string_internal(s, TRUE, &s, TRUE, TRUE, &resetok)))
6550         goto EXPAND_FAILED;
6551       xtract = string_copyn(xtract, s - xtract);
6552
6553       if (*s++ != '}')
6554         {
6555         expand_string_message = US"missing '}' closing extractor arg of sort";
6556         goto EXPAND_FAILED_CURLY;
6557         }
6558                                                         /*{*/
6559       if (*s++ != '}')
6560         {                                               /*{*/
6561         expand_string_message = US"missing } at end of \"sort\"";
6562         goto EXPAND_FAILED;
6563         }
6564
6565       if (skipping) continue;
6566
6567       while ((srcitem = string_nextinlist(&srclist, &sep, NULL, 0)))
6568         {
6569         uschar * srcfield, * dstitem;
6570         gstring * newlist = NULL;
6571         gstring * newkeylist = NULL;
6572
6573         DEBUG(D_expand) debug_printf_indent("%s: $item = \"%s\"\n", name, srcitem);
6574
6575         /* extract field for comparisons */
6576         iterate_item = srcitem;
6577         if (  !(srcfield = expand_string_internal(xtract, FALSE, NULL, FALSE,
6578                                           TRUE, &resetok))
6579            || !*srcfield)
6580           {
6581           expand_string_message = string_sprintf(
6582               "field-extract in sort: \"%s\"", xtract);
6583           goto EXPAND_FAILED;
6584           }
6585
6586         /* Insertion sort */
6587
6588         /* copy output list until new-item < list-item */
6589         while ((dstitem = string_nextinlist(&dstlist, &sep, NULL, 0)))
6590           {
6591           uschar * dstfield;
6592
6593           /* field for comparison */
6594           if (!(dstfield = string_nextinlist(&dstkeylist, &sep, NULL, 0)))
6595             goto sort_mismatch;
6596
6597           /* String-comparator names start with a letter; numeric names do not */
6598
6599           if (sortsbefore(cond_type, isalpha(opname[0]),
6600               srcfield, dstfield))
6601             {
6602             /* New-item sorts before this dst-item.  Append new-item,
6603             then dst-item, then remainder of dst list. */
6604
6605             newlist = string_append_listele(newlist, sep, srcitem);
6606             newkeylist = string_append_listele(newkeylist, sep, srcfield);
6607             srcitem = NULL;
6608
6609             newlist = string_append_listele(newlist, sep, dstitem);
6610             newkeylist = string_append_listele(newkeylist, sep, dstfield);
6611
6612 /*XXX why field-at-a-time copy?  Why not just dup the rest of the list? */
6613             while ((dstitem = string_nextinlist(&dstlist, &sep, NULL, 0)))
6614               {
6615               if (!(dstfield = string_nextinlist(&dstkeylist, &sep, NULL, 0)))
6616                 goto sort_mismatch;
6617               newlist = string_append_listele(newlist, sep, dstitem);
6618               newkeylist = string_append_listele(newkeylist, sep, dstfield);
6619               }
6620
6621             break;
6622             }
6623
6624           newlist = string_append_listele(newlist, sep, dstitem);
6625           newkeylist = string_append_listele(newkeylist, sep, dstfield);
6626           }
6627
6628         /* If we ran out of dstlist without consuming srcitem, append it */
6629         if (srcitem)
6630           {
6631           newlist = string_append_listele(newlist, sep, srcitem);
6632           newkeylist = string_append_listele(newkeylist, sep, srcfield);
6633           }
6634
6635         dstlist = newlist->s;
6636         dstkeylist = newkeylist->s;
6637
6638         DEBUG(D_expand) debug_printf_indent("%s: dstlist = \"%s\"\n", name, dstlist);
6639         DEBUG(D_expand) debug_printf_indent("%s: dstkeylist = \"%s\"\n", name, dstkeylist);
6640         }
6641
6642       if (dstlist)
6643         yield = string_cat(yield, dstlist);
6644
6645       /* Restore preserved $item */
6646       iterate_item = save_iterate_item;
6647       continue;
6648
6649       sort_mismatch:
6650         expand_string_message = US"Internal error in sort (list mismatch)";
6651         goto EXPAND_FAILED;
6652       }
6653
6654
6655     /* If ${dlfunc } support is configured, handle calling dynamically-loaded
6656     functions, unless locked out at this time. Syntax is ${dlfunc{file}{func}}
6657     or ${dlfunc{file}{func}{arg}} or ${dlfunc{file}{func}{arg1}{arg2}} or up to
6658     a maximum of EXPAND_DLFUNC_MAX_ARGS arguments (defined below). */
6659
6660     #define EXPAND_DLFUNC_MAX_ARGS 8
6661
6662     case EITEM_DLFUNC:
6663 #ifndef EXPAND_DLFUNC
6664       expand_string_message = US"\"${dlfunc\" encountered, but this facility "  /*}*/
6665         "is not included in this binary";
6666       goto EXPAND_FAILED;
6667
6668 #else   /* EXPAND_DLFUNC */
6669       {
6670       tree_node *t;
6671       exim_dlfunc_t *func;
6672       uschar *result;
6673       int status, argc;
6674       uschar *argv[EXPAND_DLFUNC_MAX_ARGS + 3];
6675
6676       if ((expand_forbid & RDO_DLFUNC) != 0)
6677         {
6678         expand_string_message =
6679           US"dynamically-loaded functions are not permitted";
6680         goto EXPAND_FAILED;
6681         }
6682
6683       switch(read_subs(argv, EXPAND_DLFUNC_MAX_ARGS + 2, 2, &s, skipping,
6684            TRUE, name, &resetok))
6685         {
6686         case 1: goto EXPAND_FAILED_CURLY;
6687         case 2:
6688         case 3: goto EXPAND_FAILED;
6689         }
6690
6691       /* If skipping, we don't actually do anything */
6692
6693       if (skipping) continue;
6694
6695       /* Look up the dynamically loaded object handle in the tree. If it isn't
6696       found, dlopen() the file and put the handle in the tree for next time. */
6697
6698       if (!(t = tree_search(dlobj_anchor, argv[0])))
6699         {
6700         void *handle = dlopen(CS argv[0], RTLD_LAZY);
6701         if (!handle)
6702           {
6703           expand_string_message = string_sprintf("dlopen \"%s\" failed: %s",
6704             argv[0], dlerror());
6705           log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message);
6706           goto EXPAND_FAILED;
6707           }
6708         t = store_get_perm(sizeof(tree_node) + Ustrlen(argv[0]), is_tainted(argv[0]));
6709         Ustrcpy(t->name, argv[0]);
6710         t->data.ptr = handle;
6711         (void)tree_insertnode(&dlobj_anchor, t);
6712         }
6713
6714       /* Having obtained the dynamically loaded object handle, look up the
6715       function pointer. */
6716
6717       if (!(func = (exim_dlfunc_t *)dlsym(t->data.ptr, CS argv[1])))
6718         {
6719         expand_string_message = string_sprintf("dlsym \"%s\" in \"%s\" failed: "
6720           "%s", argv[1], argv[0], dlerror());
6721         log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message);
6722         goto EXPAND_FAILED;
6723         }
6724
6725       /* Call the function and work out what to do with the result. If it
6726       returns OK, we have a replacement string; if it returns DEFER then
6727       expansion has failed in a non-forced manner; if it returns FAIL then
6728       failure was forced; if it returns ERROR or any other value there's a
6729       problem, so panic slightly. In any case, assume that the function has
6730       side-effects on the store that must be preserved. */
6731
6732       resetok = FALSE;
6733       result = NULL;
6734       for (argc = 0; argv[argc]; argc++);
6735       status = func(&result, argc - 2, &argv[2]);
6736       if(status == OK)
6737         {
6738         if (!result) result = US"";
6739         yield = string_cat(yield, result);
6740         continue;
6741         }
6742       else
6743         {
6744         expand_string_message = result ? result : US"(no message)";
6745         if (status == FAIL_FORCED)
6746           f.expand_string_forcedfail = TRUE;
6747         else if (status != FAIL)
6748           log_write(0, LOG_MAIN|LOG_PANIC, "dlfunc{%s}{%s} failed (%d): %s",
6749               argv[0], argv[1], status, expand_string_message);
6750         goto EXPAND_FAILED;
6751         }
6752       }
6753 #endif /* EXPAND_DLFUNC */
6754
6755     case EITEM_ENV:     /* ${env {name} {val_if_found} {val_if_unfound}} */
6756       {
6757       uschar * key;
6758       uschar *save_lookup_value = lookup_value;
6759
6760       if (Uskip_whitespace(&s) != '{')                                  /*}*/
6761         goto EXPAND_FAILED;
6762
6763       key = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok);
6764       if (!key) goto EXPAND_FAILED;                     /*{*/
6765       if (*s++ != '}')
6766         {
6767         expand_string_message = US"missing '{' for name arg of env";
6768         goto EXPAND_FAILED_CURLY;
6769         }
6770
6771       lookup_value = US getenv(CS key);
6772
6773       switch(process_yesno(
6774                skipping,                     /* were previously skipping */
6775                lookup_value != NULL,         /* success/failure indicator */
6776                save_lookup_value,            /* value to reset for string2 */
6777                &s,                           /* input pointer */
6778                &yield,                       /* output pointer */
6779                US"env",                      /* condition type */
6780                &resetok))
6781         {
6782         case 1: goto EXPAND_FAILED;          /* when all is well, the */
6783         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
6784         }
6785       continue;
6786       }
6787
6788 #ifdef SUPPORT_SRS
6789     case EITEM_SRS_ENCODE:
6790       /* ${srs_encode {secret} {return_path} {orig_domain}} */
6791       {
6792       uschar * sub[3];
6793       uschar cksum[4];
6794       gstring * g = NULL;
6795       BOOL quoted = FALSE;
6796
6797       switch (read_subs(sub, 3, 3, CUSS &s, skipping, TRUE, name, &resetok))
6798         {
6799         case 1: goto EXPAND_FAILED_CURLY;
6800         case 2:
6801         case 3: goto EXPAND_FAILED;
6802         }
6803
6804       g = string_catn(g, US"SRS0=", 5);
6805
6806       /* ${l_4:${hmac{md5}{SRS_SECRET}{${lc:$return_path}}}}= */
6807       hmac_md5(sub[0], string_copylc(sub[1]), cksum, sizeof(cksum));
6808       g = string_catn(g, cksum, sizeof(cksum));
6809       g = string_catn(g, US"=", 1);
6810
6811       /* ${base32:${eval:$tod_epoch/86400&0x3ff}}= */
6812         {
6813         struct timeval now;
6814         unsigned long i;
6815         gstring * h = NULL;
6816
6817         gettimeofday(&now, NULL);
6818         for (unsigned long i = (now.tv_sec / 86400) & 0x3ff; i; i >>= 5)
6819           h = string_catn(h, &base32_chars[i & 0x1f], 1);
6820         if (h) while (h->ptr > 0)
6821           g = string_catn(g, &h->s[--h->ptr], 1);
6822         }
6823       g = string_catn(g, US"=", 1);
6824
6825       /* ${domain:$return_path}=${local_part:$return_path} */
6826         {
6827         int start, end, domain;
6828         uschar * t = parse_extract_address(sub[1], &expand_string_message,
6829                                           &start, &end, &domain, FALSE);
6830         uschar * s;
6831
6832         if (!t)
6833           goto EXPAND_FAILED;
6834
6835         if (domain > 0) g = string_cat(g, t + domain);
6836         g = string_catn(g, US"=", 1);
6837
6838         s = domain > 0 ? string_copyn(t, domain - 1) : t;
6839         if ((quoted = Ustrchr(s, '"') != NULL))
6840           {
6841           gstring * h = NULL;
6842           DEBUG(D_expand) debug_printf_indent("auto-quoting local part\n");
6843           while (*s)            /* de-quote */
6844             {
6845             while (*s && *s != '"') h = string_catn(h, s++, 1);
6846             if (*s) s++;
6847             while (*s && *s != '"') h = string_catn(h, s++, 1);
6848             if (*s) s++;
6849             }
6850           gstring_release_unused(h);
6851           s = string_from_gstring(h);
6852           }
6853         g = string_cat(g, s);
6854         }
6855
6856       /* Assume that if the original local_part had quotes
6857       it was for good reason */
6858
6859       if (quoted) yield = string_catn(yield, US"\"", 1);
6860       yield = string_catn(yield, g->s, g->ptr);
6861       if (quoted) yield = string_catn(yield, US"\"", 1);
6862
6863       /* @$original_domain */
6864       yield = string_catn(yield, US"@", 1);
6865       yield = string_cat(yield, sub[2]);
6866       continue;
6867       }
6868 #endif /*SUPPORT_SRS*/
6869     }   /* EITEM_* switch */
6870
6871   /* Control reaches here if the name is not recognized as one of the more
6872   complicated expansion items. Check for the "operator" syntax (name terminated
6873   by a colon). Some of the operators have arguments, separated by _ from the
6874   name. */
6875
6876   if (*s == ':')
6877     {
6878     int c;
6879     uschar *arg = NULL;
6880     uschar *sub;
6881 #ifndef DISABLE_TLS
6882     var_entry *vp = NULL;
6883 #endif
6884
6885     /* Owing to an historical mis-design, an underscore may be part of the
6886     operator name, or it may introduce arguments.  We therefore first scan the
6887     table of names that contain underscores. If there is no match, we cut off
6888     the arguments and then scan the main table. */
6889
6890     if ((c = chop_match(name, op_table_underscore,
6891                         nelem(op_table_underscore))) < 0)
6892       {
6893       if ((arg = Ustrchr(name, '_')))
6894         *arg = 0;
6895       if ((c = chop_match(name, op_table_main, nelem(op_table_main))) >= 0)
6896         c += nelem(op_table_underscore);
6897       if (arg) *arg++ = '_';            /* Put back for error messages */
6898       }
6899
6900     /* Deal specially with operators that might take a certificate variable
6901     as we do not want to do the usual expansion. For most, expand the string.*/
6902     switch(c)
6903       {
6904 #ifndef DISABLE_TLS
6905       case EOP_MD5:
6906       case EOP_SHA1:
6907       case EOP_SHA256:
6908       case EOP_BASE64:
6909         if (s[1] == '$')
6910           {
6911           const uschar * s1 = s;
6912           sub = expand_string_internal(s+2, TRUE, &s1, skipping,
6913                   FALSE, &resetok);
6914           if (!sub)       goto EXPAND_FAILED;           /*{*/
6915           if (*s1 != '}')
6916             {
6917             expand_string_message =
6918               string_sprintf("missing '}' closing cert arg of %s", name);
6919             goto EXPAND_FAILED_CURLY;
6920             }
6921           if ((vp = find_var_ent(sub)) && vp->type == vtype_cert)
6922             {
6923             s = s1+1;
6924             break;
6925             }
6926           vp = NULL;
6927           }
6928         /*FALLTHROUGH*/
6929 #endif
6930       default:
6931         sub = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok);
6932         if (!sub) goto EXPAND_FAILED;
6933         s++;
6934         break;
6935       }
6936
6937     /* If we are skipping, we don't need to perform the operation at all.
6938     This matters for operations like "mask", because the data may not be
6939     in the correct format when skipping. For example, the expression may test
6940     for the existence of $sender_host_address before trying to mask it. For
6941     other operations, doing them may not fail, but it is a waste of time. */
6942
6943     if (skipping && c >= 0) continue;
6944
6945     /* Otherwise, switch on the operator type */
6946
6947     switch(c)
6948       {
6949       case EOP_BASE32:
6950         {
6951         uschar *t;
6952         unsigned long int n = Ustrtoul(sub, &t, 10);
6953         gstring * g = NULL;
6954
6955         if (*t != 0)
6956           {
6957           expand_string_message = string_sprintf("argument for base32 "
6958             "operator is \"%s\", which is not a decimal number", sub);
6959           goto EXPAND_FAILED;
6960           }
6961         for ( ; n; n >>= 5)
6962           g = string_catn(g, &base32_chars[n & 0x1f], 1);
6963
6964         if (g) while (g->ptr > 0) yield = string_catn(yield, &g->s[--g->ptr], 1);
6965         continue;
6966         }
6967
6968       case EOP_BASE32D:
6969         {
6970         uschar *tt = sub;
6971         unsigned long int n = 0;
6972         while (*tt)
6973           {
6974           uschar * t = Ustrchr(base32_chars, *tt++);
6975           if (!t)
6976             {
6977             expand_string_message = string_sprintf("argument for base32d "
6978               "operator is \"%s\", which is not a base 32 number", sub);
6979             goto EXPAND_FAILED;
6980             }
6981           n = n * 32 + (t - base32_chars);
6982           }
6983         yield = string_fmt_append(yield, "%ld", n);
6984         continue;
6985         }
6986
6987       case EOP_BASE62:
6988         {
6989         uschar *t;
6990         unsigned long int n = Ustrtoul(sub, &t, 10);
6991         if (*t != 0)
6992           {
6993           expand_string_message = string_sprintf("argument for base62 "
6994             "operator is \"%s\", which is not a decimal number", sub);
6995           goto EXPAND_FAILED;
6996           }
6997         yield = string_cat(yield, string_base62(n));
6998         continue;
6999         }
7000
7001       /* Note that for Darwin and Cygwin, BASE_62 actually has the value 36 */
7002
7003       case EOP_BASE62D:
7004         {
7005         uschar *tt = sub;
7006         unsigned long int n = 0;
7007         while (*tt != 0)
7008           {
7009           uschar *t = Ustrchr(base62_chars, *tt++);
7010           if (!t)
7011             {
7012             expand_string_message = string_sprintf("argument for base62d "
7013               "operator is \"%s\", which is not a base %d number", sub,
7014               BASE_62);
7015             goto EXPAND_FAILED;
7016             }
7017           n = n * BASE_62 + (t - base62_chars);
7018           }
7019         yield = string_fmt_append(yield, "%ld", n);
7020         continue;
7021         }
7022
7023       case EOP_BLESS:
7024         /* This is purely for the convenience of the test harness.  Do not enable
7025         it otherwise as it defeats the taint-checking security. */
7026
7027         if (f.running_in_test_harness)
7028           yield = string_cat(yield, is_tainted(sub)
7029                                     ? string_copy_taint(sub, FALSE) : sub);
7030         else
7031           {
7032           DEBUG(D_expand) debug_printf_indent("bless operator not supported\n");
7033           yield = string_cat(yield, sub);
7034           }
7035         continue;
7036
7037       case EOP_EXPAND:
7038         {
7039         uschar *expanded = expand_string_internal(sub, FALSE, NULL, skipping, TRUE, &resetok);
7040         if (!expanded)
7041           {
7042           expand_string_message =
7043             string_sprintf("internal expansion of \"%s\" failed: %s", sub,
7044               expand_string_message);
7045           goto EXPAND_FAILED;
7046           }
7047         yield = string_cat(yield, expanded);
7048         continue;
7049         }
7050
7051       case EOP_LC:
7052         {
7053         int count = 0;
7054         uschar *t = sub - 1;
7055         while (*(++t) != 0) { *t = tolower(*t); count++; }
7056         yield = string_catn(yield, sub, count);
7057         continue;
7058         }
7059
7060       case EOP_UC:
7061         {
7062         int count = 0;
7063         uschar *t = sub - 1;
7064         while (*(++t) != 0) { *t = toupper(*t); count++; }
7065         yield = string_catn(yield, sub, count);
7066         continue;
7067         }
7068
7069       case EOP_MD5:
7070 #ifndef DISABLE_TLS
7071         if (vp && *(void **)vp->value)
7072           {
7073           uschar * cp = tls_cert_fprt_md5(*(void **)vp->value);
7074           yield = string_cat(yield, cp);
7075           }
7076         else
7077 #endif
7078           {
7079           md5 base;
7080           uschar digest[16];
7081           md5_start(&base);
7082           md5_end(&base, sub, Ustrlen(sub), digest);
7083           for (int j = 0; j < 16; j++)
7084             yield = string_fmt_append(yield, "%02x", digest[j]);
7085           }
7086         continue;
7087
7088       case EOP_SHA1:
7089 #ifndef DISABLE_TLS
7090         if (vp && *(void **)vp->value)
7091           {
7092           uschar * cp = tls_cert_fprt_sha1(*(void **)vp->value);
7093           yield = string_cat(yield, cp);
7094           }
7095         else
7096 #endif
7097           {
7098           hctx h;
7099           uschar digest[20];
7100           sha1_start(&h);
7101           sha1_end(&h, sub, Ustrlen(sub), digest);
7102           for (int j = 0; j < 20; j++)
7103             yield = string_fmt_append(yield, "%02X", digest[j]);
7104           }
7105         continue;
7106
7107       case EOP_SHA2:
7108       case EOP_SHA256:
7109 #ifdef EXIM_HAVE_SHA2
7110         if (vp && *(void **)vp->value)
7111           if (c == EOP_SHA256)
7112             yield = string_cat(yield, tls_cert_fprt_sha256(*(void **)vp->value));
7113           else
7114             expand_string_message = US"sha2_N not supported with certificates";
7115         else
7116           {
7117           hctx h;
7118           blob b;
7119           hashmethod m = !arg ? HASH_SHA2_256
7120             : Ustrcmp(arg, "256") == 0 ? HASH_SHA2_256
7121             : Ustrcmp(arg, "384") == 0 ? HASH_SHA2_384
7122             : Ustrcmp(arg, "512") == 0 ? HASH_SHA2_512
7123             : HASH_BADTYPE;
7124
7125           if (m == HASH_BADTYPE || !exim_sha_init(&h, m))
7126             {
7127             expand_string_message = US"unrecognised sha2 variant";
7128             goto EXPAND_FAILED;
7129             }
7130
7131           exim_sha_update(&h, sub, Ustrlen(sub));
7132           exim_sha_finish(&h, &b);
7133           while (b.len-- > 0)
7134             yield = string_fmt_append(yield, "%02X", *b.data++);
7135           }
7136 #else
7137           expand_string_message = US"sha256 only supported with TLS";
7138 #endif
7139         continue;
7140
7141       case EOP_SHA3:
7142 #ifdef EXIM_HAVE_SHA3
7143         {
7144         hctx h;
7145         blob b;
7146         hashmethod m = !arg ? HASH_SHA3_256
7147           : Ustrcmp(arg, "224") == 0 ? HASH_SHA3_224
7148           : Ustrcmp(arg, "256") == 0 ? HASH_SHA3_256
7149           : Ustrcmp(arg, "384") == 0 ? HASH_SHA3_384
7150           : Ustrcmp(arg, "512") == 0 ? HASH_SHA3_512
7151           : HASH_BADTYPE;
7152
7153         if (m == HASH_BADTYPE || !exim_sha_init(&h, m))
7154           {
7155           expand_string_message = US"unrecognised sha3 variant";
7156           goto EXPAND_FAILED;
7157           }
7158
7159         exim_sha_update(&h, sub, Ustrlen(sub));
7160         exim_sha_finish(&h, &b);
7161         while (b.len-- > 0)
7162           yield = string_fmt_append(yield, "%02X", *b.data++);
7163         }
7164         continue;
7165 #else
7166         expand_string_message = US"sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 +";
7167         goto EXPAND_FAILED;
7168 #endif
7169
7170       /* Convert hex encoding to base64 encoding */
7171
7172       case EOP_HEX2B64:
7173         {
7174         int c = 0;
7175         int b = -1;
7176         uschar *in = sub;
7177         uschar *out = sub;
7178         uschar *enc;
7179
7180         for (enc = sub; *enc; enc++)
7181           {
7182           if (!isxdigit(*enc))
7183             {
7184             expand_string_message = string_sprintf("\"%s\" is not a hex "
7185               "string", sub);
7186             goto EXPAND_FAILED;
7187             }
7188           c++;
7189           }
7190
7191         if ((c & 1) != 0)
7192           {
7193           expand_string_message = string_sprintf("\"%s\" contains an odd "
7194             "number of characters", sub);
7195           goto EXPAND_FAILED;
7196           }
7197
7198         while ((c = *in++) != 0)
7199           {
7200           if (isdigit(c)) c -= '0';
7201           else c = toupper(c) - 'A' + 10;
7202           if (b == -1)
7203             b = c << 4;
7204           else
7205             {
7206             *out++ = b | c;
7207             b = -1;
7208             }
7209           }
7210
7211         enc = b64encode(CUS sub, out - sub);
7212         yield = string_cat(yield, enc);
7213         continue;
7214         }
7215
7216       /* Convert octets outside 0x21..0x7E to \xXX form */
7217
7218       case EOP_HEXQUOTE:
7219         {
7220         uschar *t = sub - 1;
7221         while (*(++t) != 0)
7222           {
7223           if (*t < 0x21 || 0x7E < *t)
7224             yield = string_fmt_append(yield, "\\x%02x", *t);
7225           else
7226             yield = string_catn(yield, t, 1);
7227           }
7228         continue;
7229         }
7230
7231       /* count the number of list elements */
7232
7233       case EOP_LISTCOUNT:
7234         {
7235         int cnt = 0;
7236         int sep = 0;
7237
7238         while (string_nextinlist(CUSS &sub, &sep, NULL, 0)) cnt++;
7239         yield = string_fmt_append(yield, "%d", cnt);
7240         continue;
7241         }
7242
7243       /* expand a named list given the name */
7244       /* handles nested named lists; requotes as colon-sep list */
7245
7246       case EOP_LISTNAMED:
7247         {
7248         tree_node *t = NULL;
7249         const uschar * list;
7250         int sep = 0;
7251         uschar * item;
7252         uschar * suffix = US"";
7253         BOOL needsep = FALSE;
7254         uschar buffer[256];
7255
7256         if (*sub == '+') sub++;
7257         if (!arg)               /* no-argument version */
7258           {
7259           if (!(t = tree_search(addresslist_anchor, sub)) &&
7260               !(t = tree_search(domainlist_anchor,  sub)) &&
7261               !(t = tree_search(hostlist_anchor,    sub)))
7262             t = tree_search(localpartlist_anchor, sub);
7263           }
7264         else switch(*arg)       /* specific list-type version */
7265           {
7266           case 'a': t = tree_search(addresslist_anchor,   sub); suffix = US"_a"; break;
7267           case 'd': t = tree_search(domainlist_anchor,    sub); suffix = US"_d"; break;
7268           case 'h': t = tree_search(hostlist_anchor,      sub); suffix = US"_h"; break;
7269           case 'l': t = tree_search(localpartlist_anchor, sub); suffix = US"_l"; break;
7270           default:
7271             expand_string_message = US"bad suffix on \"list\" operator";
7272             goto EXPAND_FAILED;
7273           }
7274
7275         if(!t)
7276           {
7277           expand_string_message = string_sprintf("\"%s\" is not a %snamed list",
7278             sub, !arg?""
7279               : *arg=='a'?"address "
7280               : *arg=='d'?"domain "
7281               : *arg=='h'?"host "
7282               : *arg=='l'?"localpart "
7283               : 0);
7284           goto EXPAND_FAILED;
7285           }
7286
7287         list = ((namedlist_block *)(t->data.ptr))->string;
7288
7289         while ((item = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
7290           {
7291           uschar * buf = US" : ";
7292           if (needsep)
7293             yield = string_catn(yield, buf, 3);
7294           else
7295             needsep = TRUE;
7296
7297           if (*item == '+')     /* list item is itself a named list */
7298             {
7299             uschar * sub = string_sprintf("${listnamed%s:%s}", suffix, item);
7300             item = expand_string_internal(sub, FALSE, NULL, FALSE, TRUE, &resetok);
7301             }
7302           else if (sep != ':')  /* item from non-colon-sep list, re-quote for colon list-separator */
7303             {
7304             char * cp;
7305             char tok[3];
7306             tok[0] = sep; tok[1] = ':'; tok[2] = 0;
7307             while ((cp= strpbrk(CCS item, tok)))
7308               {
7309               yield = string_catn(yield, item, cp - CS item);
7310               if (*cp++ == ':') /* colon in a non-colon-sep list item, needs doubling */
7311                 {
7312                 yield = string_catn(yield, US"::", 2);
7313                 item = US cp;
7314                 }
7315               else              /* sep in item; should already be doubled; emit once */
7316                 {
7317                 yield = string_catn(yield, US tok, 1);
7318                 if (*cp == sep) cp++;
7319                 item = US cp;
7320                 }
7321               }
7322             }
7323           yield = string_cat(yield, item);
7324           }
7325         continue;
7326         }
7327
7328       /* quote a list-item for the given list-separator */
7329
7330       /* mask applies a mask to an IP address; for example the result of
7331       ${mask:131.111.10.206/28} is 131.111.10.192/28. */
7332
7333       case EOP_MASK:
7334         {
7335         int count;
7336         uschar *endptr;
7337         int binary[4];
7338         int mask, maskoffset;
7339         int type = string_is_ip_address(sub, &maskoffset);
7340         uschar buffer[64];
7341
7342         if (type == 0)
7343           {
7344           expand_string_message = string_sprintf("\"%s\" is not an IP address",
7345            sub);
7346           goto EXPAND_FAILED;
7347           }
7348
7349         if (maskoffset == 0)
7350           {
7351           expand_string_message = string_sprintf("missing mask value in \"%s\"",
7352             sub);
7353           goto EXPAND_FAILED;
7354           }
7355
7356         mask = Ustrtol(sub + maskoffset + 1, &endptr, 10);
7357
7358         if (*endptr != 0 || mask < 0 || mask > ((type == 4)? 32 : 128))
7359           {
7360           expand_string_message = string_sprintf("mask value too big in \"%s\"",
7361             sub);
7362           goto EXPAND_FAILED;
7363           }
7364
7365         /* Convert the address to binary integer(s) and apply the mask */
7366
7367         sub[maskoffset] = 0;
7368         count = host_aton(sub, binary);
7369         host_mask(count, binary, mask);
7370
7371         /* Convert to masked textual format and add to output. */
7372
7373         yield = string_catn(yield, buffer,
7374           host_nmtoa(count, binary, mask, buffer, '.'));
7375         continue;
7376         }
7377
7378       case EOP_IPV6NORM:
7379       case EOP_IPV6DENORM:
7380         {
7381         int type = string_is_ip_address(sub, NULL);
7382         int binary[4];
7383         uschar buffer[44];
7384
7385         switch (type)
7386           {
7387           case 6:
7388             (void) host_aton(sub, binary);
7389             break;
7390
7391           case 4:       /* convert to IPv4-mapped IPv6 */
7392             binary[0] = binary[1] = 0;
7393             binary[2] = 0x0000ffff;
7394             (void) host_aton(sub, binary+3);
7395             break;
7396
7397           case 0:
7398             expand_string_message =
7399               string_sprintf("\"%s\" is not an IP address", sub);
7400             goto EXPAND_FAILED;
7401           }
7402
7403         yield = string_catn(yield, buffer, c == EOP_IPV6NORM
7404                     ? ipv6_nmtoa(binary, buffer)
7405                     : host_nmtoa(4, binary, -1, buffer, ':')
7406                   );
7407         continue;
7408         }
7409
7410       case EOP_ADDRESS:
7411       case EOP_LOCAL_PART:
7412       case EOP_DOMAIN:
7413         {
7414         uschar * error;
7415         int start, end, domain;
7416         uschar * t = parse_extract_address(sub, &error, &start, &end, &domain,
7417           FALSE);
7418         if (t)
7419           if (c != EOP_DOMAIN)
7420             yield = c == EOP_LOCAL_PART && domain > 0
7421               ? string_catn(yield, t, domain - 1)
7422               : string_cat(yield, t);
7423           else if (domain > 0)
7424             yield = string_cat(yield, t + domain);
7425         continue;
7426         }
7427
7428       case EOP_ADDRESSES:
7429         {
7430         uschar outsep[2] = { ':', '\0' };
7431         uschar *address, *error;
7432         int save_ptr = gstring_length(yield);
7433         int start, end, domain;  /* Not really used */
7434
7435         if (Uskip_whitespace(&sub) == '>')
7436           if (*outsep = *++sub) ++sub;
7437           else
7438             {
7439             expand_string_message = string_sprintf("output separator "
7440               "missing in expanding ${addresses:%s}", --sub);
7441             goto EXPAND_FAILED;
7442             }
7443         f.parse_allow_group = TRUE;
7444
7445         for (;;)
7446           {
7447           uschar * p = parse_find_address_end(sub, FALSE);
7448           uschar saveend = *p;
7449           *p = '\0';
7450           address = parse_extract_address(sub, &error, &start, &end, &domain,
7451             FALSE);
7452           *p = saveend;
7453
7454           /* Add the address to the output list that we are building. This is
7455           done in chunks by searching for the separator character. At the
7456           start, unless we are dealing with the first address of the output
7457           list, add in a space if the new address begins with the separator
7458           character, or is an empty string. */
7459
7460           if (address)
7461             {
7462             if (yield && yield->ptr != save_ptr && address[0] == *outsep)
7463               yield = string_catn(yield, US" ", 1);
7464
7465             for (;;)
7466               {
7467               size_t seglen = Ustrcspn(address, outsep);
7468               yield = string_catn(yield, address, seglen + 1);
7469
7470               /* If we got to the end of the string we output one character
7471               too many. */
7472
7473               if (address[seglen] == '\0') { yield->ptr--; break; }
7474               yield = string_catn(yield, outsep, 1);
7475               address += seglen + 1;
7476               }
7477
7478             /* Output a separator after the string: we will remove the
7479             redundant final one at the end. */
7480
7481             yield = string_catn(yield, outsep, 1);
7482             }
7483
7484           if (saveend == '\0') break;
7485           sub = p + 1;
7486           }
7487
7488         /* If we have generated anything, remove the redundant final
7489         separator. */
7490
7491         if (yield && yield->ptr != save_ptr) yield->ptr--;
7492         f.parse_allow_group = FALSE;
7493         continue;
7494         }
7495
7496
7497       /* quote puts a string in quotes if it is empty or contains anything
7498       other than alphamerics, underscore, dot, or hyphen.
7499
7500       quote_local_part puts a string in quotes if RFC 2821/2822 requires it to
7501       be quoted in order to be a valid local part.
7502
7503       In both cases, newlines and carriage returns are converted into \n and \r
7504       respectively */
7505
7506       case EOP_QUOTE:
7507       case EOP_QUOTE_LOCAL_PART:
7508       if (!arg)
7509         {
7510         BOOL needs_quote = (!*sub);      /* TRUE for empty string */
7511         uschar *t = sub - 1;
7512
7513         if (c == EOP_QUOTE)
7514           while (!needs_quote && *++t)
7515             needs_quote = !isalnum(*t) && !strchr("_-.", *t);
7516
7517         else  /* EOP_QUOTE_LOCAL_PART */
7518           while (!needs_quote && *++t)
7519             needs_quote = !isalnum(*t)
7520               && strchr("!#$%&'*+-/=?^_`{|}~", *t) == NULL
7521               && (*t != '.' || t == sub || !t[1]);
7522
7523         if (needs_quote)
7524           {
7525           yield = string_catn(yield, US"\"", 1);
7526           t = sub - 1;
7527           while (*++t)
7528             if (*t == '\n')
7529               yield = string_catn(yield, US"\\n", 2);
7530             else if (*t == '\r')
7531               yield = string_catn(yield, US"\\r", 2);
7532             else
7533               {
7534               if (*t == '\\' || *t == '"')
7535                 yield = string_catn(yield, US"\\", 1);
7536               yield = string_catn(yield, t, 1);
7537               }
7538           yield = string_catn(yield, US"\"", 1);
7539           }
7540         else
7541           yield = string_cat(yield, sub);
7542         continue;
7543         }
7544
7545       /* quote_lookuptype does lookup-specific quoting */
7546
7547       else
7548         {
7549         int n;
7550         uschar *opt = Ustrchr(arg, '_');
7551
7552         if (opt) *opt++ = 0;
7553
7554         if ((n = search_findtype(arg, Ustrlen(arg))) < 0)
7555           {
7556           expand_string_message = search_error_message;
7557           goto EXPAND_FAILED;
7558           }
7559
7560         if (lookup_list[n]->quote)
7561           sub = (lookup_list[n]->quote)(sub, opt);
7562         else if (opt)
7563           sub = NULL;
7564
7565         if (!sub)
7566           {
7567           expand_string_message = string_sprintf(
7568             "\"%s\" unrecognized after \"${quote_%s\"",
7569             opt, arg);
7570           goto EXPAND_FAILED;
7571           }
7572
7573         yield = string_cat(yield, sub);
7574         continue;
7575         }
7576
7577       /* rx quote sticks in \ before any non-alphameric character so that
7578       the insertion works in a regular expression. */
7579
7580       case EOP_RXQUOTE:
7581         {
7582         uschar *t = sub - 1;
7583         while (*(++t) != 0)
7584           {
7585           if (!isalnum(*t))
7586             yield = string_catn(yield, US"\\", 1);
7587           yield = string_catn(yield, t, 1);
7588           }
7589         continue;
7590         }
7591
7592       /* RFC 2047 encodes, assuming headers_charset (default ISO 8859-1) as
7593       prescribed by the RFC, if there are characters that need to be encoded */
7594
7595       case EOP_RFC2047:
7596         yield = string_cat(yield,
7597                             parse_quote_2047(sub, Ustrlen(sub), headers_charset,
7598                               FALSE));
7599         continue;
7600
7601       /* RFC 2047 decode */
7602
7603       case EOP_RFC2047D:
7604         {
7605         int len;
7606         uschar *error;
7607         uschar *decoded = rfc2047_decode(sub, check_rfc2047_length,
7608           headers_charset, '?', &len, &error);
7609         if (error)
7610           {
7611           expand_string_message = error;
7612           goto EXPAND_FAILED;
7613           }
7614         yield = string_catn(yield, decoded, len);
7615         continue;
7616         }
7617
7618       /* from_utf8 converts UTF-8 to 8859-1, turning non-existent chars into
7619       underscores */
7620
7621       case EOP_FROM_UTF8:
7622         {
7623         uschar * buff = store_get(4, is_tainted(sub));
7624         while (*sub)
7625           {
7626           int c;
7627           GETUTF8INC(c, sub);
7628           if (c > 255) c = '_';
7629           buff[0] = c;
7630           yield = string_catn(yield, buff, 1);
7631           }
7632         continue;
7633         }
7634
7635       /* replace illegal UTF-8 sequences by replacement character  */
7636
7637       #define UTF8_REPLACEMENT_CHAR US"?"
7638
7639       case EOP_UTF8CLEAN:
7640         {
7641         int seq_len = 0, index = 0;
7642         int bytes_left = 0;
7643         long codepoint = -1;
7644         int complete;
7645         uschar seq_buff[4];                     /* accumulate utf-8 here */
7646
7647         /* Manually track tainting, as we deal in individual chars below */
7648
7649         if (is_tainted(sub))
7650           if (yield->s && yield->ptr)
7651             gstring_rebuffer(yield);
7652           else
7653             yield->s = store_get(yield->size = Ustrlen(sub), TRUE);
7654
7655         /* Check the UTF-8, byte-by-byte */
7656
7657         while (*sub)
7658           {
7659           complete = 0;
7660           uschar c = *sub++;
7661
7662           if (bytes_left)
7663             {
7664             if ((c & 0xc0) != 0x80)
7665                     /* wrong continuation byte; invalidate all bytes */
7666               complete = 1; /* error */
7667             else
7668               {
7669               codepoint = (codepoint << 6) | (c & 0x3f);
7670               seq_buff[index++] = c;
7671               if (--bytes_left == 0)            /* codepoint complete */
7672                 if(codepoint > 0x10FFFF)        /* is it too large? */
7673                   complete = -1;        /* error (RFC3629 limit) */
7674                 else
7675                   {             /* finished; output utf-8 sequence */
7676                   yield = string_catn(yield, seq_buff, seq_len);
7677                   index = 0;
7678                   }
7679               }
7680             }
7681           else  /* no bytes left: new sequence */
7682             {
7683             if(!(c & 0x80))     /* 1-byte sequence, US-ASCII, keep it */
7684               {
7685               yield = string_catn(yield, &c, 1);
7686               continue;
7687               }
7688             if((c & 0xe0) == 0xc0)              /* 2-byte sequence */
7689               {
7690               if(c == 0xc0 || c == 0xc1)        /* 0xc0 and 0xc1 are illegal */
7691                 complete = -1;
7692               else
7693                 {
7694                   bytes_left = 1;
7695                   codepoint = c & 0x1f;
7696                 }
7697               }
7698             else if((c & 0xf0) == 0xe0)         /* 3-byte sequence */
7699               {
7700               bytes_left = 2;
7701               codepoint = c & 0x0f;
7702               }
7703             else if((c & 0xf8) == 0xf0)         /* 4-byte sequence */
7704               {
7705               bytes_left = 3;
7706               codepoint = c & 0x07;
7707               }
7708             else        /* invalid or too long (RFC3629 allows only 4 bytes) */
7709               complete = -1;
7710
7711             seq_buff[index++] = c;
7712             seq_len = bytes_left + 1;
7713             }           /* if(bytes_left) */
7714
7715           if (complete != 0)
7716             {
7717             bytes_left = index = 0;
7718             yield = string_catn(yield, UTF8_REPLACEMENT_CHAR, 1);
7719             }
7720           if ((complete == 1) && ((c & 0x80) == 0))
7721                         /* ASCII character follows incomplete sequence */
7722               yield = string_catn(yield, &c, 1);
7723           }
7724         /* If given a sequence truncated mid-character, we also want to report ?
7725         * Eg, ${length_1:フィル} is one byte, not one character, so we expect
7726         * ${utf8clean:${length_1:フィル}} to yield '?' */
7727         if (bytes_left != 0)
7728           yield = string_catn(yield, UTF8_REPLACEMENT_CHAR, 1);
7729
7730         continue;
7731         }
7732
7733 #ifdef SUPPORT_I18N
7734       case EOP_UTF8_DOMAIN_TO_ALABEL:
7735         {
7736         uschar * error = NULL;
7737         uschar * s = string_domain_utf8_to_alabel(sub, &error);
7738         if (error)
7739           {
7740           expand_string_message = string_sprintf(
7741             "error converting utf8 (%s) to alabel: %s",
7742             string_printing(sub), error);
7743           goto EXPAND_FAILED;
7744           }
7745         yield = string_cat(yield, s);
7746         continue;
7747         }
7748
7749       case EOP_UTF8_DOMAIN_FROM_ALABEL:
7750         {
7751         uschar * error = NULL;
7752         uschar * s = string_domain_alabel_to_utf8(sub, &error);
7753         if (error)
7754           {
7755           expand_string_message = string_sprintf(
7756             "error converting alabel (%s) to utf8: %s",
7757             string_printing(sub), error);
7758           goto EXPAND_FAILED;
7759           }
7760         yield = string_cat(yield, s);
7761         continue;
7762         }
7763
7764       case EOP_UTF8_LOCALPART_TO_ALABEL:
7765         {
7766         uschar * error = NULL;
7767         uschar * s = string_localpart_utf8_to_alabel(sub, &error);
7768         if (error)
7769           {
7770           expand_string_message = string_sprintf(
7771             "error converting utf8 (%s) to alabel: %s",
7772             string_printing(sub), error);
7773           goto EXPAND_FAILED;
7774           }
7775         yield = string_cat(yield, s);
7776         DEBUG(D_expand) debug_printf_indent("yield: '%s'\n", yield->s);
7777         continue;
7778         }
7779
7780       case EOP_UTF8_LOCALPART_FROM_ALABEL:
7781         {
7782         uschar * error = NULL;
7783         uschar * s = string_localpart_alabel_to_utf8(sub, &error);
7784         if (error)
7785           {
7786           expand_string_message = string_sprintf(
7787             "error converting alabel (%s) to utf8: %s",
7788             string_printing(sub), error);
7789           goto EXPAND_FAILED;
7790           }
7791         yield = string_cat(yield, s);
7792         continue;
7793         }
7794 #endif  /* EXPERIMENTAL_INTERNATIONAL */
7795
7796       /* escape turns all non-printing characters into escape sequences. */
7797
7798       case EOP_ESCAPE:
7799         {
7800         const uschar * t = string_printing(sub);
7801         yield = string_cat(yield, t);
7802         continue;
7803         }
7804
7805       case EOP_ESCAPE8BIT:
7806         {
7807         uschar c;
7808
7809         for (const uschar * s = sub; (c = *s); s++)
7810           yield = c < 127 && c != '\\'
7811             ? string_catn(yield, s, 1)
7812             : string_fmt_append(yield, "\\%03o", c);
7813         continue;
7814         }
7815
7816       /* Handle numeric expression evaluation */
7817
7818       case EOP_EVAL:
7819       case EOP_EVAL10:
7820         {
7821         uschar *save_sub = sub;
7822         uschar *error = NULL;
7823         int_eximarith_t n = eval_expr(&sub, (c == EOP_EVAL10), &error, FALSE);
7824         if (error)
7825           {
7826           expand_string_message = string_sprintf("error in expression "
7827             "evaluation: %s (after processing \"%.*s\")", error,
7828             (int)(sub-save_sub), save_sub);
7829           goto EXPAND_FAILED;
7830           }
7831         yield = string_fmt_append(yield, PR_EXIM_ARITH, n);
7832         continue;
7833         }
7834
7835       /* Handle time period formatting */
7836
7837       case EOP_TIME_EVAL:
7838         {
7839         int n = readconf_readtime(sub, 0, FALSE);
7840         if (n < 0)
7841           {
7842           expand_string_message = string_sprintf("string \"%s\" is not an "
7843             "Exim time interval in \"%s\" operator", sub, name);
7844           goto EXPAND_FAILED;
7845           }
7846         yield = string_fmt_append(yield, "%d", n);
7847         continue;
7848         }
7849
7850       case EOP_TIME_INTERVAL:
7851         {
7852         int n;
7853         uschar *t = read_number(&n, sub);
7854         if (*t != 0) /* Not A Number*/
7855           {
7856           expand_string_message = string_sprintf("string \"%s\" is not a "
7857             "positive number in \"%s\" operator", sub, name);
7858           goto EXPAND_FAILED;
7859           }
7860         t = readconf_printtime(n);
7861         yield = string_cat(yield, t);
7862         continue;
7863         }
7864
7865       /* Convert string to base64 encoding */
7866
7867       case EOP_STR2B64:
7868       case EOP_BASE64:
7869         {
7870 #ifndef DISABLE_TLS
7871         uschar * s = vp && *(void **)vp->value
7872           ? tls_cert_der_b64(*(void **)vp->value)
7873           : b64encode(CUS sub, Ustrlen(sub));
7874 #else
7875         uschar * s = b64encode(CUS sub, Ustrlen(sub));
7876 #endif
7877         yield = string_cat(yield, s);
7878         continue;
7879         }
7880
7881       case EOP_BASE64D:
7882         {
7883         uschar * s;
7884         int len = b64decode(sub, &s);
7885         if (len < 0)
7886           {
7887           expand_string_message = string_sprintf("string \"%s\" is not "
7888             "well-formed for \"%s\" operator", sub, name);
7889           goto EXPAND_FAILED;
7890           }
7891         yield = string_cat(yield, s);
7892         continue;
7893         }
7894
7895       /* strlen returns the length of the string */
7896
7897       case EOP_STRLEN:
7898         yield = string_fmt_append(yield, "%d", Ustrlen(sub));
7899         continue;
7900
7901       /* length_n or l_n takes just the first n characters or the whole string,
7902       whichever is the shorter;
7903
7904       substr_m_n, and s_m_n take n characters from offset m; negative m take
7905       from the end; l_n is synonymous with s_0_n. If n is omitted in substr it
7906       takes the rest, either to the right or to the left.
7907
7908       hash_n or h_n makes a hash of length n from the string, yielding n
7909       characters from the set a-z; hash_n_m makes a hash of length n, but
7910       uses m characters from the set a-zA-Z0-9.
7911
7912       nhash_n returns a single number between 0 and n-1 (in text form), while
7913       nhash_n_m returns a div/mod hash as two numbers "a/b". The first lies
7914       between 0 and n-1 and the second between 0 and m-1. */
7915
7916       case EOP_LENGTH:
7917       case EOP_L:
7918       case EOP_SUBSTR:
7919       case EOP_S:
7920       case EOP_HASH:
7921       case EOP_H:
7922       case EOP_NHASH:
7923       case EOP_NH:
7924         {
7925         int sign = 1;
7926         int value1 = 0;
7927         int value2 = -1;
7928         int *pn;
7929         int len;
7930         uschar *ret;
7931
7932         if (!arg)
7933           {
7934           expand_string_message = string_sprintf("missing values after %s",
7935             name);
7936           goto EXPAND_FAILED;
7937           }
7938
7939         /* "length" has only one argument, effectively being synonymous with
7940         substr_0_n. */
7941
7942         if (c == EOP_LENGTH || c == EOP_L)
7943           {
7944           pn = &value2;
7945           value2 = 0;
7946           }
7947
7948         /* The others have one or two arguments; for "substr" the first may be
7949         negative. The second being negative means "not supplied". */
7950
7951         else
7952           {
7953           pn = &value1;
7954           if (name[0] == 's' && *arg == '-') { sign = -1; arg++; }
7955           }
7956
7957         /* Read up to two numbers, separated by underscores */
7958
7959         ret = arg;
7960         while (*arg != 0)
7961           {
7962           if (arg != ret && *arg == '_' && pn == &value1)
7963             {
7964             pn = &value2;
7965             value2 = 0;
7966             if (arg[1] != 0) arg++;
7967             }
7968           else if (!isdigit(*arg))
7969             {
7970             expand_string_message =
7971               string_sprintf("non-digit after underscore in \"%s\"", name);
7972             goto EXPAND_FAILED;
7973             }
7974           else *pn = (*pn)*10 + *arg++ - '0';
7975           }
7976         value1 *= sign;
7977
7978         /* Perform the required operation */
7979
7980         ret = c == EOP_HASH || c == EOP_H
7981           ? compute_hash(sub, value1, value2, &len)
7982           : c == EOP_NHASH || c == EOP_NH
7983           ? compute_nhash(sub, value1, value2, &len)
7984           : extract_substr(sub, value1, value2, &len);
7985         if (!ret) goto EXPAND_FAILED;
7986
7987         yield = string_catn(yield, ret, len);
7988         continue;
7989         }
7990
7991       /* Stat a path */
7992
7993       case EOP_STAT:
7994         {
7995         uschar smode[12];
7996         uschar **modetable[3];
7997         mode_t mode;
7998         struct stat st;
7999
8000         if (expand_forbid & RDO_EXISTS)
8001           {
8002           expand_string_message = US"Use of the stat() expansion is not permitted";
8003           goto EXPAND_FAILED;
8004           }
8005
8006         if (stat(CS sub, &st) < 0)
8007           {
8008           expand_string_message = string_sprintf("stat(%s) failed: %s",
8009             sub, strerror(errno));
8010           goto EXPAND_FAILED;
8011           }
8012         mode = st.st_mode;
8013         switch (mode & S_IFMT)
8014           {
8015           case S_IFIFO: smode[0] = 'p'; break;
8016           case S_IFCHR: smode[0] = 'c'; break;
8017           case S_IFDIR: smode[0] = 'd'; break;
8018           case S_IFBLK: smode[0] = 'b'; break;
8019           case S_IFREG: smode[0] = '-'; break;
8020           default: smode[0] = '?'; break;
8021           }
8022
8023         modetable[0] = ((mode & 01000) == 0)? mtable_normal : mtable_sticky;
8024         modetable[1] = ((mode & 02000) == 0)? mtable_normal : mtable_setid;
8025         modetable[2] = ((mode & 04000) == 0)? mtable_normal : mtable_setid;
8026
8027         for (int i = 0; i < 3; i++)
8028           {
8029           memcpy(CS(smode + 7 - i*3), CS(modetable[i][mode & 7]), 3);
8030           mode >>= 3;
8031           }
8032
8033         smode[10] = 0;
8034         yield = string_fmt_append(yield,
8035           "mode=%04lo smode=%s inode=%ld device=%ld links=%ld "
8036           "uid=%ld gid=%ld size=" OFF_T_FMT " atime=%ld mtime=%ld ctime=%ld",
8037           (long)(st.st_mode & 077777), smode, (long)st.st_ino,
8038           (long)st.st_dev, (long)st.st_nlink, (long)st.st_uid,
8039           (long)st.st_gid, st.st_size, (long)st.st_atime,
8040           (long)st.st_mtime, (long)st.st_ctime);
8041         continue;
8042         }
8043
8044       /* vaguely random number less than N */
8045
8046       case EOP_RANDINT:
8047         {
8048         int_eximarith_t max = expanded_string_integer(sub, TRUE);
8049
8050         if (expand_string_message)
8051           goto EXPAND_FAILED;
8052         yield = string_fmt_append(yield, "%d", vaguely_random_number((int)max));
8053         continue;
8054         }
8055
8056       /* Reverse IP, including IPv6 to dotted-nibble */
8057
8058       case EOP_REVERSE_IP:
8059         {
8060         int family, maskptr;
8061         uschar reversed[128];
8062
8063         family = string_is_ip_address(sub, &maskptr);
8064         if (family == 0)
8065           {
8066           expand_string_message = string_sprintf(
8067               "reverse_ip() not given an IP address [%s]", sub);
8068           goto EXPAND_FAILED;
8069           }
8070         invert_address(reversed, sub);
8071         yield = string_cat(yield, reversed);
8072         continue;
8073         }
8074
8075       /* Unknown operator */
8076
8077       default:
8078         expand_string_message =
8079           string_sprintf("unknown expansion operator \"%s\"", name);
8080         goto EXPAND_FAILED;
8081       }
8082     }
8083
8084   /* Handle a plain name. If this is the first thing in the expansion, release
8085   the pre-allocated buffer. If the result data is known to be in a new buffer,
8086   newsize will be set to the size of that buffer, and we can just point at that
8087   store instead of copying. Many expansion strings contain just one reference,
8088   so this is a useful optimization, especially for humungous headers
8089   ($message_headers). */
8090                                                 /*{*/
8091   if (*s++ == '}')
8092     {
8093     int len;
8094     int newsize = 0;
8095     gstring * g = NULL;
8096
8097     if (!yield)
8098       g = store_get(sizeof(gstring), FALSE);
8099     else if (yield->ptr == 0)
8100       {
8101       if (resetok) reset_point = store_reset(reset_point);
8102       yield = NULL;
8103       reset_point = store_mark();
8104       g = store_get(sizeof(gstring), FALSE);    /* alloc _before_ calling find_variable() */
8105       }
8106     if (!(value = find_variable(name, FALSE, skipping, &newsize)))
8107       {
8108       expand_string_message =
8109         string_sprintf("unknown variable in \"${%s}\"", name);
8110       check_variable_error_message(name);
8111       goto EXPAND_FAILED;
8112       }
8113     len = Ustrlen(value);
8114     if (!yield && newsize)
8115       {
8116       yield = g;
8117       yield->size = newsize;
8118       yield->ptr = len;
8119       yield->s = value;
8120       }
8121     else
8122       yield = string_catn(yield, value, len);
8123     continue;
8124     }
8125
8126   /* Else there's something wrong */
8127
8128   expand_string_message =
8129     string_sprintf("\"${%s\" is not a known operator (or a } is missing "
8130     "in a variable reference)", name);
8131   goto EXPAND_FAILED;
8132   }
8133
8134 /* If we hit the end of the string when ket_ends is set, there is a missing
8135 terminating brace. */
8136
8137 if (ket_ends && *s == 0)
8138   {
8139   expand_string_message = malformed_header
8140     ? US"missing } at end of string - could be header name not terminated by colon"
8141     : US"missing } at end of string";
8142   goto EXPAND_FAILED;
8143   }
8144
8145 /* Expansion succeeded; yield may still be NULL here if nothing was actually
8146 added to the string. If so, set up an empty string. Add a terminating zero. If
8147 left != NULL, return a pointer to the terminator. */
8148
8149 if (!yield)
8150   yield = string_get(1);
8151 (void) string_from_gstring(yield);
8152 if (left) *left = s;
8153
8154 /* Any stacking store that was used above the final string is no longer needed.
8155 In many cases the final string will be the first one that was got and so there
8156 will be optimal store usage. */
8157
8158 if (resetok) gstring_release_unused(yield);
8159 else if (resetok_p) *resetok_p = FALSE;
8160
8161 DEBUG(D_expand)
8162   {
8163   BOOL tainted = is_tainted(yield->s);
8164   DEBUG(D_noutf8)
8165     {
8166     debug_printf_indent("|--expanding: %.*s\n", (int)(s - string), string);
8167     debug_printf_indent("%sresult: %s\n",
8168       skipping ? "|-----" : "\\_____", yield->s);
8169     if (tainted)
8170       debug_printf_indent("%s     \\__(tainted)\n",
8171         skipping ? "|     " : "      ");
8172     if (skipping)
8173       debug_printf_indent("\\___skipping: result is not used\n");
8174     }
8175   else
8176     {
8177     debug_printf_indent(UTF8_VERT_RIGHT UTF8_HORIZ UTF8_HORIZ
8178       "expanding: %.*s\n",
8179       (int)(s - string), string);
8180     debug_printf_indent("%s" UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ
8181       "result: %s\n",
8182       skipping ? UTF8_VERT_RIGHT : UTF8_UP_RIGHT,
8183       yield->s);
8184     if (tainted)
8185       debug_printf_indent("%s(tainted)\n",
8186         skipping
8187         ? UTF8_VERT "             " : "           " UTF8_UP_RIGHT UTF8_HORIZ UTF8_HORIZ);
8188     if (skipping)
8189       debug_printf_indent(UTF8_UP_RIGHT UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ
8190         "skipping: result is not used\n");
8191     }
8192   }
8193 expand_level--;
8194 return yield->s;
8195
8196 /* This is the failure exit: easiest to program with a goto. We still need
8197 to update the pointer to the terminator, for cases of nested calls with "fail".
8198 */
8199
8200 EXPAND_FAILED_CURLY:
8201 if (malformed_header)
8202   expand_string_message =
8203     US"missing or misplaced { or } - could be header name not terminated by colon";
8204
8205 else if (!expand_string_message || !*expand_string_message)
8206   expand_string_message = US"missing or misplaced { or }";
8207
8208 /* At one point, Exim reset the store to yield (if yield was not NULL), but
8209 that is a bad idea, because expand_string_message is in dynamic store. */
8210
8211 EXPAND_FAILED:
8212 if (left) *left = s;
8213 DEBUG(D_expand)
8214   DEBUG(D_noutf8)
8215     {
8216     debug_printf_indent("|failed to expand: %s\n", string);
8217     debug_printf_indent("%serror message: %s\n",
8218       f.expand_string_forcedfail ? "|---" : "\\___", expand_string_message);
8219     if (f.expand_string_forcedfail)
8220       debug_printf_indent("\\failure was forced\n");
8221     }
8222   else
8223     {
8224     debug_printf_indent(UTF8_VERT_RIGHT "failed to expand: %s\n",
8225       string);
8226     debug_printf_indent("%s" UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ
8227       "error message: %s\n",
8228       f.expand_string_forcedfail ? UTF8_VERT_RIGHT : UTF8_UP_RIGHT,
8229       expand_string_message);
8230     if (f.expand_string_forcedfail)
8231       debug_printf_indent(UTF8_UP_RIGHT "failure was forced\n");
8232     }
8233 if (resetok_p && !resetok) *resetok_p = FALSE;
8234 expand_level--;
8235 return NULL;
8236 }
8237
8238
8239 /* This is the external function call. Do a quick check for any expansion
8240 metacharacters, and if there are none, just return the input string.
8241
8242 Argument: the string to be expanded
8243 Returns:  the expanded string, or NULL if expansion failed; if failure was
8244           due to a lookup deferring, search_find_defer will be TRUE
8245 */
8246
8247 const uschar *
8248 expand_cstring(const uschar * string)
8249 {
8250 if (Ustrpbrk(string, "$\\") != NULL)
8251   {
8252   int old_pool = store_pool;
8253   uschar * s;
8254
8255   f.search_find_defer = FALSE;
8256   malformed_header = FALSE;
8257   store_pool = POOL_MAIN;
8258     s = expand_string_internal(string, FALSE, NULL, FALSE, TRUE, NULL);
8259   store_pool = old_pool;
8260   return s;
8261   }
8262 return string;
8263 }
8264
8265
8266 uschar *
8267 expand_string(uschar * string)
8268 {
8269 return US expand_cstring(CUS string);
8270 }
8271
8272
8273
8274
8275
8276 /*************************************************
8277 *              Expand and copy                   *
8278 *************************************************/
8279
8280 /* Now and again we want to expand a string and be sure that the result is in a
8281 new bit of store. This function does that.
8282 Since we know it has been copied, the de-const cast is safe.
8283
8284 Argument: the string to be expanded
8285 Returns:  the expanded string, always in a new bit of store, or NULL
8286 */
8287
8288 uschar *
8289 expand_string_copy(const uschar *string)
8290 {
8291 const uschar *yield = expand_cstring(string);
8292 if (yield == string) yield = string_copy(string);
8293 return US yield;
8294 }
8295
8296
8297
8298 /*************************************************
8299 *        Expand and interpret as an integer      *
8300 *************************************************/
8301
8302 /* Expand a string, and convert the result into an integer.
8303
8304 Arguments:
8305   string  the string to be expanded
8306   isplus  TRUE if a non-negative number is expected
8307
8308 Returns:  the integer value, or
8309           -1 for an expansion error               ) in both cases, message in
8310           -2 for an integer interpretation error  ) expand_string_message
8311           expand_string_message is set NULL for an OK integer
8312 */
8313
8314 int_eximarith_t
8315 expand_string_integer(uschar *string, BOOL isplus)
8316 {
8317 return expanded_string_integer(expand_string(string), isplus);
8318 }
8319
8320
8321 /*************************************************
8322  *         Interpret string as an integer        *
8323  *************************************************/
8324
8325 /* Convert a string (that has already been expanded) into an integer.
8326
8327 This function is used inside the expansion code.
8328
8329 Arguments:
8330   s       the string to be expanded
8331   isplus  TRUE if a non-negative number is expected
8332
8333 Returns:  the integer value, or
8334           -1 if string is NULL (which implies an expansion error)
8335           -2 for an integer interpretation error
8336           expand_string_message is set NULL for an OK integer
8337 */
8338
8339 static int_eximarith_t
8340 expanded_string_integer(const uschar *s, BOOL isplus)
8341 {
8342 int_eximarith_t value;
8343 uschar *msg = US"invalid integer \"%s\"";
8344 uschar *endptr;
8345
8346 /* If expansion failed, expand_string_message will be set. */
8347
8348 if (!s) return -1;
8349
8350 /* On an overflow, strtol() returns LONG_MAX or LONG_MIN, and sets errno
8351 to ERANGE. When there isn't an overflow, errno is not changed, at least on some
8352 systems, so we set it zero ourselves. */
8353
8354 errno = 0;
8355 expand_string_message = NULL;               /* Indicates no error */
8356
8357 /* Before Exim 4.64, strings consisting entirely of whitespace compared
8358 equal to 0.  Unfortunately, people actually relied upon that, so preserve
8359 the behaviour explicitly.  Stripping leading whitespace is a harmless
8360 noop change since strtol skips it anyway (provided that there is a number
8361 to find at all). */
8362 if (isspace(*s))
8363   if (Uskip_whitespace(&s) == '\0')
8364     {
8365       DEBUG(D_expand)
8366        debug_printf_indent("treating blank string as number 0\n");
8367       return 0;
8368     }
8369
8370 value = strtoll(CS s, CSS &endptr, 10);
8371
8372 if (endptr == s)
8373   msg = US"integer expected but \"%s\" found";
8374 else if (value < 0 && isplus)
8375   msg = US"non-negative integer expected but \"%s\" found";
8376 else
8377   {
8378   switch (tolower(*endptr))
8379     {
8380     default:
8381       break;
8382     case 'k':
8383       if (value > EXIM_ARITH_MAX/1024 || value < EXIM_ARITH_MIN/1024) errno = ERANGE;
8384       else value *= 1024;
8385       endptr++;
8386       break;
8387     case 'm':
8388       if (value > EXIM_ARITH_MAX/(1024*1024) || value < EXIM_ARITH_MIN/(1024*1024)) errno = ERANGE;
8389       else value *= 1024*1024;
8390       endptr++;
8391       break;
8392     case 'g':
8393       if (value > EXIM_ARITH_MAX/(1024*1024*1024) || value < EXIM_ARITH_MIN/(1024*1024*1024)) errno = ERANGE;
8394       else value *= 1024*1024*1024;
8395       endptr++;
8396       break;
8397     }
8398   if (errno == ERANGE)
8399     msg = US"absolute value of integer \"%s\" is too large (overflow)";
8400   else
8401     if (Uskip_whitespace(&endptr) == 0) return value;
8402   }
8403
8404 expand_string_message = string_sprintf(CS msg, s);
8405 return -2;
8406 }
8407
8408
8409 /* These values are usually fixed boolean values, but they are permitted to be
8410 expanded strings.
8411
8412 Arguments:
8413   addr       address being routed
8414   mtype      the module type
8415   mname      the module name
8416   dbg_opt    debug selectors
8417   oname      the option name
8418   bvalue     the router's boolean value
8419   svalue     the router's string value
8420   rvalue     where to put the returned value
8421
8422 Returns:     OK     value placed in rvalue
8423              DEFER  expansion failed
8424 */
8425
8426 int
8427 exp_bool(address_item *addr,
8428   uschar *mtype, uschar *mname, unsigned dbg_opt,
8429   uschar *oname, BOOL bvalue,
8430   uschar *svalue, BOOL *rvalue)
8431 {
8432 uschar *expanded;
8433 if (!svalue) { *rvalue = bvalue; return OK; }
8434
8435 if (!(expanded = expand_string(svalue)))
8436   {
8437   if (f.expand_string_forcedfail)
8438     {
8439     DEBUG(dbg_opt) debug_printf("expansion of \"%s\" forced failure\n", oname);
8440     *rvalue = bvalue;
8441     return OK;
8442     }
8443   addr->message = string_sprintf("failed to expand \"%s\" in %s %s: %s",
8444       oname, mname, mtype, expand_string_message);
8445   DEBUG(dbg_opt) debug_printf("%s\n", addr->message);
8446   return DEFER;
8447   }
8448
8449 DEBUG(dbg_opt) debug_printf("expansion of \"%s\" yields \"%s\"\n", oname,
8450   expanded);
8451
8452 if (strcmpic(expanded, US"true") == 0 || strcmpic(expanded, US"yes") == 0)
8453   *rvalue = TRUE;
8454 else if (strcmpic(expanded, US"false") == 0 || strcmpic(expanded, US"no") == 0)
8455   *rvalue = FALSE;
8456 else
8457   {
8458   addr->message = string_sprintf("\"%s\" is not a valid value for the "
8459     "\"%s\" option in the %s %s", expanded, oname, mname, mtype);
8460   return DEFER;
8461   }
8462
8463 return OK;
8464 }
8465
8466
8467
8468 /* Avoid potentially exposing a password in a string about to be logged */
8469
8470 uschar *
8471 expand_hide_passwords(uschar * s)
8472 {
8473 return (  (  Ustrstr(s, "failed to expand") != NULL
8474           || Ustrstr(s, "expansion of ")    != NULL
8475           )
8476        && (  Ustrstr(s, "mysql")   != NULL
8477           || Ustrstr(s, "pgsql")   != NULL
8478           || Ustrstr(s, "redis")   != NULL
8479           || Ustrstr(s, "sqlite")  != NULL
8480           || Ustrstr(s, "ldap:")   != NULL
8481           || Ustrstr(s, "ldaps:")  != NULL
8482           || Ustrstr(s, "ldapi:")  != NULL
8483           || Ustrstr(s, "ldapdn:") != NULL
8484           || Ustrstr(s, "ldapm:")  != NULL
8485        )  )
8486   ? US"Temporary internal error" : s;
8487 }
8488
8489
8490 /* Read given named file into big_buffer.  Use for keying material etc.
8491 The content will have an ascii NUL appended.
8492
8493 Arguments:
8494  filename       as it says
8495
8496 Return:  pointer to buffer, or NULL on error.
8497 */
8498
8499 uschar *
8500 expand_file_big_buffer(const uschar * filename)
8501 {
8502 int fd, off = 0, len;
8503
8504 if ((fd = exim_open2(CS filename, O_RDONLY)) < 0)
8505   {
8506   log_write(0, LOG_MAIN | LOG_PANIC, "unable to open file for reading: %s",
8507              filename);
8508   return NULL;
8509   }
8510
8511 do
8512   {
8513   if ((len = read(fd, big_buffer + off, big_buffer_size - 2 - off)) < 0)
8514     {
8515     (void) close(fd);
8516     log_write(0, LOG_MAIN|LOG_PANIC, "unable to read file: %s", filename);
8517     return NULL;
8518     }
8519   off += len;
8520   }
8521 while (len > 0);
8522
8523 (void) close(fd);
8524 big_buffer[off] = '\0';
8525 return big_buffer;
8526 }
8527
8528
8529
8530 /*************************************************
8531 * Error-checking for testsuite                   *
8532 *************************************************/
8533 typedef struct {
8534   uschar *      region_start;
8535   uschar *      region_end;
8536   const uschar *var_name;
8537   const uschar *var_data;
8538 } err_ctx;
8539
8540 static void
8541 assert_variable_notin(uschar * var_name, uschar * var_data, void * ctx)
8542 {
8543 err_ctx * e = ctx;
8544 if (var_data >= e->region_start  &&  var_data < e->region_end)
8545   {
8546   e->var_name = CUS var_name;
8547   e->var_data = CUS var_data;
8548   }
8549 }
8550
8551 void
8552 assert_no_variables(void * ptr, int len, const char * filename, int linenumber)
8553 {
8554 err_ctx e = { .region_start = ptr, .region_end = US ptr + len,
8555               .var_name = NULL, .var_data = NULL };
8556
8557 /* check acl_ variables */
8558 tree_walk(acl_var_c, assert_variable_notin, &e);
8559 tree_walk(acl_var_m, assert_variable_notin, &e);
8560
8561 /* check auth<n> variables */
8562 for (int i = 0; i < AUTH_VARS; i++) if (auth_vars[i])
8563   assert_variable_notin(US"auth<n>", auth_vars[i], &e);
8564
8565 /* check regex<n> variables */
8566 for (int i = 0; i < REGEX_VARS; i++) if (regex_vars[i])
8567   assert_variable_notin(US"regex<n>", regex_vars[i], &e);
8568
8569 /* check known-name variables */
8570 for (var_entry * v = var_table; v < var_table + var_table_size; v++)
8571   if (v->type == vtype_stringptr)
8572     assert_variable_notin(US v->name, *(USS v->value), &e);
8573
8574 /* check dns and address trees */
8575 tree_walk(tree_dns_fails,     assert_variable_notin, &e);
8576 tree_walk(tree_duplicates,    assert_variable_notin, &e);
8577 tree_walk(tree_nonrecipients, assert_variable_notin, &e);
8578 tree_walk(tree_unusable,      assert_variable_notin, &e);
8579
8580 if (e.var_name)
8581   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
8582     "live variable '%s' destroyed by reset_store at %s:%d\n- value '%.64s'",
8583     e.var_name, filename, linenumber, e.var_data);
8584 }
8585
8586
8587
8588 /*************************************************
8589 **************************************************
8590 *             Stand-alone test program           *
8591 **************************************************
8592 *************************************************/
8593
8594 #ifdef STAND_ALONE
8595
8596
8597 BOOL
8598 regex_match_and_setup(const pcre *re, uschar *subject, int options, int setup)
8599 {
8600 int ovector[3*(EXPAND_MAXN+1)];
8601 int n = pcre_exec(re, NULL, subject, Ustrlen(subject), 0, PCRE_EOPT|options,
8602   ovector, nelem(ovector));
8603 BOOL yield = n >= 0;
8604 if (n == 0) n = EXPAND_MAXN + 1;
8605 if (yield)
8606   {
8607   expand_nmax = setup < 0 ? 0 : setup + 1;
8608   for (int nn = setup < 0 ? 0 : 2; nn < n*2; nn += 2)
8609     {
8610     expand_nstring[expand_nmax] = subject + ovector[nn];
8611     expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
8612     }
8613   expand_nmax--;
8614   }
8615 return yield;
8616 }
8617
8618
8619 int main(int argc, uschar **argv)
8620 {
8621 uschar buffer[1024];
8622
8623 debug_selector = D_v;
8624 debug_file = stderr;
8625 debug_fd = fileno(debug_file);
8626 big_buffer = malloc(big_buffer_size);
8627
8628 for (int i = 1; i < argc; i++)
8629   {
8630   if (argv[i][0] == '+')
8631     {
8632     debug_trace_memory = 2;
8633     argv[i]++;
8634     }
8635   if (isdigit(argv[i][0]))
8636     debug_selector = Ustrtol(argv[i], NULL, 0);
8637   else
8638     if (Ustrspn(argv[i], "abcdefghijklmnopqrtsuvwxyz0123456789-.:/") ==
8639         Ustrlen(argv[i]))
8640       {
8641 #ifdef LOOKUP_LDAP
8642       eldap_default_servers = argv[i];
8643 #endif
8644 #ifdef LOOKUP_MYSQL
8645       mysql_servers = argv[i];
8646 #endif
8647 #ifdef LOOKUP_PGSQL
8648       pgsql_servers = argv[i];
8649 #endif
8650 #ifdef LOOKUP_REDIS
8651       redis_servers = argv[i];
8652 #endif
8653       }
8654 #ifdef EXIM_PERL
8655   else opt_perl_startup = argv[i];
8656 #endif
8657   }
8658
8659 printf("Testing string expansion: debug_level = %d\n\n", debug_level);
8660
8661 expand_nstring[1] = US"string 1....";
8662 expand_nlength[1] = 8;
8663 expand_nmax = 1;
8664
8665 #ifdef EXIM_PERL
8666 if (opt_perl_startup != NULL)
8667   {
8668   uschar *errstr;
8669   printf("Starting Perl interpreter\n");
8670   errstr = init_perl(opt_perl_startup);
8671   if (errstr != NULL)
8672     {
8673     printf("** error in perl_startup code: %s\n", errstr);
8674     return EXIT_FAILURE;
8675     }
8676   }
8677 #endif /* EXIM_PERL */
8678
8679 /* Thie deliberately regards the input as untainted, so that it can be
8680 expanded; only reasonable since this is a test for string-expansions. */
8681
8682 while (fgets(buffer, sizeof(buffer), stdin) != NULL)
8683   {
8684   rmark reset_point = store_mark();
8685   uschar *yield = expand_string(buffer);
8686   if (yield)
8687     printf("%s\n", yield);
8688   else
8689     {
8690     if (f.search_find_defer) printf("search_find deferred\n");
8691     printf("Failed: %s\n", expand_string_message);
8692     if (f.expand_string_forcedfail) printf("Forced failure\n");
8693     printf("\n");
8694     }
8695   store_reset(reset_point);
8696   }
8697
8698 search_tidyup();
8699
8700 return 0;
8701 }
8702
8703 #endif
8704
8705 /* vi: aw ai sw=2
8706 */
8707 /* End of expand.c */