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