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