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