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