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