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