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