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