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