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