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