JSON: add iterative conditions for arrays
[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 occured.
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       enum {extract_basic, extract_json, extract_jsons} fmt = extract_basic;
5666
5667       while (isspace(*s)) s++;
5668
5669       /* Check for a format-variant specifier */
5670
5671       if (*s != '{')                                    /*}*/
5672         if (Ustrncmp(s, "json", 4) == 0)
5673           if (*(s += 4) == 's')
5674             {fmt = extract_jsons; s++;}
5675           else
5676             fmt = extract_json;
5677
5678       /* While skipping we cannot rely on the data for expansions being
5679       available (eg. $item) hence cannot decide on numeric vs. keyed.
5680       Read a maximum of 5 arguments (including the yes/no) */
5681
5682       if (skipping)
5683         {
5684         for (int j = 5; j > 0 && *s == '{'; j--)                /*'}'*/
5685           {
5686           if (!expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok))
5687             goto EXPAND_FAILED;                                 /*'{'*/
5688           if (*s++ != '}')
5689             {
5690             expand_string_message = US"missing '{' for arg of extract";
5691             goto EXPAND_FAILED_CURLY;
5692             }
5693           while (isspace(*s)) s++;
5694           }
5695         if (  Ustrncmp(s, "fail", 4) == 0                       /*'{'*/
5696            && (s[4] == '}' || s[4] == ' ' || s[4] == '\t' || !s[4])
5697            )
5698           {
5699           s += 4;
5700           while (isspace(*s)) s++;
5701           }                                                     /*'{'*/
5702         if (*s != '}')
5703           {
5704           expand_string_message = US"missing '}' closing extract";
5705           goto EXPAND_FAILED_CURLY;
5706           }
5707         }
5708
5709       else for (int i = 0, j = 2; i < j; i++) /* Read the proper number of arguments */
5710         {
5711         while (isspace(*s)) s++;
5712         if (*s == '{')                                          /*'}'*/
5713           {
5714           sub[i] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok);
5715           if (sub[i] == NULL) goto EXPAND_FAILED;               /*'{'*/
5716           if (*s++ != '}')
5717             {
5718             expand_string_message = string_sprintf(
5719               "missing '}' closing arg %d of extract", i+1);
5720             goto EXPAND_FAILED_CURLY;
5721             }
5722
5723           /* After removal of leading and trailing white space, the first
5724           argument must not be empty; if it consists entirely of digits
5725           (optionally preceded by a minus sign), this is a numerical
5726           extraction, and we expect 3 arguments (normal) or 2 (json). */
5727
5728           if (i == 0)
5729             {
5730             int len;
5731             int x = 0;
5732             uschar *p = sub[0];
5733
5734             while (isspace(*p)) p++;
5735             sub[0] = p;
5736
5737             len = Ustrlen(p);
5738             while (len > 0 && isspace(p[len-1])) len--;
5739             p[len] = 0;
5740
5741             if (*p == 0)
5742               {
5743               expand_string_message = US"first argument of \"extract\" must "
5744                 "not be empty";
5745               goto EXPAND_FAILED;
5746               }
5747
5748             if (*p == '-')
5749               {
5750               field_number = -1;
5751               p++;
5752               }
5753             while (*p != 0 && isdigit(*p)) x = x * 10 + *p++ - '0';
5754             if (*p == 0)
5755               {
5756               field_number *= x;
5757               if (fmt == extract_basic) j = 3;               /* Need 3 args */
5758               field_number_set = TRUE;
5759               }
5760             }
5761           }
5762         else
5763           {
5764           expand_string_message = string_sprintf(
5765             "missing '{' for arg %d of extract", i+1);
5766           goto EXPAND_FAILED_CURLY;
5767           }
5768         }
5769
5770       /* Extract either the numbered or the keyed substring into $value. If
5771       skipping, just pretend the extraction failed. */
5772
5773       if (skipping)
5774         lookup_value = NULL;
5775       else switch (fmt)
5776         {
5777         case extract_basic:
5778           lookup_value = field_number_set
5779             ? expand_gettokened(field_number, sub[1], sub[2])
5780             : expand_getkeyed(sub[0], sub[1]);
5781           break;
5782
5783         case extract_json:
5784         case extract_jsons:
5785           {
5786           uschar * s, * item;
5787           const uschar * list;
5788
5789           /* Array: Bracket-enclosed and comma-separated.
5790           Object: Brace-enclosed, comma-sep list of name:value pairs */
5791
5792           if (!(s = dewrap(sub[1], field_number_set ? US"[]" : US"{}")))
5793             {
5794             expand_string_message =
5795               string_sprintf("%s wrapping %s for extract json",
5796                 expand_string_message,
5797                 field_number_set ? "array" : "object");
5798             goto EXPAND_FAILED_CURLY;
5799             }
5800
5801           list = s;
5802           if (field_number_set)
5803             {
5804             if (field_number <= 0)
5805               {
5806               expand_string_message = US"first argument of \"extract\" must "
5807                 "be greater than zero";
5808               goto EXPAND_FAILED;
5809               }
5810             while (field_number > 0 && (item = json_nextinlist(&list)))
5811               field_number--;
5812             s = item;
5813             lookup_value = s;
5814             while (*s) s++;
5815             while (--s >= lookup_value && isspace(*s)) *s = '\0';
5816             }
5817           else
5818             {
5819             lookup_value = NULL;
5820             while ((item = json_nextinlist(&list)))
5821               {
5822               /* Item is:  string name-sep value.  string is quoted.
5823               Dequote the string and compare with the search key. */
5824
5825               if (!(item = dewrap(item, US"\"\"")))
5826                 {
5827                 expand_string_message =
5828                   string_sprintf("%s wrapping string key for extract json",
5829                     expand_string_message);
5830                 goto EXPAND_FAILED_CURLY;
5831                 }
5832               if (Ustrcmp(item, sub[0]) == 0)   /*XXX should be a UTF8-compare */
5833                 {
5834                 s = item + Ustrlen(item) + 1;
5835                 while (isspace(*s)) s++;
5836                 if (*s != ':')
5837                   {
5838                   expand_string_message = string_sprintf(
5839                     "missing object value-separator for extract json");
5840                   goto EXPAND_FAILED_CURLY;
5841                   }
5842                 s++;
5843                 while (isspace(*s)) s++;
5844                 lookup_value = s;
5845                 break;
5846                 }
5847               }
5848             }
5849           }
5850
5851           if (fmt == extract_jsons)
5852             if (!(lookup_value = dewrap(lookup_value, US"\"\"")))
5853               {
5854               expand_string_message =
5855                 string_sprintf("%s wrapping string result for extract jsons",
5856                   expand_string_message);
5857               goto EXPAND_FAILED_CURLY;
5858               }
5859         }
5860
5861       /* If no string follows, $value gets substituted; otherwise there can
5862       be yes/no strings, as for lookup or if. */
5863
5864       switch(process_yesno(
5865                skipping,                     /* were previously skipping */
5866                lookup_value != NULL,         /* success/failure indicator */
5867                save_lookup_value,            /* value to reset for string2 */
5868                &s,                           /* input pointer */
5869                &yield,                       /* output pointer */
5870                US"extract",                  /* condition type */
5871                &resetok))
5872         {
5873         case 1: goto EXPAND_FAILED;          /* when all is well, the */
5874         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
5875         }
5876
5877       /* All done - restore numerical variables. */
5878
5879       restore_expand_strings(save_expand_nmax, save_expand_nstring,
5880         save_expand_nlength);
5881
5882       continue;
5883       }
5884
5885     /* return the Nth item from a list */
5886
5887     case EITEM_LISTEXTRACT:
5888       {
5889       int field_number = 1;
5890       uschar *save_lookup_value = lookup_value;
5891       uschar *sub[2];
5892       int save_expand_nmax =
5893         save_expand_strings(save_expand_nstring, save_expand_nlength);
5894
5895       /* Read the field & list arguments */
5896
5897       for (int i = 0; i < 2; i++)
5898         {
5899         while (isspace(*s)) s++;
5900         if (*s != '{')                                  /*'}'*/
5901           {
5902           expand_string_message = string_sprintf(
5903             "missing '{' for arg %d of listextract", i+1);
5904           goto EXPAND_FAILED_CURLY;
5905           }
5906
5907         sub[i] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok);
5908         if (!sub[i])     goto EXPAND_FAILED;            /*{*/
5909         if (*s++ != '}')
5910           {
5911           expand_string_message = string_sprintf(
5912             "missing '}' closing arg %d of listextract", i+1);
5913           goto EXPAND_FAILED_CURLY;
5914           }
5915
5916         /* After removal of leading and trailing white space, the first
5917         argument must be numeric and nonempty. */
5918
5919         if (i == 0)
5920           {
5921           int len;
5922           int x = 0;
5923           uschar *p = sub[0];
5924
5925           while (isspace(*p)) p++;
5926           sub[0] = p;
5927
5928           len = Ustrlen(p);
5929           while (len > 0 && isspace(p[len-1])) len--;
5930           p[len] = 0;
5931
5932           if (!*p && !skipping)
5933             {
5934             expand_string_message = US"first argument of \"listextract\" must "
5935               "not be empty";
5936             goto EXPAND_FAILED;
5937             }
5938
5939           if (*p == '-')
5940             {
5941             field_number = -1;
5942             p++;
5943             }
5944           while (*p && isdigit(*p)) x = x * 10 + *p++ - '0';
5945           if (*p)
5946             {
5947             expand_string_message = US"first argument of \"listextract\" must "
5948               "be numeric";
5949             goto EXPAND_FAILED;
5950             }
5951           field_number *= x;
5952           }
5953         }
5954
5955       /* Extract the numbered element into $value. If
5956       skipping, just pretend the extraction failed. */
5957
5958       lookup_value = skipping ? NULL : expand_getlistele(field_number, sub[1]);
5959
5960       /* If no string follows, $value gets substituted; otherwise there can
5961       be yes/no strings, as for lookup or if. */
5962
5963       switch(process_yesno(
5964                skipping,                     /* were previously skipping */
5965                lookup_value != NULL,         /* success/failure indicator */
5966                save_lookup_value,            /* value to reset for string2 */
5967                &s,                           /* input pointer */
5968                &yield,                       /* output pointer */
5969                US"listextract",              /* condition type */
5970                &resetok))
5971         {
5972         case 1: goto EXPAND_FAILED;          /* when all is well, the */
5973         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
5974         }
5975
5976       /* All done - restore numerical variables. */
5977
5978       restore_expand_strings(save_expand_nmax, save_expand_nstring,
5979         save_expand_nlength);
5980
5981       continue;
5982       }
5983
5984 #ifdef SUPPORT_TLS
5985     case EITEM_CERTEXTRACT:
5986       {
5987       uschar *save_lookup_value = lookup_value;
5988       uschar *sub[2];
5989       int save_expand_nmax =
5990         save_expand_strings(save_expand_nstring, save_expand_nlength);
5991
5992       /* Read the field argument */
5993       while (isspace(*s)) s++;
5994       if (*s != '{')                                    /*}*/
5995         {
5996         expand_string_message = US"missing '{' for field arg of certextract";
5997         goto EXPAND_FAILED_CURLY;
5998         }
5999       sub[0] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok);
6000       if (!sub[0])     goto EXPAND_FAILED;              /*{*/
6001       if (*s++ != '}')
6002         {
6003         expand_string_message = US"missing '}' closing field arg of certextract";
6004         goto EXPAND_FAILED_CURLY;
6005         }
6006       /* strip spaces fore & aft */
6007       {
6008       int len;
6009       uschar *p = sub[0];
6010
6011       while (isspace(*p)) p++;
6012       sub[0] = p;
6013
6014       len = Ustrlen(p);
6015       while (len > 0 && isspace(p[len-1])) len--;
6016       p[len] = 0;
6017       }
6018
6019       /* inspect the cert argument */
6020       while (isspace(*s)) s++;
6021       if (*s != '{')                                    /*}*/
6022         {
6023         expand_string_message = US"missing '{' for cert variable arg of certextract";
6024         goto EXPAND_FAILED_CURLY;
6025         }
6026       if (*++s != '$')
6027         {
6028         expand_string_message = US"second argument of \"certextract\" must "
6029           "be a certificate variable";
6030         goto EXPAND_FAILED;
6031         }
6032       sub[1] = expand_string_internal(s+1, TRUE, &s, skipping, FALSE, &resetok);
6033       if (!sub[1])     goto EXPAND_FAILED;              /*{*/
6034       if (*s++ != '}')
6035         {
6036         expand_string_message = US"missing '}' closing cert variable arg of certextract";
6037         goto EXPAND_FAILED_CURLY;
6038         }
6039
6040       if (skipping)
6041         lookup_value = NULL;
6042       else
6043         {
6044         lookup_value = expand_getcertele(sub[0], sub[1]);
6045         if (*expand_string_message) goto EXPAND_FAILED;
6046         }
6047       switch(process_yesno(
6048                skipping,                     /* were previously skipping */
6049                lookup_value != NULL,         /* success/failure indicator */
6050                save_lookup_value,            /* value to reset for string2 */
6051                &s,                           /* input pointer */
6052                &yield,                       /* output pointer */
6053                US"certextract",              /* condition type */
6054                &resetok))
6055         {
6056         case 1: goto EXPAND_FAILED;          /* when all is well, the */
6057         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
6058         }
6059
6060       restore_expand_strings(save_expand_nmax, save_expand_nstring,
6061         save_expand_nlength);
6062       continue;
6063       }
6064 #endif  /*SUPPORT_TLS*/
6065
6066     /* Handle list operations */
6067
6068     case EITEM_FILTER:
6069     case EITEM_MAP:
6070     case EITEM_REDUCE:
6071       {
6072       int sep = 0;
6073       int save_ptr = yield->ptr;
6074       uschar outsep[2] = { '\0', '\0' };
6075       const uschar *list, *expr, *temp;
6076       uschar *save_iterate_item = iterate_item;
6077       uschar *save_lookup_value = lookup_value;
6078
6079       while (isspace(*s)) s++;
6080       if (*s++ != '{')
6081         {
6082         expand_string_message =
6083           string_sprintf("missing '{' for first arg of %s", name);
6084         goto EXPAND_FAILED_CURLY;
6085         }
6086
6087       list = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok);
6088       if (list == NULL) goto EXPAND_FAILED;
6089       if (*s++ != '}')
6090         {
6091         expand_string_message =
6092           string_sprintf("missing '}' closing first arg of %s", name);
6093         goto EXPAND_FAILED_CURLY;
6094         }
6095
6096       if (item_type == EITEM_REDUCE)
6097         {
6098         uschar * t;
6099         while (isspace(*s)) s++;
6100         if (*s++ != '{')
6101           {
6102           expand_string_message = US"missing '{' for second arg of reduce";
6103           goto EXPAND_FAILED_CURLY;
6104           }
6105         t = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok);
6106         if (!t) goto EXPAND_FAILED;
6107         lookup_value = t;
6108         if (*s++ != '}')
6109           {
6110           expand_string_message = US"missing '}' closing second arg of reduce";
6111           goto EXPAND_FAILED_CURLY;
6112           }
6113         }
6114
6115       while (isspace(*s)) s++;
6116       if (*s++ != '{')
6117         {
6118         expand_string_message =
6119           string_sprintf("missing '{' for last arg of %s", name);
6120         goto EXPAND_FAILED_CURLY;
6121         }
6122
6123       expr = s;
6124
6125       /* For EITEM_FILTER, call eval_condition once, with result discarded (as
6126       if scanning a "false" part). This allows us to find the end of the
6127       condition, because if the list is empty, we won't actually evaluate the
6128       condition for real. For EITEM_MAP and EITEM_REDUCE, do the same, using
6129       the normal internal expansion function. */
6130
6131       if (item_type == EITEM_FILTER)
6132         {
6133         temp = eval_condition(expr, &resetok, NULL);
6134         if (temp != NULL) s = temp;
6135         }
6136       else
6137         temp = expand_string_internal(s, TRUE, &s, TRUE, TRUE, &resetok);
6138
6139       if (temp == NULL)
6140         {
6141         expand_string_message = string_sprintf("%s inside \"%s\" item",
6142           expand_string_message, name);
6143         goto EXPAND_FAILED;
6144         }
6145
6146       while (isspace(*s)) s++;
6147       if (*s++ != '}')
6148         {                                               /*{*/
6149         expand_string_message = string_sprintf("missing } at end of condition "
6150           "or expression inside \"%s\"; could be an unquoted } in the content",
6151           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 \"%s\"",
6159           name);
6160         goto EXPAND_FAILED;
6161         }
6162
6163       /* If we are skipping, we can now just move on to the next item. When
6164       processing for real, we perform the iteration. */
6165
6166       if (skipping) continue;
6167       while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)))
6168         {
6169         *outsep = (uschar)sep;      /* Separator as a string */
6170
6171         DEBUG(D_expand) debug_printf_indent("%s: $item = '%s'  $value = '%s'\n",
6172                           name, iterate_item, lookup_value);
6173
6174         if (item_type == EITEM_FILTER)
6175           {
6176           BOOL condresult;
6177           if (eval_condition(expr, &resetok, &condresult) == NULL)
6178             {
6179             iterate_item = save_iterate_item;
6180             lookup_value = save_lookup_value;
6181             expand_string_message = string_sprintf("%s inside \"%s\" condition",
6182               expand_string_message, name);
6183             goto EXPAND_FAILED;
6184             }
6185           DEBUG(D_expand) debug_printf_indent("%s: condition is %s\n", name,
6186             condresult? "true":"false");
6187           if (condresult)
6188             temp = iterate_item;    /* TRUE => include this item */
6189           else
6190             continue;               /* FALSE => skip this item */
6191           }
6192
6193         /* EITEM_MAP and EITEM_REDUCE */
6194
6195         else
6196           {
6197           uschar * t = expand_string_internal(expr, TRUE, NULL, skipping, TRUE, &resetok);
6198           temp = t;
6199           if (temp == NULL)
6200             {
6201             iterate_item = save_iterate_item;
6202             expand_string_message = string_sprintf("%s inside \"%s\" item",
6203               expand_string_message, name);
6204             goto EXPAND_FAILED;
6205             }
6206           if (item_type == EITEM_REDUCE)
6207             {
6208             lookup_value = t;         /* Update the value of $value */
6209             continue;                 /* and continue the iteration */
6210             }
6211           }
6212
6213         /* We reach here for FILTER if the condition is true, always for MAP,
6214         and never for REDUCE. The value in "temp" is to be added to the output
6215         list that is being created, ensuring that any occurrences of the
6216         separator character are doubled. Unless we are dealing with the first
6217         item of the output list, add in a space if the new item begins with the
6218         separator character, or is an empty string. */
6219
6220         if (yield->ptr != save_ptr && (temp[0] == *outsep || temp[0] == 0))
6221           yield = string_catn(yield, US" ", 1);
6222
6223         /* Add the string in "temp" to the output list that we are building,
6224         This is done in chunks by searching for the separator character. */
6225
6226         for (;;)
6227           {
6228           size_t seglen = Ustrcspn(temp, outsep);
6229
6230           yield = string_catn(yield, temp, seglen + 1);
6231
6232           /* If we got to the end of the string we output one character
6233           too many; backup and end the loop. Otherwise arrange to double the
6234           separator. */
6235
6236           if (temp[seglen] == '\0') { yield->ptr--; break; }
6237           yield = string_catn(yield, outsep, 1);
6238           temp += seglen + 1;
6239           }
6240
6241         /* Output a separator after the string: we will remove the redundant
6242         final one at the end. */
6243
6244         yield = string_catn(yield, outsep, 1);
6245         }   /* End of iteration over the list loop */
6246
6247       /* REDUCE has generated no output above: output the final value of
6248       $value. */
6249
6250       if (item_type == EITEM_REDUCE)
6251         {
6252         yield = string_cat(yield, lookup_value);
6253         lookup_value = save_lookup_value;  /* Restore $value */
6254         }
6255
6256       /* FILTER and MAP generate lists: if they have generated anything, remove
6257       the redundant final separator. Even though an empty item at the end of a
6258       list does not count, this is tidier. */
6259
6260       else if (yield->ptr != save_ptr) yield->ptr--;
6261
6262       /* Restore preserved $item */
6263
6264       iterate_item = save_iterate_item;
6265       continue;
6266       }
6267
6268     case EITEM_SORT:
6269       {
6270       int sep = 0;
6271       const uschar *srclist, *cmp, *xtract;
6272       uschar *srcitem;
6273       const uschar *dstlist = NULL, *dstkeylist = NULL;
6274       uschar * tmp;
6275       uschar *save_iterate_item = iterate_item;
6276
6277       while (isspace(*s)) s++;
6278       if (*s++ != '{')
6279         {
6280         expand_string_message = US"missing '{' for list arg of sort";
6281         goto EXPAND_FAILED_CURLY;
6282         }
6283
6284       srclist = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok);
6285       if (!srclist) goto EXPAND_FAILED;
6286       if (*s++ != '}')
6287         {
6288         expand_string_message = US"missing '}' closing list arg of sort";
6289         goto EXPAND_FAILED_CURLY;
6290         }
6291
6292       while (isspace(*s)) s++;
6293       if (*s++ != '{')
6294         {
6295         expand_string_message = US"missing '{' for comparator arg of sort";
6296         goto EXPAND_FAILED_CURLY;
6297         }
6298
6299       cmp = expand_string_internal(s, TRUE, &s, skipping, FALSE, &resetok);
6300       if (!cmp) goto EXPAND_FAILED;
6301       if (*s++ != '}')
6302         {
6303         expand_string_message = US"missing '}' closing comparator arg of sort";
6304         goto EXPAND_FAILED_CURLY;
6305         }
6306
6307       while (isspace(*s)) s++;
6308       if (*s++ != '{')
6309         {
6310         expand_string_message = US"missing '{' for extractor arg of sort";
6311         goto EXPAND_FAILED_CURLY;
6312         }
6313
6314       xtract = s;
6315       tmp = expand_string_internal(s, TRUE, &s, TRUE, TRUE, &resetok);
6316       if (!tmp) goto EXPAND_FAILED;
6317       xtract = string_copyn(xtract, s - xtract);
6318
6319       if (*s++ != '}')
6320         {
6321         expand_string_message = US"missing '}' closing extractor arg of sort";
6322         goto EXPAND_FAILED_CURLY;
6323         }
6324                                                         /*{*/
6325       if (*s++ != '}')
6326         {                                               /*{*/
6327         expand_string_message = US"missing } at end of \"sort\"";
6328         goto EXPAND_FAILED;
6329         }
6330
6331       if (skipping) continue;
6332
6333       while ((srcitem = string_nextinlist(&srclist, &sep, NULL, 0)))
6334         {
6335         uschar * dstitem;
6336         gstring * newlist = NULL;
6337         gstring * newkeylist = NULL;
6338         uschar * srcfield;
6339
6340         DEBUG(D_expand) debug_printf_indent("%s: $item = \"%s\"\n", name, srcitem);
6341
6342         /* extract field for comparisons */
6343         iterate_item = srcitem;
6344         if (  !(srcfield = expand_string_internal(xtract, FALSE, NULL, FALSE,
6345                                           TRUE, &resetok))
6346            || !*srcfield)
6347           {
6348           expand_string_message = string_sprintf(
6349               "field-extract in sort: \"%s\"", xtract);
6350           goto EXPAND_FAILED;
6351           }
6352
6353         /* Insertion sort */
6354
6355         /* copy output list until new-item < list-item */
6356         while ((dstitem = string_nextinlist(&dstlist, &sep, NULL, 0)))
6357           {
6358           uschar * dstfield;
6359           uschar * expr;
6360           BOOL before;
6361
6362           /* field for comparison */
6363           if (!(dstfield = string_nextinlist(&dstkeylist, &sep, NULL, 0)))
6364             goto sort_mismatch;
6365
6366           /* build and run condition string */
6367           expr = string_sprintf("%s{%s}{%s}", cmp, srcfield, dstfield);
6368
6369           DEBUG(D_expand) debug_printf_indent("%s: cond = \"%s\"\n", name, expr);
6370           if (!eval_condition(expr, &resetok, &before))
6371             {
6372             expand_string_message = string_sprintf("comparison in sort: %s",
6373                 expr);
6374             goto EXPAND_FAILED;
6375             }
6376
6377           if (before)
6378             {
6379             /* New-item sorts before this dst-item.  Append new-item,
6380             then dst-item, then remainder of dst list. */
6381
6382             newlist = string_append_listele(newlist, sep, srcitem);
6383             newkeylist = string_append_listele(newkeylist, sep, srcfield);
6384             srcitem = NULL;
6385
6386             newlist = string_append_listele(newlist, sep, dstitem);
6387             newkeylist = string_append_listele(newkeylist, sep, dstfield);
6388
6389             while ((dstitem = string_nextinlist(&dstlist, &sep, NULL, 0)))
6390               {
6391               if (!(dstfield = string_nextinlist(&dstkeylist, &sep, NULL, 0)))
6392                 goto sort_mismatch;
6393               newlist = string_append_listele(newlist, sep, dstitem);
6394               newkeylist = string_append_listele(newkeylist, sep, dstfield);
6395               }
6396
6397             break;
6398             }
6399
6400           newlist = string_append_listele(newlist, sep, dstitem);
6401           newkeylist = string_append_listele(newkeylist, sep, dstfield);
6402           }
6403
6404         /* If we ran out of dstlist without consuming srcitem, append it */
6405         if (srcitem)
6406           {
6407           newlist = string_append_listele(newlist, sep, srcitem);
6408           newkeylist = string_append_listele(newkeylist, sep, srcfield);
6409           }
6410
6411         dstlist = newlist->s;
6412         dstkeylist = newkeylist->s;
6413
6414         DEBUG(D_expand) debug_printf_indent("%s: dstlist = \"%s\"\n", name, dstlist);
6415         DEBUG(D_expand) debug_printf_indent("%s: dstkeylist = \"%s\"\n", name, dstkeylist);
6416         }
6417
6418       if (dstlist)
6419         yield = string_cat(yield, dstlist);
6420
6421       /* Restore preserved $item */
6422       iterate_item = save_iterate_item;
6423       continue;
6424
6425       sort_mismatch:
6426         expand_string_message = US"Internal error in sort (list mismatch)";
6427         goto EXPAND_FAILED;
6428       }
6429
6430
6431     /* If ${dlfunc } support is configured, handle calling dynamically-loaded
6432     functions, unless locked out at this time. Syntax is ${dlfunc{file}{func}}
6433     or ${dlfunc{file}{func}{arg}} or ${dlfunc{file}{func}{arg1}{arg2}} or up to
6434     a maximum of EXPAND_DLFUNC_MAX_ARGS arguments (defined below). */
6435
6436     #define EXPAND_DLFUNC_MAX_ARGS 8
6437
6438     case EITEM_DLFUNC:
6439 #ifndef EXPAND_DLFUNC
6440       expand_string_message = US"\"${dlfunc\" encountered, but this facility "  /*}*/
6441         "is not included in this binary";
6442       goto EXPAND_FAILED;
6443
6444 #else   /* EXPAND_DLFUNC */
6445       {
6446       tree_node *t;
6447       exim_dlfunc_t *func;
6448       uschar *result;
6449       int status, argc;
6450       uschar *argv[EXPAND_DLFUNC_MAX_ARGS + 3];
6451
6452       if ((expand_forbid & RDO_DLFUNC) != 0)
6453         {
6454         expand_string_message =
6455           US"dynamically-loaded functions are not permitted";
6456         goto EXPAND_FAILED;
6457         }
6458
6459       switch(read_subs(argv, EXPAND_DLFUNC_MAX_ARGS + 2, 2, &s, skipping,
6460            TRUE, US"dlfunc", &resetok))
6461         {
6462         case 1: goto EXPAND_FAILED_CURLY;
6463         case 2:
6464         case 3: goto EXPAND_FAILED;
6465         }
6466
6467       /* If skipping, we don't actually do anything */
6468
6469       if (skipping) continue;
6470
6471       /* Look up the dynamically loaded object handle in the tree. If it isn't
6472       found, dlopen() the file and put the handle in the tree for next time. */
6473
6474       if (!(t = tree_search(dlobj_anchor, argv[0])))
6475         {
6476         void *handle = dlopen(CS argv[0], RTLD_LAZY);
6477         if (handle == NULL)
6478           {
6479           expand_string_message = string_sprintf("dlopen \"%s\" failed: %s",
6480             argv[0], dlerror());
6481           log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message);
6482           goto EXPAND_FAILED;
6483           }
6484         t = store_get_perm(sizeof(tree_node) + Ustrlen(argv[0]));
6485         Ustrcpy(t->name, argv[0]);
6486         t->data.ptr = handle;
6487         (void)tree_insertnode(&dlobj_anchor, t);
6488         }
6489
6490       /* Having obtained the dynamically loaded object handle, look up the
6491       function pointer. */
6492
6493       func = (exim_dlfunc_t *)dlsym(t->data.ptr, CS argv[1]);
6494       if (func == NULL)
6495         {
6496         expand_string_message = string_sprintf("dlsym \"%s\" in \"%s\" failed: "
6497           "%s", argv[1], argv[0], dlerror());
6498         log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message);
6499         goto EXPAND_FAILED;
6500         }
6501
6502       /* Call the function and work out what to do with the result. If it
6503       returns OK, we have a replacement string; if it returns DEFER then
6504       expansion has failed in a non-forced manner; if it returns FAIL then
6505       failure was forced; if it returns ERROR or any other value there's a
6506       problem, so panic slightly. In any case, assume that the function has
6507       side-effects on the store that must be preserved. */
6508
6509       resetok = FALSE;
6510       result = NULL;
6511       for (argc = 0; argv[argc] != NULL; argc++);
6512       status = func(&result, argc - 2, &argv[2]);
6513       if(status == OK)
6514         {
6515         if (result == NULL) result = US"";
6516         yield = string_cat(yield, result);
6517         continue;
6518         }
6519       else
6520         {
6521         expand_string_message = result == NULL ? US"(no message)" : result;
6522         if(status == FAIL_FORCED) f.expand_string_forcedfail = TRUE;
6523           else if(status != FAIL)
6524             log_write(0, LOG_MAIN|LOG_PANIC, "dlfunc{%s}{%s} failed (%d): %s",
6525               argv[0], argv[1], status, expand_string_message);
6526         goto EXPAND_FAILED;
6527         }
6528       }
6529 #endif /* EXPAND_DLFUNC */
6530
6531     case EITEM_ENV:     /* ${env {name} {val_if_found} {val_if_unfound}} */
6532       {
6533       uschar * key;
6534       uschar *save_lookup_value = lookup_value;
6535
6536       while (isspace(*s)) s++;
6537       if (*s != '{')                                    /*}*/
6538         goto EXPAND_FAILED;
6539
6540       key = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok);
6541       if (!key) goto EXPAND_FAILED;                     /*{*/
6542       if (*s++ != '}')
6543         {
6544         expand_string_message = US"missing '{' for name arg of env";
6545         goto EXPAND_FAILED_CURLY;
6546         }
6547
6548       lookup_value = US getenv(CS key);
6549
6550       switch(process_yesno(
6551                skipping,                     /* were previously skipping */
6552                lookup_value != NULL,         /* success/failure indicator */
6553                save_lookup_value,            /* value to reset for string2 */
6554                &s,                           /* input pointer */
6555                &yield,                       /* output pointer */
6556                US"env",                      /* condition type */
6557                &resetok))
6558         {
6559         case 1: goto EXPAND_FAILED;          /* when all is well, the */
6560         case 2: goto EXPAND_FAILED_CURLY;    /* returned value is 0 */
6561         }
6562       continue;
6563       }
6564     }   /* EITEM_* switch */
6565
6566   /* Control reaches here if the name is not recognized as one of the more
6567   complicated expansion items. Check for the "operator" syntax (name terminated
6568   by a colon). Some of the operators have arguments, separated by _ from the
6569   name. */
6570
6571   if (*s == ':')
6572     {
6573     int c;
6574     uschar *arg = NULL;
6575     uschar *sub;
6576 #ifdef SUPPORT_TLS
6577     var_entry *vp = NULL;
6578 #endif
6579
6580     /* Owing to an historical mis-design, an underscore may be part of the
6581     operator name, or it may introduce arguments.  We therefore first scan the
6582     table of names that contain underscores. If there is no match, we cut off
6583     the arguments and then scan the main table. */
6584
6585     if ((c = chop_match(name, op_table_underscore,
6586                         nelem(op_table_underscore))) < 0)
6587       {
6588       arg = Ustrchr(name, '_');
6589       if (arg != NULL) *arg = 0;
6590       c = chop_match(name, op_table_main, nelem(op_table_main));
6591       if (c >= 0) c += nelem(op_table_underscore);
6592       if (arg != NULL) *arg++ = '_';   /* Put back for error messages */
6593       }
6594
6595     /* Deal specially with operators that might take a certificate variable
6596     as we do not want to do the usual expansion. For most, expand the string.*/
6597     switch(c)
6598       {
6599 #ifdef SUPPORT_TLS
6600       case EOP_MD5:
6601       case EOP_SHA1:
6602       case EOP_SHA256:
6603       case EOP_BASE64:
6604         if (s[1] == '$')
6605           {
6606           const uschar * s1 = s;
6607           sub = expand_string_internal(s+2, TRUE, &s1, skipping,
6608                   FALSE, &resetok);
6609           if (!sub)       goto EXPAND_FAILED;           /*{*/
6610           if (*s1 != '}')
6611             {
6612             expand_string_message =
6613               string_sprintf("missing '}' closing cert arg of %s", name);
6614             goto EXPAND_FAILED_CURLY;
6615             }
6616           if ((vp = find_var_ent(sub)) && vp->type == vtype_cert)
6617             {
6618             s = s1+1;
6619             break;
6620             }
6621           vp = NULL;
6622           }
6623         /*FALLTHROUGH*/
6624 #endif
6625       default:
6626         sub = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok);
6627         if (!sub) goto EXPAND_FAILED;
6628         s++;
6629         break;
6630       }
6631
6632     /* If we are skipping, we don't need to perform the operation at all.
6633     This matters for operations like "mask", because the data may not be
6634     in the correct format when skipping. For example, the expression may test
6635     for the existence of $sender_host_address before trying to mask it. For
6636     other operations, doing them may not fail, but it is a waste of time. */
6637
6638     if (skipping && c >= 0) continue;
6639
6640     /* Otherwise, switch on the operator type */
6641
6642     switch(c)
6643       {
6644       case EOP_BASE32:
6645         {
6646         uschar *t;
6647         unsigned long int n = Ustrtoul(sub, &t, 10);
6648         gstring * g = NULL;
6649
6650         if (*t != 0)
6651           {
6652           expand_string_message = string_sprintf("argument for base32 "
6653             "operator is \"%s\", which is not a decimal number", sub);
6654           goto EXPAND_FAILED;
6655           }
6656         for ( ; n; n >>= 5)
6657           g = string_catn(g, &base32_chars[n & 0x1f], 1);
6658
6659         if (g) while (g->ptr > 0) yield = string_catn(yield, &g->s[--g->ptr], 1);
6660         continue;
6661         }
6662
6663       case EOP_BASE32D:
6664         {
6665         uschar *tt = sub;
6666         unsigned long int n = 0;
6667         uschar * s;
6668         while (*tt)
6669           {
6670           uschar * t = Ustrchr(base32_chars, *tt++);
6671           if (t == NULL)
6672             {
6673             expand_string_message = string_sprintf("argument for base32d "
6674               "operator is \"%s\", which is not a base 32 number", sub);
6675             goto EXPAND_FAILED;
6676             }
6677           n = n * 32 + (t - base32_chars);
6678           }
6679         s = string_sprintf("%ld", n);
6680         yield = string_cat(yield, s);
6681         continue;
6682         }
6683
6684       case EOP_BASE62:
6685         {
6686         uschar *t;
6687         unsigned long int n = Ustrtoul(sub, &t, 10);
6688         if (*t != 0)
6689           {
6690           expand_string_message = string_sprintf("argument for base62 "
6691             "operator is \"%s\", which is not a decimal number", sub);
6692           goto EXPAND_FAILED;
6693           }
6694         t = string_base62(n);
6695         yield = string_cat(yield, t);
6696         continue;
6697         }
6698
6699       /* Note that for Darwin and Cygwin, BASE_62 actually has the value 36 */
6700
6701       case EOP_BASE62D:
6702         {
6703         uschar *tt = sub;
6704         unsigned long int n = 0;
6705         while (*tt != 0)
6706           {
6707           uschar *t = Ustrchr(base62_chars, *tt++);
6708           if (t == NULL)
6709             {
6710             expand_string_message = string_sprintf("argument for base62d "
6711               "operator is \"%s\", which is not a base %d number", sub,
6712               BASE_62);
6713             goto EXPAND_FAILED;
6714             }
6715           n = n * BASE_62 + (t - base62_chars);
6716           }
6717         yield = string_fmt_append(yield, "%ld", n);
6718         continue;
6719         }
6720
6721       case EOP_EXPAND:
6722         {
6723         uschar *expanded = expand_string_internal(sub, FALSE, NULL, skipping, TRUE, &resetok);
6724         if (expanded == NULL)
6725           {
6726           expand_string_message =
6727             string_sprintf("internal expansion of \"%s\" failed: %s", sub,
6728               expand_string_message);
6729           goto EXPAND_FAILED;
6730           }
6731         yield = string_cat(yield, expanded);
6732         continue;
6733         }
6734
6735       case EOP_LC:
6736         {
6737         int count = 0;
6738         uschar *t = sub - 1;
6739         while (*(++t) != 0) { *t = tolower(*t); count++; }
6740         yield = string_catn(yield, sub, count);
6741         continue;
6742         }
6743
6744       case EOP_UC:
6745         {
6746         int count = 0;
6747         uschar *t = sub - 1;
6748         while (*(++t) != 0) { *t = toupper(*t); count++; }
6749         yield = string_catn(yield, sub, count);
6750         continue;
6751         }
6752
6753       case EOP_MD5:
6754 #ifdef SUPPORT_TLS
6755         if (vp && *(void **)vp->value)
6756           {
6757           uschar * cp = tls_cert_fprt_md5(*(void **)vp->value);
6758           yield = string_cat(yield, cp);
6759           }
6760         else
6761 #endif
6762           {
6763           md5 base;
6764           uschar digest[16];
6765           md5_start(&base);
6766           md5_end(&base, sub, Ustrlen(sub), digest);
6767           for (int j = 0; j < 16; j++)
6768             yield = string_fmt_append(yield, "%02x", digest[j]);
6769           }
6770         continue;
6771
6772       case EOP_SHA1:
6773 #ifdef SUPPORT_TLS
6774         if (vp && *(void **)vp->value)
6775           {
6776           uschar * cp = tls_cert_fprt_sha1(*(void **)vp->value);
6777           yield = string_cat(yield, cp);
6778           }
6779         else
6780 #endif
6781           {
6782           hctx h;
6783           uschar digest[20];
6784           sha1_start(&h);
6785           sha1_end(&h, sub, Ustrlen(sub), digest);
6786           for (int j = 0; j < 20; j++)
6787             yield = string_fmt_append(yield, "%02X", digest[j]);
6788           }
6789         continue;
6790
6791       case EOP_SHA256:
6792 #ifdef EXIM_HAVE_SHA2
6793         if (vp && *(void **)vp->value)
6794           {
6795           uschar * cp = tls_cert_fprt_sha256(*(void **)vp->value);
6796           yield = string_cat(yield, cp);
6797           }
6798         else
6799           {
6800           hctx h;
6801           blob b;
6802
6803           if (!exim_sha_init(&h, HASH_SHA2_256))
6804             {
6805             expand_string_message = US"unrecognised sha256 variant";
6806             goto EXPAND_FAILED;
6807             }
6808           exim_sha_update(&h, sub, Ustrlen(sub));
6809           exim_sha_finish(&h, &b);
6810           while (b.len-- > 0)
6811             yield = string_fmt_append(yield, "%02X", *b.data++);
6812           }
6813 #else
6814           expand_string_message = US"sha256 only supported with TLS";
6815 #endif
6816         continue;
6817
6818       case EOP_SHA3:
6819 #ifdef EXIM_HAVE_SHA3
6820         {
6821         hctx h;
6822         blob b;
6823         hashmethod m = !arg ? HASH_SHA3_256
6824           : Ustrcmp(arg, "224") == 0 ? HASH_SHA3_224
6825           : Ustrcmp(arg, "256") == 0 ? HASH_SHA3_256
6826           : Ustrcmp(arg, "384") == 0 ? HASH_SHA3_384
6827           : Ustrcmp(arg, "512") == 0 ? HASH_SHA3_512
6828           : HASH_BADTYPE;
6829
6830         if (m == HASH_BADTYPE || !exim_sha_init(&h, m))
6831           {
6832           expand_string_message = US"unrecognised sha3 variant";
6833           goto EXPAND_FAILED;
6834           }
6835
6836         exim_sha_update(&h, sub, Ustrlen(sub));
6837         exim_sha_finish(&h, &b);
6838         while (b.len-- > 0)
6839           yield = string_fmt_append(yield, "%02X", *b.data++);
6840         }
6841         continue;
6842 #else
6843         expand_string_message = US"sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 +";
6844         goto EXPAND_FAILED;
6845 #endif
6846
6847       /* Convert hex encoding to base64 encoding */
6848
6849       case EOP_HEX2B64:
6850         {
6851         int c = 0;
6852         int b = -1;
6853         uschar *in = sub;
6854         uschar *out = sub;
6855         uschar *enc;
6856
6857         for (enc = sub; *enc; enc++)
6858           {
6859           if (!isxdigit(*enc))
6860             {
6861             expand_string_message = string_sprintf("\"%s\" is not a hex "
6862               "string", sub);
6863             goto EXPAND_FAILED;
6864             }
6865           c++;
6866           }
6867
6868         if ((c & 1) != 0)
6869           {
6870           expand_string_message = string_sprintf("\"%s\" contains an odd "
6871             "number of characters", sub);
6872           goto EXPAND_FAILED;
6873           }
6874
6875         while ((c = *in++) != 0)
6876           {
6877           if (isdigit(c)) c -= '0';
6878           else c = toupper(c) - 'A' + 10;
6879           if (b == -1)
6880             b = c << 4;
6881           else
6882             {
6883             *out++ = b | c;
6884             b = -1;
6885             }
6886           }
6887
6888         enc = b64encode(CUS sub, out - sub);
6889         yield = string_cat(yield, enc);
6890         continue;
6891         }
6892
6893       /* Convert octets outside 0x21..0x7E to \xXX form */
6894
6895       case EOP_HEXQUOTE:
6896         {
6897         uschar *t = sub - 1;
6898         while (*(++t) != 0)
6899           {
6900           if (*t < 0x21 || 0x7E < *t)
6901             yield = string_fmt_append(yield, "\\x%02x", *t);
6902           else
6903             yield = string_catn(yield, t, 1);
6904           }
6905         continue;
6906         }
6907
6908       /* count the number of list elements */
6909
6910       case EOP_LISTCOUNT:
6911         {
6912         int cnt = 0;
6913         int sep = 0;
6914         uschar buffer[256];
6915
6916         while (string_nextinlist(CUSS &sub, &sep, buffer, sizeof(buffer)) != NULL) cnt++;
6917         yield = string_fmt_append(yield, "%d", cnt);
6918         continue;
6919         }
6920
6921       /* expand a named list given the name */
6922       /* handles nested named lists; requotes as colon-sep list */
6923
6924       case EOP_LISTNAMED:
6925         {
6926         tree_node *t = NULL;
6927         const uschar * list;
6928         int sep = 0;
6929         uschar * item;
6930         uschar * suffix = US"";
6931         BOOL needsep = FALSE;
6932         uschar buffer[256];
6933
6934         if (*sub == '+') sub++;
6935         if (arg == NULL)        /* no-argument version */
6936           {
6937           if (!(t = tree_search(addresslist_anchor, sub)) &&
6938               !(t = tree_search(domainlist_anchor,  sub)) &&
6939               !(t = tree_search(hostlist_anchor,    sub)))
6940             t = tree_search(localpartlist_anchor, sub);
6941           }
6942         else switch(*arg)       /* specific list-type version */
6943           {
6944           case 'a': t = tree_search(addresslist_anchor,   sub); suffix = US"_a"; break;
6945           case 'd': t = tree_search(domainlist_anchor,    sub); suffix = US"_d"; break;
6946           case 'h': t = tree_search(hostlist_anchor,      sub); suffix = US"_h"; break;
6947           case 'l': t = tree_search(localpartlist_anchor, sub); suffix = US"_l"; break;
6948           default:
6949             expand_string_message = string_sprintf("bad suffix on \"list\" operator");
6950             goto EXPAND_FAILED;
6951           }
6952
6953         if(!t)
6954           {
6955           expand_string_message = string_sprintf("\"%s\" is not a %snamed list",
6956             sub, !arg?""
6957               : *arg=='a'?"address "
6958               : *arg=='d'?"domain "
6959               : *arg=='h'?"host "
6960               : *arg=='l'?"localpart "
6961               : 0);
6962           goto EXPAND_FAILED;
6963           }
6964
6965         list = ((namedlist_block *)(t->data.ptr))->string;
6966
6967         while ((item = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
6968           {
6969           uschar * buf = US" : ";
6970           if (needsep)
6971             yield = string_catn(yield, buf, 3);
6972           else
6973             needsep = TRUE;
6974
6975           if (*item == '+')     /* list item is itself a named list */
6976             {
6977             uschar * sub = string_sprintf("${listnamed%s:%s}", suffix, item);
6978             item = expand_string_internal(sub, FALSE, NULL, FALSE, TRUE, &resetok);
6979             }
6980           else if (sep != ':')  /* item from non-colon-sep list, re-quote for colon list-separator */
6981             {
6982             char * cp;
6983             char tok[3];
6984             tok[0] = sep; tok[1] = ':'; tok[2] = 0;
6985             while ((cp= strpbrk(CCS item, tok)))
6986               {
6987               yield = string_catn(yield, item, cp - CS item);
6988               if (*cp++ == ':') /* colon in a non-colon-sep list item, needs doubling */
6989                 {
6990                 yield = string_catn(yield, US"::", 2);
6991                 item = US cp;
6992                 }
6993               else              /* sep in item; should already be doubled; emit once */
6994                 {
6995                 yield = string_catn(yield, US tok, 1);
6996                 if (*cp == sep) cp++;
6997                 item = US cp;
6998                 }
6999               }
7000             }
7001           yield = string_cat(yield, item);
7002           }
7003         continue;
7004         }
7005
7006       /* mask applies a mask to an IP address; for example the result of
7007       ${mask:131.111.10.206/28} is 131.111.10.192/28. */
7008
7009       case EOP_MASK:
7010         {
7011         int count;
7012         uschar *endptr;
7013         int binary[4];
7014         int mask, maskoffset;
7015         int type = string_is_ip_address(sub, &maskoffset);
7016         uschar buffer[64];
7017
7018         if (type == 0)
7019           {
7020           expand_string_message = string_sprintf("\"%s\" is not an IP address",
7021            sub);
7022           goto EXPAND_FAILED;
7023           }
7024
7025         if (maskoffset == 0)
7026           {
7027           expand_string_message = string_sprintf("missing mask value in \"%s\"",
7028             sub);
7029           goto EXPAND_FAILED;
7030           }
7031
7032         mask = Ustrtol(sub + maskoffset + 1, &endptr, 10);
7033
7034         if (*endptr != 0 || mask < 0 || mask > ((type == 4)? 32 : 128))
7035           {
7036           expand_string_message = string_sprintf("mask value too big in \"%s\"",
7037             sub);
7038           goto EXPAND_FAILED;
7039           }
7040
7041         /* Convert the address to binary integer(s) and apply the mask */
7042
7043         sub[maskoffset] = 0;
7044         count = host_aton(sub, binary);
7045         host_mask(count, binary, mask);
7046
7047         /* Convert to masked textual format and add to output. */
7048
7049         yield = string_catn(yield, buffer,
7050           host_nmtoa(count, binary, mask, buffer, '.'));
7051         continue;
7052         }
7053
7054       case EOP_IPV6NORM:
7055       case EOP_IPV6DENORM:
7056         {
7057         int type = string_is_ip_address(sub, NULL);
7058         int binary[4];
7059         uschar buffer[44];
7060
7061         switch (type)
7062           {
7063           case 6:
7064             (void) host_aton(sub, binary);
7065             break;
7066
7067           case 4:       /* convert to IPv4-mapped IPv6 */
7068             binary[0] = binary[1] = 0;
7069             binary[2] = 0x0000ffff;
7070             (void) host_aton(sub, binary+3);
7071             break;
7072
7073           case 0:
7074             expand_string_message =
7075               string_sprintf("\"%s\" is not an IP address", sub);
7076             goto EXPAND_FAILED;
7077           }
7078
7079         yield = string_catn(yield, buffer, c == EOP_IPV6NORM
7080                     ? ipv6_nmtoa(binary, buffer)
7081                     : host_nmtoa(4, binary, -1, buffer, ':')
7082                   );
7083         continue;
7084         }
7085
7086       case EOP_ADDRESS:
7087       case EOP_LOCAL_PART:
7088       case EOP_DOMAIN:
7089         {
7090         uschar * error;
7091         int start, end, domain;
7092         uschar * t = parse_extract_address(sub, &error, &start, &end, &domain,
7093           FALSE);
7094         if (t)
7095           if (c != EOP_DOMAIN)
7096             {
7097             if (c == EOP_LOCAL_PART && domain != 0) end = start + domain - 1;
7098             yield = string_catn(yield, sub+start, end-start);
7099             }
7100           else if (domain != 0)
7101             {
7102             domain += start;
7103             yield = string_catn(yield, sub+domain, end-domain);
7104             }
7105         continue;
7106         }
7107
7108       case EOP_ADDRESSES:
7109         {
7110         uschar outsep[2] = { ':', '\0' };
7111         uschar *address, *error;
7112         int save_ptr = yield->ptr;
7113         int start, end, domain;  /* Not really used */
7114
7115         while (isspace(*sub)) sub++;
7116         if (*sub == '>')
7117           if (*outsep = *++sub) ++sub;
7118           else
7119             {
7120             expand_string_message = string_sprintf("output separator "
7121               "missing in expanding ${addresses:%s}", --sub);
7122             goto EXPAND_FAILED;
7123             }
7124         f.parse_allow_group = TRUE;
7125
7126         for (;;)
7127           {
7128           uschar *p = parse_find_address_end(sub, FALSE);
7129           uschar saveend = *p;
7130           *p = '\0';
7131           address = parse_extract_address(sub, &error, &start, &end, &domain,
7132             FALSE);
7133           *p = saveend;
7134
7135           /* Add the address to the output list that we are building. This is
7136           done in chunks by searching for the separator character. At the
7137           start, unless we are dealing with the first address of the output
7138           list, add in a space if the new address begins with the separator
7139           character, or is an empty string. */
7140
7141           if (address != NULL)
7142             {
7143             if (yield->ptr != save_ptr && address[0] == *outsep)
7144               yield = string_catn(yield, US" ", 1);
7145
7146             for (;;)
7147               {
7148               size_t seglen = Ustrcspn(address, outsep);
7149               yield = string_catn(yield, address, seglen + 1);
7150
7151               /* If we got to the end of the string we output one character
7152               too many. */
7153
7154               if (address[seglen] == '\0') { yield->ptr--; break; }
7155               yield = string_catn(yield, outsep, 1);
7156               address += seglen + 1;
7157               }
7158
7159             /* Output a separator after the string: we will remove the
7160             redundant final one at the end. */
7161
7162             yield = string_catn(yield, outsep, 1);
7163             }
7164
7165           if (saveend == '\0') break;
7166           sub = p + 1;
7167           }
7168
7169         /* If we have generated anything, remove the redundant final
7170         separator. */
7171
7172         if (yield->ptr != save_ptr) yield->ptr--;
7173         f.parse_allow_group = FALSE;
7174         continue;
7175         }
7176
7177
7178       /* quote puts a string in quotes if it is empty or contains anything
7179       other than alphamerics, underscore, dot, or hyphen.
7180
7181       quote_local_part puts a string in quotes if RFC 2821/2822 requires it to
7182       be quoted in order to be a valid local part.
7183
7184       In both cases, newlines and carriage returns are converted into \n and \r
7185       respectively */
7186
7187       case EOP_QUOTE:
7188       case EOP_QUOTE_LOCAL_PART:
7189       if (arg == NULL)
7190         {
7191         BOOL needs_quote = (*sub == 0);      /* TRUE for empty string */
7192         uschar *t = sub - 1;
7193
7194         if (c == EOP_QUOTE)
7195           {
7196           while (!needs_quote && *(++t) != 0)
7197             needs_quote = !isalnum(*t) && !strchr("_-.", *t);
7198           }
7199         else  /* EOP_QUOTE_LOCAL_PART */
7200           {
7201           while (!needs_quote && *(++t) != 0)
7202             needs_quote = !isalnum(*t) &&
7203               strchr("!#$%&'*+-/=?^_`{|}~", *t) == NULL &&
7204               (*t != '.' || t == sub || t[1] == 0);
7205           }
7206
7207         if (needs_quote)
7208           {
7209           yield = string_catn(yield, US"\"", 1);
7210           t = sub - 1;
7211           while (*(++t) != 0)
7212             {
7213             if (*t == '\n')
7214               yield = string_catn(yield, US"\\n", 2);
7215             else if (*t == '\r')
7216               yield = string_catn(yield, US"\\r", 2);
7217             else
7218               {
7219               if (*t == '\\' || *t == '"')
7220                 yield = string_catn(yield, US"\\", 1);
7221               yield = string_catn(yield, t, 1);
7222               }
7223             }
7224           yield = string_catn(yield, US"\"", 1);
7225           }
7226         else yield = string_cat(yield, sub);
7227         continue;
7228         }
7229
7230       /* quote_lookuptype does lookup-specific quoting */
7231
7232       else
7233         {
7234         int n;
7235         uschar *opt = Ustrchr(arg, '_');
7236
7237         if (opt != NULL) *opt++ = 0;
7238
7239         n = search_findtype(arg, Ustrlen(arg));
7240         if (n < 0)
7241           {
7242           expand_string_message = search_error_message;
7243           goto EXPAND_FAILED;
7244           }
7245
7246         if (lookup_list[n]->quote != NULL)
7247           sub = (lookup_list[n]->quote)(sub, opt);
7248         else if (opt != NULL) sub = NULL;
7249
7250         if (sub == NULL)
7251           {
7252           expand_string_message = string_sprintf(
7253             "\"%s\" unrecognized after \"${quote_%s\"",
7254             opt, arg);
7255           goto EXPAND_FAILED;
7256           }
7257
7258         yield = string_cat(yield, sub);
7259         continue;
7260         }
7261
7262       /* rx quote sticks in \ before any non-alphameric character so that
7263       the insertion works in a regular expression. */
7264
7265       case EOP_RXQUOTE:
7266         {
7267         uschar *t = sub - 1;
7268         while (*(++t) != 0)
7269           {
7270           if (!isalnum(*t))
7271             yield = string_catn(yield, US"\\", 1);
7272           yield = string_catn(yield, t, 1);
7273           }
7274         continue;
7275         }
7276
7277       /* RFC 2047 encodes, assuming headers_charset (default ISO 8859-1) as
7278       prescribed by the RFC, if there are characters that need to be encoded */
7279
7280       case EOP_RFC2047:
7281         {
7282         uschar buffer[2048];
7283         yield = string_cat(yield,
7284                             parse_quote_2047(sub, Ustrlen(sub), headers_charset,
7285                               buffer, sizeof(buffer), FALSE));
7286         continue;
7287         }
7288
7289       /* RFC 2047 decode */
7290
7291       case EOP_RFC2047D:
7292         {
7293         int len;
7294         uschar *error;
7295         uschar *decoded = rfc2047_decode(sub, check_rfc2047_length,
7296           headers_charset, '?', &len, &error);
7297         if (error != NULL)
7298           {
7299           expand_string_message = error;
7300           goto EXPAND_FAILED;
7301           }
7302         yield = string_catn(yield, decoded, len);
7303         continue;
7304         }
7305
7306       /* from_utf8 converts UTF-8 to 8859-1, turning non-existent chars into
7307       underscores */
7308
7309       case EOP_FROM_UTF8:
7310         {
7311         while (*sub != 0)
7312           {
7313           int c;
7314           uschar buff[4];
7315           GETUTF8INC(c, sub);
7316           if (c > 255) c = '_';
7317           buff[0] = c;
7318           yield = string_catn(yield, buff, 1);
7319           }
7320         continue;
7321         }
7322
7323           /* replace illegal UTF-8 sequences by replacement character  */
7324
7325       #define UTF8_REPLACEMENT_CHAR US"?"
7326
7327       case EOP_UTF8CLEAN:
7328         {
7329         int seq_len = 0, index = 0;
7330         int bytes_left = 0;
7331         long codepoint = -1;
7332         int complete;
7333         uschar seq_buff[4];                     /* accumulate utf-8 here */
7334
7335         while (*sub != 0)
7336           {
7337           complete = 0;
7338           uschar c = *sub++;
7339
7340           if (bytes_left)
7341             {
7342             if ((c & 0xc0) != 0x80)
7343                     /* wrong continuation byte; invalidate all bytes */
7344               complete = 1; /* error */
7345             else
7346               {
7347               codepoint = (codepoint << 6) | (c & 0x3f);
7348               seq_buff[index++] = c;
7349               if (--bytes_left == 0)            /* codepoint complete */
7350                 if(codepoint > 0x10FFFF)        /* is it too large? */
7351                   complete = -1;        /* error (RFC3629 limit) */
7352                 else
7353                   {             /* finished; output utf-8 sequence */
7354                   yield = string_catn(yield, seq_buff, seq_len);
7355                   index = 0;
7356                   }
7357               }
7358             }
7359           else  /* no bytes left: new sequence */
7360             {
7361             if((c & 0x80) == 0) /* 1-byte sequence, US-ASCII, keep it */
7362               {
7363               yield = string_catn(yield, &c, 1);
7364               continue;
7365               }
7366             if((c & 0xe0) == 0xc0)              /* 2-byte sequence */
7367               {
7368               if(c == 0xc0 || c == 0xc1)        /* 0xc0 and 0xc1 are illegal */
7369                 complete = -1;
7370               else
7371                 {
7372                   bytes_left = 1;
7373                   codepoint = c & 0x1f;
7374                 }
7375               }
7376             else if((c & 0xf0) == 0xe0)         /* 3-byte sequence */
7377               {
7378               bytes_left = 2;
7379               codepoint = c & 0x0f;
7380               }
7381             else if((c & 0xf8) == 0xf0)         /* 4-byte sequence */
7382               {
7383               bytes_left = 3;
7384               codepoint = c & 0x07;
7385               }
7386             else        /* invalid or too long (RFC3629 allows only 4 bytes) */
7387               complete = -1;
7388
7389             seq_buff[index++] = c;
7390             seq_len = bytes_left + 1;
7391             }           /* if(bytes_left) */
7392
7393           if (complete != 0)
7394             {
7395             bytes_left = index = 0;
7396             yield = string_catn(yield, UTF8_REPLACEMENT_CHAR, 1);
7397             }
7398           if ((complete == 1) && ((c & 0x80) == 0))
7399                         /* ASCII character follows incomplete sequence */
7400               yield = string_catn(yield, &c, 1);
7401           }
7402         /* If given a sequence truncated mid-character, we also want to report ?
7403         * Eg, ${length_1:フィル} is one byte, not one character, so we expect
7404         * ${utf8clean:${length_1:フィル}} to yield '?' */
7405         if (bytes_left != 0)
7406           {
7407           yield = string_catn(yield, UTF8_REPLACEMENT_CHAR, 1);
7408           }
7409         continue;
7410         }
7411
7412 #ifdef SUPPORT_I18N
7413       case EOP_UTF8_DOMAIN_TO_ALABEL:
7414         {
7415         uschar * error = NULL;
7416         uschar * s = string_domain_utf8_to_alabel(sub, &error);
7417         if (error)
7418           {
7419           expand_string_message = string_sprintf(
7420             "error converting utf8 (%s) to alabel: %s",
7421             string_printing(sub), error);
7422           goto EXPAND_FAILED;
7423           }
7424         yield = string_cat(yield, s);
7425         continue;
7426         }
7427
7428       case EOP_UTF8_DOMAIN_FROM_ALABEL:
7429         {
7430         uschar * error = NULL;
7431         uschar * s = string_domain_alabel_to_utf8(sub, &error);
7432         if (error)
7433           {
7434           expand_string_message = string_sprintf(
7435             "error converting alabel (%s) to utf8: %s",
7436             string_printing(sub), error);
7437           goto EXPAND_FAILED;
7438           }
7439         yield = string_cat(yield, s);
7440         continue;
7441         }
7442
7443       case EOP_UTF8_LOCALPART_TO_ALABEL:
7444         {
7445         uschar * error = NULL;
7446         uschar * s = string_localpart_utf8_to_alabel(sub, &error);
7447         if (error)
7448           {
7449           expand_string_message = string_sprintf(
7450             "error converting utf8 (%s) to alabel: %s",
7451             string_printing(sub), error);
7452           goto EXPAND_FAILED;
7453           }
7454         yield = string_cat(yield, s);
7455         DEBUG(D_expand) debug_printf_indent("yield: '%s'\n", yield->s);
7456         continue;
7457         }
7458
7459       case EOP_UTF8_LOCALPART_FROM_ALABEL:
7460         {
7461         uschar * error = NULL;
7462         uschar * s = string_localpart_alabel_to_utf8(sub, &error);
7463         if (error)
7464           {
7465           expand_string_message = string_sprintf(
7466             "error converting alabel (%s) to utf8: %s",
7467             string_printing(sub), error);
7468           goto EXPAND_FAILED;
7469           }
7470         yield = string_cat(yield, s);
7471         continue;
7472         }
7473 #endif  /* EXPERIMENTAL_INTERNATIONAL */
7474
7475       /* escape turns all non-printing characters into escape sequences. */
7476
7477       case EOP_ESCAPE:
7478         {
7479         const uschar * t = string_printing(sub);
7480         yield = string_cat(yield, t);
7481         continue;
7482         }
7483
7484       case EOP_ESCAPE8BIT:
7485         {
7486         uschar c;
7487
7488         for (const uschar * s = sub; (c = *s); s++)
7489           yield = c < 127 && c != '\\'
7490             ? string_catn(yield, s, 1)
7491             : string_fmt_append(yield, "\\%03o", c);
7492         continue;
7493         }
7494
7495       /* Handle numeric expression evaluation */
7496
7497       case EOP_EVAL:
7498       case EOP_EVAL10:
7499         {
7500         uschar *save_sub = sub;
7501         uschar *error = NULL;
7502         int_eximarith_t n = eval_expr(&sub, (c == EOP_EVAL10), &error, FALSE);
7503         if (error)
7504           {
7505           expand_string_message = string_sprintf("error in expression "
7506             "evaluation: %s (after processing \"%.*s\")", error,
7507             (int)(sub-save_sub), save_sub);
7508           goto EXPAND_FAILED;
7509           }
7510         yield = string_fmt_append(yield, PR_EXIM_ARITH, n);
7511         continue;
7512         }
7513
7514       /* Handle time period formating */
7515
7516       case EOP_TIME_EVAL:
7517         {
7518         int n = readconf_readtime(sub, 0, FALSE);
7519         if (n < 0)
7520           {
7521           expand_string_message = string_sprintf("string \"%s\" is not an "
7522             "Exim time interval in \"%s\" operator", sub, name);
7523           goto EXPAND_FAILED;
7524           }
7525         yield = string_fmt_append(yield, "%d", n);
7526         continue;
7527         }
7528
7529       case EOP_TIME_INTERVAL:
7530         {
7531         int n;
7532         uschar *t = read_number(&n, sub);
7533         if (*t != 0) /* Not A Number*/
7534           {
7535           expand_string_message = string_sprintf("string \"%s\" is not a "
7536             "positive number in \"%s\" operator", sub, name);
7537           goto EXPAND_FAILED;
7538           }
7539         t = readconf_printtime(n);
7540         yield = string_cat(yield, t);
7541         continue;
7542         }
7543
7544       /* Convert string to base64 encoding */
7545
7546       case EOP_STR2B64:
7547       case EOP_BASE64:
7548         {
7549 #ifdef SUPPORT_TLS
7550         uschar * s = vp && *(void **)vp->value
7551           ? tls_cert_der_b64(*(void **)vp->value)
7552           : b64encode(CUS sub, Ustrlen(sub));
7553 #else
7554         uschar * s = b64encode(CUS sub, Ustrlen(sub));
7555 #endif
7556         yield = string_cat(yield, s);
7557         continue;
7558         }
7559
7560       case EOP_BASE64D:
7561         {
7562         uschar * s;
7563         int len = b64decode(sub, &s);
7564         if (len < 0)
7565           {
7566           expand_string_message = string_sprintf("string \"%s\" is not "
7567             "well-formed for \"%s\" operator", sub, name);
7568           goto EXPAND_FAILED;
7569           }
7570         yield = string_cat(yield, s);
7571         continue;
7572         }
7573
7574       /* strlen returns the length of the string */
7575
7576       case EOP_STRLEN:
7577         yield = string_fmt_append(yield, "%d", Ustrlen(sub));
7578         continue;
7579
7580       /* length_n or l_n takes just the first n characters or the whole string,
7581       whichever is the shorter;
7582
7583       substr_m_n, and s_m_n take n characters from offset m; negative m take
7584       from the end; l_n is synonymous with s_0_n. If n is omitted in substr it
7585       takes the rest, either to the right or to the left.
7586
7587       hash_n or h_n makes a hash of length n from the string, yielding n
7588       characters from the set a-z; hash_n_m makes a hash of length n, but
7589       uses m characters from the set a-zA-Z0-9.
7590
7591       nhash_n returns a single number between 0 and n-1 (in text form), while
7592       nhash_n_m returns a div/mod hash as two numbers "a/b". The first lies
7593       between 0 and n-1 and the second between 0 and m-1. */
7594
7595       case EOP_LENGTH:
7596       case EOP_L:
7597       case EOP_SUBSTR:
7598       case EOP_S:
7599       case EOP_HASH:
7600       case EOP_H:
7601       case EOP_NHASH:
7602       case EOP_NH:
7603         {
7604         int sign = 1;
7605         int value1 = 0;
7606         int value2 = -1;
7607         int *pn;
7608         int len;
7609         uschar *ret;
7610
7611         if (!arg)
7612           {
7613           expand_string_message = string_sprintf("missing values after %s",
7614             name);
7615           goto EXPAND_FAILED;
7616           }
7617
7618         /* "length" has only one argument, effectively being synonymous with
7619         substr_0_n. */
7620
7621         if (c == EOP_LENGTH || c == EOP_L)
7622           {
7623           pn = &value2;
7624           value2 = 0;
7625           }
7626
7627         /* The others have one or two arguments; for "substr" the first may be
7628         negative. The second being negative means "not supplied". */
7629
7630         else
7631           {
7632           pn = &value1;
7633           if (name[0] == 's' && *arg == '-') { sign = -1; arg++; }
7634           }
7635
7636         /* Read up to two numbers, separated by underscores */
7637
7638         ret = arg;
7639         while (*arg != 0)
7640           {
7641           if (arg != ret && *arg == '_' && pn == &value1)
7642             {
7643             pn = &value2;
7644             value2 = 0;
7645             if (arg[1] != 0) arg++;
7646             }
7647           else if (!isdigit(*arg))
7648             {
7649             expand_string_message =
7650               string_sprintf("non-digit after underscore in \"%s\"", name);
7651             goto EXPAND_FAILED;
7652             }
7653           else *pn = (*pn)*10 + *arg++ - '0';
7654           }
7655         value1 *= sign;
7656
7657         /* Perform the required operation */
7658
7659         ret =
7660           (c == EOP_HASH || c == EOP_H)?
7661              compute_hash(sub, value1, value2, &len) :
7662           (c == EOP_NHASH || c == EOP_NH)?
7663              compute_nhash(sub, value1, value2, &len) :
7664              extract_substr(sub, value1, value2, &len);
7665
7666         if (ret == NULL) goto EXPAND_FAILED;
7667         yield = string_catn(yield, ret, len);
7668         continue;
7669         }
7670
7671       /* Stat a path */
7672
7673       case EOP_STAT:
7674         {
7675         uschar smode[12];
7676         uschar **modetable[3];
7677         mode_t mode;
7678         struct stat st;
7679
7680         if (expand_forbid & RDO_EXISTS)
7681           {
7682           expand_string_message = US"Use of the stat() expansion is not permitted";
7683           goto EXPAND_FAILED;
7684           }
7685
7686         if (stat(CS sub, &st) < 0)
7687           {
7688           expand_string_message = string_sprintf("stat(%s) failed: %s",
7689             sub, strerror(errno));
7690           goto EXPAND_FAILED;
7691           }
7692         mode = st.st_mode;
7693         switch (mode & S_IFMT)
7694           {
7695           case S_IFIFO: smode[0] = 'p'; break;
7696           case S_IFCHR: smode[0] = 'c'; break;
7697           case S_IFDIR: smode[0] = 'd'; break;
7698           case S_IFBLK: smode[0] = 'b'; break;
7699           case S_IFREG: smode[0] = '-'; break;
7700           default: smode[0] = '?'; break;
7701           }
7702
7703         modetable[0] = ((mode & 01000) == 0)? mtable_normal : mtable_sticky;
7704         modetable[1] = ((mode & 02000) == 0)? mtable_normal : mtable_setid;
7705         modetable[2] = ((mode & 04000) == 0)? mtable_normal : mtable_setid;
7706
7707         for (int i = 0; i < 3; i++)
7708           {
7709           memcpy(CS(smode + 7 - i*3), CS(modetable[i][mode & 7]), 3);
7710           mode >>= 3;
7711           }
7712
7713         smode[10] = 0;
7714         yield = string_fmt_append(yield,
7715           "mode=%04lo smode=%s inode=%ld device=%ld links=%ld "
7716           "uid=%ld gid=%ld size=" OFF_T_FMT " atime=%ld mtime=%ld ctime=%ld",
7717           (long)(st.st_mode & 077777), smode, (long)st.st_ino,
7718           (long)st.st_dev, (long)st.st_nlink, (long)st.st_uid,
7719           (long)st.st_gid, st.st_size, (long)st.st_atime,
7720           (long)st.st_mtime, (long)st.st_ctime);
7721         continue;
7722         }
7723
7724       /* vaguely random number less than N */
7725
7726       case EOP_RANDINT:
7727         {
7728         int_eximarith_t max = expanded_string_integer(sub, TRUE);
7729
7730         if (expand_string_message)
7731           goto EXPAND_FAILED;
7732         yield = string_fmt_append(yield, "%d", vaguely_random_number((int)max));
7733         continue;
7734         }
7735
7736       /* Reverse IP, including IPv6 to dotted-nibble */
7737
7738       case EOP_REVERSE_IP:
7739         {
7740         int family, maskptr;
7741         uschar reversed[128];
7742
7743         family = string_is_ip_address(sub, &maskptr);
7744         if (family == 0)
7745           {
7746           expand_string_message = string_sprintf(
7747               "reverse_ip() not given an IP address [%s]", sub);
7748           goto EXPAND_FAILED;
7749           }
7750         invert_address(reversed, sub);
7751         yield = string_cat(yield, reversed);
7752         continue;
7753         }
7754
7755       /* Unknown operator */
7756
7757       default:
7758         expand_string_message =
7759           string_sprintf("unknown expansion operator \"%s\"", name);
7760         goto EXPAND_FAILED;
7761       }
7762     }
7763
7764   /* Handle a plain name. If this is the first thing in the expansion, release
7765   the pre-allocated buffer. If the result data is known to be in a new buffer,
7766   newsize will be set to the size of that buffer, and we can just point at that
7767   store instead of copying. Many expansion strings contain just one reference,
7768   so this is a useful optimization, especially for humungous headers
7769   ($message_headers). */
7770                                                 /*{*/
7771   if (*s++ == '}')
7772     {
7773     int len;
7774     int newsize = 0;
7775     gstring * g = NULL;
7776
7777     if (!yield)
7778       g = store_get(sizeof(gstring));
7779     else if (yield->ptr == 0)
7780       {
7781       if (resetok) store_reset(yield);
7782       yield = NULL;
7783       g = store_get(sizeof(gstring));   /* alloc _before_ calling find_variable() */
7784       }
7785     if (!(value = find_variable(name, FALSE, skipping, &newsize)))
7786       {
7787       expand_string_message =
7788         string_sprintf("unknown variable in \"${%s}\"", name);
7789       check_variable_error_message(name);
7790       goto EXPAND_FAILED;
7791       }
7792     len = Ustrlen(value);
7793     if (!yield && newsize)
7794       {
7795       yield = g;
7796       yield->size = newsize;
7797       yield->ptr = len;
7798       yield->s = value;
7799       }
7800     else
7801       yield = string_catn(yield, value, len);
7802     continue;
7803     }
7804
7805   /* Else there's something wrong */
7806
7807   expand_string_message =
7808     string_sprintf("\"${%s\" is not a known operator (or a } is missing "
7809     "in a variable reference)", name);
7810   goto EXPAND_FAILED;
7811   }
7812
7813 /* If we hit the end of the string when ket_ends is set, there is a missing
7814 terminating brace. */
7815
7816 if (ket_ends && *s == 0)
7817   {
7818   expand_string_message = malformed_header
7819     ? US"missing } at end of string - could be header name not terminated by colon"
7820     : US"missing } at end of string";
7821   goto EXPAND_FAILED;
7822   }
7823
7824 /* Expansion succeeded; yield may still be NULL here if nothing was actually
7825 added to the string. If so, set up an empty string. Add a terminating zero. If
7826 left != NULL, return a pointer to the terminator. */
7827
7828 if (!yield)
7829   yield = string_get(1);
7830 (void) string_from_gstring(yield);
7831 if (left) *left = s;
7832
7833 /* Any stacking store that was used above the final string is no longer needed.
7834 In many cases the final string will be the first one that was got and so there
7835 will be optimal store usage. */
7836
7837 if (resetok) store_reset(yield->s + (yield->size = yield->ptr + 1));
7838 else if (resetok_p) *resetok_p = FALSE;
7839
7840 DEBUG(D_expand)
7841   DEBUG(D_noutf8)
7842     {
7843     debug_printf_indent("|--expanding: %.*s\n", (int)(s - string), string);
7844     debug_printf_indent("%sresult: %s\n",
7845       skipping ? "|-----" : "\\_____", yield->s);
7846     if (skipping)
7847       debug_printf_indent("\\___skipping: result is not used\n");
7848     }
7849   else
7850     {
7851     debug_printf_indent(UTF8_VERT_RIGHT UTF8_HORIZ UTF8_HORIZ
7852       "expanding: %.*s\n",
7853       (int)(s - string), string);
7854     debug_printf_indent("%s"
7855       UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ
7856       "result: %s\n",
7857       skipping ? UTF8_VERT_RIGHT : UTF8_UP_RIGHT,
7858       yield->s);
7859     if (skipping)
7860       debug_printf_indent(UTF8_UP_RIGHT UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ
7861         "skipping: result is not used\n");
7862     }
7863 expand_level--;
7864 return yield->s;
7865
7866 /* This is the failure exit: easiest to program with a goto. We still need
7867 to update the pointer to the terminator, for cases of nested calls with "fail".
7868 */
7869
7870 EXPAND_FAILED_CURLY:
7871 if (malformed_header)
7872   expand_string_message =
7873     US"missing or misplaced { or } - could be header name not terminated by colon";
7874
7875 else if (!expand_string_message || !*expand_string_message)
7876   expand_string_message = US"missing or misplaced { or }";
7877
7878 /* At one point, Exim reset the store to yield (if yield was not NULL), but
7879 that is a bad idea, because expand_string_message is in dynamic store. */
7880
7881 EXPAND_FAILED:
7882 if (left) *left = s;
7883 DEBUG(D_expand)
7884   DEBUG(D_noutf8)
7885     {
7886     debug_printf_indent("|failed to expand: %s\n", string);
7887     debug_printf_indent("%serror message: %s\n",
7888       f.expand_string_forcedfail ? "|---" : "\\___", expand_string_message);
7889     if (f.expand_string_forcedfail)
7890       debug_printf_indent("\\failure was forced\n");
7891     }
7892   else
7893     {
7894     debug_printf_indent(UTF8_VERT_RIGHT "failed to expand: %s\n",
7895       string);
7896     debug_printf_indent("%s" UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ
7897       "error message: %s\n",
7898       f.expand_string_forcedfail ? UTF8_VERT_RIGHT : UTF8_UP_RIGHT,
7899       expand_string_message);
7900     if (f.expand_string_forcedfail)
7901       debug_printf_indent(UTF8_UP_RIGHT "failure was forced\n");
7902     }
7903 if (resetok_p && !resetok) *resetok_p = FALSE;
7904 expand_level--;
7905 return NULL;
7906 }
7907
7908
7909 /* This is the external function call. Do a quick check for any expansion
7910 metacharacters, and if there are none, just return the input string.
7911
7912 Argument: the string to be expanded
7913 Returns:  the expanded string, or NULL if expansion failed; if failure was
7914           due to a lookup deferring, search_find_defer will be TRUE
7915 */
7916
7917 const uschar *
7918 expand_cstring(const uschar * string)
7919 {
7920 if (Ustrpbrk(string, "$\\") != NULL)
7921   {
7922   int old_pool = store_pool;
7923   uschar * s;
7924
7925   f.search_find_defer = FALSE;
7926   malformed_header = FALSE;
7927   store_pool = POOL_MAIN;
7928     s = expand_string_internal(string, FALSE, NULL, FALSE, TRUE, NULL);
7929   store_pool = old_pool;
7930   return s;
7931   }
7932 return string;
7933 }
7934
7935
7936 uschar *
7937 expand_string(uschar * string)
7938 {
7939 return US expand_cstring(CUS string);
7940 }
7941
7942
7943
7944
7945
7946 /*************************************************
7947 *              Expand and copy                   *
7948 *************************************************/
7949
7950 /* Now and again we want to expand a string and be sure that the result is in a
7951 new bit of store. This function does that.
7952 Since we know it has been copied, the de-const cast is safe.
7953
7954 Argument: the string to be expanded
7955 Returns:  the expanded string, always in a new bit of store, or NULL
7956 */
7957
7958 uschar *
7959 expand_string_copy(const uschar *string)
7960 {
7961 const uschar *yield = expand_cstring(string);
7962 if (yield == string) yield = string_copy(string);
7963 return US yield;
7964 }
7965
7966
7967
7968 /*************************************************
7969 *        Expand and interpret as an integer      *
7970 *************************************************/
7971
7972 /* Expand a string, and convert the result into an integer.
7973
7974 Arguments:
7975   string  the string to be expanded
7976   isplus  TRUE if a non-negative number is expected
7977
7978 Returns:  the integer value, or
7979           -1 for an expansion error               ) in both cases, message in
7980           -2 for an integer interpretation error  ) expand_string_message
7981           expand_string_message is set NULL for an OK integer
7982 */
7983
7984 int_eximarith_t
7985 expand_string_integer(uschar *string, BOOL isplus)
7986 {
7987 return expanded_string_integer(expand_string(string), isplus);
7988 }
7989
7990
7991 /*************************************************
7992  *         Interpret string as an integer        *
7993  *************************************************/
7994
7995 /* Convert a string (that has already been expanded) into an integer.
7996
7997 This function is used inside the expansion code.
7998
7999 Arguments:
8000   s       the string to be expanded
8001   isplus  TRUE if a non-negative number is expected
8002
8003 Returns:  the integer value, or
8004           -1 if string is NULL (which implies an expansion error)
8005           -2 for an integer interpretation error
8006           expand_string_message is set NULL for an OK integer
8007 */
8008
8009 static int_eximarith_t
8010 expanded_string_integer(const uschar *s, BOOL isplus)
8011 {
8012 int_eximarith_t value;
8013 uschar *msg = US"invalid integer \"%s\"";
8014 uschar *endptr;
8015
8016 /* If expansion failed, expand_string_message will be set. */
8017
8018 if (s == NULL) return -1;
8019
8020 /* On an overflow, strtol() returns LONG_MAX or LONG_MIN, and sets errno
8021 to ERANGE. When there isn't an overflow, errno is not changed, at least on some
8022 systems, so we set it zero ourselves. */
8023
8024 errno = 0;
8025 expand_string_message = NULL;               /* Indicates no error */
8026
8027 /* Before Exim 4.64, strings consisting entirely of whitespace compared
8028 equal to 0.  Unfortunately, people actually relied upon that, so preserve
8029 the behaviour explicitly.  Stripping leading whitespace is a harmless
8030 noop change since strtol skips it anyway (provided that there is a number
8031 to find at all). */
8032 if (isspace(*s))
8033   {
8034   while (isspace(*s)) ++s;
8035   if (*s == '\0')
8036     {
8037       DEBUG(D_expand)
8038        debug_printf_indent("treating blank string as number 0\n");
8039       return 0;
8040     }
8041   }
8042
8043 value = strtoll(CS s, CSS &endptr, 10);
8044
8045 if (endptr == s)
8046   {
8047   msg = US"integer expected but \"%s\" found";
8048   }
8049 else if (value < 0 && isplus)
8050   {
8051   msg = US"non-negative integer expected but \"%s\" found";
8052   }
8053 else
8054   {
8055   switch (tolower(*endptr))
8056     {
8057     default:
8058       break;
8059     case 'k':
8060       if (value > EXIM_ARITH_MAX/1024 || value < EXIM_ARITH_MIN/1024) errno = ERANGE;
8061       else value *= 1024;
8062       endptr++;
8063       break;
8064     case 'm':
8065       if (value > EXIM_ARITH_MAX/(1024*1024) || value < EXIM_ARITH_MIN/(1024*1024)) errno = ERANGE;
8066       else value *= 1024*1024;
8067       endptr++;
8068       break;
8069     case 'g':
8070       if (value > EXIM_ARITH_MAX/(1024*1024*1024) || value < EXIM_ARITH_MIN/(1024*1024*1024)) errno = ERANGE;
8071       else value *= 1024*1024*1024;
8072       endptr++;
8073       break;
8074     }
8075   if (errno == ERANGE)
8076     msg = US"absolute value of integer \"%s\" is too large (overflow)";
8077   else
8078     {
8079     while (isspace(*endptr)) endptr++;
8080     if (*endptr == 0) return value;
8081     }
8082   }
8083
8084 expand_string_message = string_sprintf(CS msg, s);
8085 return -2;
8086 }
8087
8088
8089 /* These values are usually fixed boolean values, but they are permitted to be
8090 expanded strings.
8091
8092 Arguments:
8093   addr       address being routed
8094   mtype      the module type
8095   mname      the module name
8096   dbg_opt    debug selectors
8097   oname      the option name
8098   bvalue     the router's boolean value
8099   svalue     the router's string value
8100   rvalue     where to put the returned value
8101
8102 Returns:     OK     value placed in rvalue
8103              DEFER  expansion failed
8104 */
8105
8106 int
8107 exp_bool(address_item *addr,
8108   uschar *mtype, uschar *mname, unsigned dbg_opt,
8109   uschar *oname, BOOL bvalue,
8110   uschar *svalue, BOOL *rvalue)
8111 {
8112 uschar *expanded;
8113 if (svalue == NULL) { *rvalue = bvalue; return OK; }
8114
8115 expanded = expand_string(svalue);
8116 if (expanded == NULL)
8117   {
8118   if (f.expand_string_forcedfail)
8119     {
8120     DEBUG(dbg_opt) debug_printf("expansion of \"%s\" forced failure\n", oname);
8121     *rvalue = bvalue;
8122     return OK;
8123     }
8124   addr->message = string_sprintf("failed to expand \"%s\" in %s %s: %s",
8125       oname, mname, mtype, expand_string_message);
8126   DEBUG(dbg_opt) debug_printf("%s\n", addr->message);
8127   return DEFER;
8128   }
8129
8130 DEBUG(dbg_opt) debug_printf("expansion of \"%s\" yields \"%s\"\n", oname,
8131   expanded);
8132
8133 if (strcmpic(expanded, US"true") == 0 || strcmpic(expanded, US"yes") == 0)
8134   *rvalue = TRUE;
8135 else if (strcmpic(expanded, US"false") == 0 || strcmpic(expanded, US"no") == 0)
8136   *rvalue = FALSE;
8137 else
8138   {
8139   addr->message = string_sprintf("\"%s\" is not a valid value for the "
8140     "\"%s\" option in the %s %s", expanded, oname, mname, mtype);
8141   return DEFER;
8142   }
8143
8144 return OK;
8145 }
8146
8147
8148
8149 /* Avoid potentially exposing a password in a string about to be logged */
8150
8151 uschar *
8152 expand_hide_passwords(uschar * s)
8153 {
8154 return (  (  Ustrstr(s, "failed to expand") != NULL
8155           || Ustrstr(s, "expansion of ")    != NULL
8156           )
8157        && (  Ustrstr(s, "mysql")   != NULL
8158           || Ustrstr(s, "pgsql")   != NULL
8159           || Ustrstr(s, "redis")   != NULL
8160           || Ustrstr(s, "sqlite")  != NULL
8161           || Ustrstr(s, "ldap:")   != NULL
8162           || Ustrstr(s, "ldaps:")  != NULL
8163           || Ustrstr(s, "ldapi:")  != NULL
8164           || Ustrstr(s, "ldapdn:") != NULL
8165           || Ustrstr(s, "ldapm:")  != NULL
8166        )  )
8167   ? US"Temporary internal error" : s;
8168 }
8169
8170
8171 /* Read given named file into big_buffer.  Use for keying material etc.
8172 The content will have an ascii NUL appended.
8173
8174 Arguments:
8175  filename       as it says
8176
8177 Return:  pointer to buffer, or NULL on error.
8178 */
8179
8180 uschar *
8181 expand_file_big_buffer(const uschar * filename)
8182 {
8183 int fd, off = 0, len;
8184
8185 if ((fd = open(CS filename, O_RDONLY)) < 0)
8186   {
8187   log_write(0, LOG_MAIN | LOG_PANIC, "unable to open file for reading: %s",
8188              filename);
8189   return NULL;
8190   }
8191
8192 do
8193   {
8194   if ((len = read(fd, big_buffer + off, big_buffer_size - 2 - off)) < 0)
8195     {
8196     (void) close(fd);
8197     log_write(0, LOG_MAIN|LOG_PANIC, "unable to read file: %s", filename);
8198     return NULL;
8199     }
8200   off += len;
8201   }
8202 while (len > 0);
8203
8204 (void) close(fd);
8205 big_buffer[off] = '\0';
8206 return big_buffer;
8207 }
8208
8209
8210
8211 /*************************************************
8212 * Error-checking for testsuite                   *
8213 *************************************************/
8214 typedef struct {
8215   uschar *      region_start;
8216   uschar *      region_end;
8217   const uschar *var_name;
8218   const uschar *var_data;
8219 } err_ctx;
8220
8221 static void
8222 assert_variable_notin(uschar * var_name, uschar * var_data, void * ctx)
8223 {
8224 err_ctx * e = ctx;
8225 if (var_data >= e->region_start  &&  var_data < e->region_end)
8226   {
8227   e->var_name = CUS var_name;
8228   e->var_data = CUS var_data;
8229   }
8230 }
8231
8232 void
8233 assert_no_variables(void * ptr, int len, const char * filename, int linenumber)
8234 {
8235 err_ctx e = { .region_start = ptr, .region_end = US ptr + len,
8236               .var_name = NULL, .var_data = NULL };
8237
8238 /* check acl_ variables */
8239 tree_walk(acl_var_c, assert_variable_notin, &e);
8240 tree_walk(acl_var_m, assert_variable_notin, &e);
8241
8242 /* check auth<n> variables */
8243 for (int i = 0; i < AUTH_VARS; i++) if (auth_vars[i])
8244   assert_variable_notin(US"auth<n>", auth_vars[i], &e);
8245
8246 /* check regex<n> variables */
8247 for (int i = 0; i < REGEX_VARS; i++) if (regex_vars[i])
8248   assert_variable_notin(US"regex<n>", regex_vars[i], &e);
8249
8250 /* check known-name variables */
8251 for (var_entry * v = var_table; v < var_table + var_table_size; v++)
8252   if (v->type == vtype_stringptr)
8253     assert_variable_notin(US v->name, *(USS v->value), &e);
8254
8255 /* check dns and address trees */
8256 tree_walk(tree_dns_fails,     assert_variable_notin, &e);
8257 tree_walk(tree_duplicates,    assert_variable_notin, &e);
8258 tree_walk(tree_nonrecipients, assert_variable_notin, &e);
8259 tree_walk(tree_unusable,      assert_variable_notin, &e);
8260
8261 if (e.var_name)
8262   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
8263     "live variable '%s' destroyed by reset_store at %s:%d\n- value '%.64s'",
8264     e.var_name, filename, linenumber, e.var_data);
8265 }
8266
8267
8268
8269 /*************************************************
8270 **************************************************
8271 *             Stand-alone test program           *
8272 **************************************************
8273 *************************************************/
8274
8275 #ifdef STAND_ALONE
8276
8277
8278 BOOL
8279 regex_match_and_setup(const pcre *re, uschar *subject, int options, int setup)
8280 {
8281 int ovector[3*(EXPAND_MAXN+1)];
8282 int n = pcre_exec(re, NULL, subject, Ustrlen(subject), 0, PCRE_EOPT|options,
8283   ovector, nelem(ovector));
8284 BOOL yield = n >= 0;
8285 if (n == 0) n = EXPAND_MAXN + 1;
8286 if (yield)
8287   {
8288   expand_nmax = setup < 0 ? 0 : setup + 1;
8289   for (int nn = setup < 0 ? 0 : 2; nn < n*2; nn += 2)
8290     {
8291     expand_nstring[expand_nmax] = subject + ovector[nn];
8292     expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
8293     }
8294   expand_nmax--;
8295   }
8296 return yield;
8297 }
8298
8299
8300 int main(int argc, uschar **argv)
8301 {
8302 uschar buffer[1024];
8303
8304 debug_selector = D_v;
8305 debug_file = stderr;
8306 debug_fd = fileno(debug_file);
8307 big_buffer = malloc(big_buffer_size);
8308
8309 for (int i = 1; i < argc; i++)
8310   {
8311   if (argv[i][0] == '+')
8312     {
8313     debug_trace_memory = 2;
8314     argv[i]++;
8315     }
8316   if (isdigit(argv[i][0]))
8317     debug_selector = Ustrtol(argv[i], NULL, 0);
8318   else
8319     if (Ustrspn(argv[i], "abcdefghijklmnopqrtsuvwxyz0123456789-.:/") ==
8320         Ustrlen(argv[i]))
8321       {
8322 #ifdef LOOKUP_LDAP
8323       eldap_default_servers = argv[i];
8324 #endif
8325 #ifdef LOOKUP_MYSQL
8326       mysql_servers = argv[i];
8327 #endif
8328 #ifdef LOOKUP_PGSQL
8329       pgsql_servers = argv[i];
8330 #endif
8331 #ifdef LOOKUP_REDIS
8332       redis_servers = argv[i];
8333 #endif
8334       }
8335 #ifdef EXIM_PERL
8336   else opt_perl_startup = argv[i];
8337 #endif
8338   }
8339
8340 printf("Testing string expansion: debug_level = %d\n\n", debug_level);
8341
8342 expand_nstring[1] = US"string 1....";
8343 expand_nlength[1] = 8;
8344 expand_nmax = 1;
8345
8346 #ifdef EXIM_PERL
8347 if (opt_perl_startup != NULL)
8348   {
8349   uschar *errstr;
8350   printf("Starting Perl interpreter\n");
8351   errstr = init_perl(opt_perl_startup);
8352   if (errstr != NULL)
8353     {
8354     printf("** error in perl_startup code: %s\n", errstr);
8355     return EXIT_FAILURE;
8356     }
8357   }
8358 #endif /* EXIM_PERL */
8359
8360 while (fgets(buffer, sizeof(buffer), stdin) != NULL)
8361   {
8362   void *reset_point = store_get(0);
8363   uschar *yield = expand_string(buffer);
8364   if (yield != NULL)
8365     {
8366     printf("%s\n", yield);
8367     store_reset(reset_point);
8368     }
8369   else
8370     {
8371     if (f.search_find_defer) printf("search_find deferred\n");
8372     printf("Failed: %s\n", expand_string_message);
8373     if (f.expand_string_forcedfail) printf("Forced failure\n");
8374     printf("\n");
8375     }
8376   }
8377
8378 search_tidyup();
8379
8380 return 0;
8381 }
8382
8383 #endif
8384
8385 /* vi: aw ai sw=2
8386 */
8387 /* End of expand.c */