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