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