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