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