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