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