s/iterate_item_save/save_iterate_item/ to be consistent with other save_* variables.
[exim.git] / src / src / expand.c
1 /* $Cambridge: exim/src/src/expand.c,v 1.81 2007/02/10 23:51:11 magnus Exp $ */
2
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
6
7 /* Copyright (c) University of Cambridge 1995 - 2007 */
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
16 /* Recursively called function */
17
18 static uschar *expand_string_internal(uschar *, BOOL, uschar **, BOOL);
19
20 #ifdef STAND_ALONE
21 #ifndef SUPPORT_CRYPTEQ
22 #define SUPPORT_CRYPTEQ
23 #endif
24 #endif
25
26 #ifdef LOOKUP_LDAP
27 #include "lookups/ldap.h"
28 #endif
29
30 #ifdef SUPPORT_CRYPTEQ
31 #ifdef CRYPT_H
32 #include <crypt.h>
33 #endif
34 #ifndef HAVE_CRYPT16
35 extern char* crypt16(char*, char*);
36 #endif
37 #endif
38
39 /* The handling of crypt16() is a mess. I will record below the analysis of the
40 mess that was sent to me. We decided, however, to make changing this very low
41 priority, because in practice people are moving away from the crypt()
42 algorithms nowadays, so it doesn't seem worth it.
43
44 <quote>
45 There is an algorithm named "crypt16" in Ultrix and Tru64. It crypts
46 the 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,
48 or an empty block if the password is less than 9 characters, using a
49 20-round version of crypt and the same salt as was used for the first
50 block. Charaters after the first 16 are ignored. It always generates
51 a 16-byte hash, which is expressed together with the salt as a string
52 of 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
57 There's a different algorithm named "bigcrypt" in HP-UX, Digital Unix,
58 and OSF/1. This is the same as the standard crypt if given a password
59 of 8 characters or less. If given more, it first does the same as crypt
60 using the first 8 characters, then crypts the next 8 (the 9th to 16th)
61 using as salt the first two base 64 digits from the first hash block.
62 If the password is more than 16 characters then it crypts the 17th to 24th
63 characters using as salt the first two base 64 digits from the second hash
64 block. And so on: I've seen references to it cutting off the password at
65 40 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
72 Exim has something it calls "crypt16". It will either use a native
73 crypt16 or its own implementation. A native crypt16 will presumably
74 be the one that I called "crypt16" above. The internal "crypt16"
75 function, however, is a two-block-maximum implementation of what I called
76 "bigcrypt". The documentation matches the internal code.
77
78 I suspect that whoever did the "crypt16" stuff for Exim didn't realise
79 that crypt16 and bigcrypt were different things.
80
81 Exim uses the LDAP-style scheme identifier "{crypt16}" to refer
82 to whatever it is using under that name. This unfortunately sets a
83 precedent for using "{crypt16}" to identify two incompatible algorithms
84 whose output can't be distinguished. With "{crypt16}" thus rendered
85 ambiguous, I suggest you deprecate it and invent two new identifiers
86 for the two algorithms.
87
88 Both crypt16 and bigcrypt are very poor algorithms, btw. Hashing parts
89 of the password separately means they can be cracked separately, so
90 the double-length hash only doubles the cracking effort instead of
91 squaring it. I recommend salted SHA-1 ({SSHA}), or the Blowfish-based
92 bcrypt ({CRYPT}$2a$).
93 </quote>
94 */
95
96
97
98
99 /*************************************************
100 * Local statics and tables *
101 *************************************************/
102
103 /* Table of item names, and corresponding switch numbers. The names must be in
104 alphabetical order. */
105
106 static uschar *item_table[] = {
107 US"dlfunc",
108 US"extract",
109 US"hash",
110 US"hmac",
111 US"if",
112 US"length",
113 US"lookup",
114 US"nhash",
115 US"perl",
116 US"prvs",
117 US"prvscheck",
118 US"readfile",
119 US"readsocket",
120 US"run",
121 US"sg",
122 US"substr",
123 US"tr" };
124
125 enum {
126 EITEM_DLFUNC,
127 EITEM_EXTRACT,
128 EITEM_HASH,
129 EITEM_HMAC,
130 EITEM_IF,
131 EITEM_LENGTH,
132 EITEM_LOOKUP,
133 EITEM_NHASH,
134 EITEM_PERL,
135 EITEM_PRVS,
136 EITEM_PRVSCHECK,
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
145 in alphabetical order. There are two tables, because underscore is used in some
146 cases to introduce arguments, whereas for other it is part of the name. This is
147 an historical mis-design. */
148
149 static uschar *op_table_underscore[] = {
150 US"from_utf8",
151 US"local_part",
152 US"quote_local_part",
153 US"time_eval",
154 US"time_interval"};
155
156 enum {
157 EOP_FROM_UTF8,
158 EOP_LOCAL_PART,
159 EOP_QUOTE_LOCAL_PART,
160 EOP_TIME_EVAL,
161 EOP_TIME_INTERVAL };
162
163 static 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",
184 US"rfc2047d",
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
194 enum {
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,
215 EOP_RFC2047D,
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
227 be in alphabetical order. */
228
229 static 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",
243 US"forall",
244 US"forany",
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",
260 US"match_ip",
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
270 enum {
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,
284 ECOND_FORALL,
285 ECOND_FORANY,
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,
301 ECOND_MATCH_IP,
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
314 typedef 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
321 in use. */
322
323 typedef struct {
324 uschar **address;
325 int *length;
326 } alblock;
327
328 /* Types of table entry */
329
330 enum {
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 */
339 vtype_msgheaders, /* the message's headers, processed */
340 vtype_msgheaders_raw, /* the message's headers, unprocessed */
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 */
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 */
357 vtype_pinodes /* partition inodes; value is T/F for spool/log */
358 #ifdef EXPERIMENTAL_DOMAINKEYS
359 ,vtype_dk_verify /* Serve request out of DomainKeys verification structure */
360 #endif
361 };
362
363 /* This table must be kept in alphabetical order. */
364
365 static var_entry var_table[] = {
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. */
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 },
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
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 },
389 { "csa_status", vtype_stringptr, &csa_status },
390 #ifdef WITH_OLD_DEMIME
391 { "demime_errorlevel", vtype_int, &demime_errorlevel },
392 { "demime_reason", vtype_stringptr, &demime_reason },
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 },
406 #endif
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 },
415 #ifdef WITH_OLD_DEMIME
416 { "found_extension", vtype_stringptr, &found_extension },
417 #endif
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 },
422 { "host_lookup_deferred",vtype_int, &host_lookup_deferred },
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 },
427 { "item", vtype_stringptr, &iterate_item },
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 },
440 { "log_inodes", vtype_pinodes, (void *)FALSE },
441 { "log_space", vtype_pspace, (void *)FALSE },
442 { "mailstore_basename", vtype_stringptr, &mailstore_basename },
443 #ifdef WITH_CONTENT_SCAN
444 { "malware_name", vtype_stringptr, &malware_name },
445 #endif
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 },
450 { "message_exim_id", vtype_stringptr, &message_id },
451 { "message_headers", vtype_msgheaders, NULL },
452 { "message_headers_raw", vtype_msgheaders_raw, NULL },
453 { "message_id", vtype_stringptr, &message_id },
454 { "message_linecount", vtype_int, &message_linecount },
455 { "message_size", vtype_int, &message_size },
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
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 },
492 { "prvscheck_address", vtype_stringptr, &prvscheck_address },
493 { "prvscheck_keynum", vtype_stringptr, &prvscheck_keynum },
494 { "prvscheck_result", vtype_stringptr, &prvscheck_result },
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 },
502 { "received_ip_address", vtype_stringptr, &interface_address },
503 { "received_port", vtype_int, &interface_port },
504 { "received_protocol", vtype_stringptr, &received_protocol },
505 { "received_time", vtype_int, &received_time },
506 { "recipient_data", vtype_stringptr, &recipient_data },
507 { "recipient_verify_failure",vtype_stringptr,&recipient_verify_failure },
508 { "recipients", vtype_recipients, NULL },
509 { "recipients_count", vtype_int, &recipients_count },
510 #ifdef WITH_CONTENT_SCAN
511 { "regex_match_string", vtype_stringptr, &regex_match_string },
512 #endif
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 },
519 { "sender_address_data", vtype_stringptr, &sender_address_data },
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 },
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 },
533 { "sender_rcvhost", vtype_stringptr, &sender_rcvhost },
534 { "sender_verify_failure",vtype_stringptr, &sender_verify_failure },
535 { "sending_ip_address", vtype_stringptr, &sending_ip_address },
536 { "sending_port", vtype_int, &sending_port },
537 { "smtp_active_hostname", vtype_stringptr, &smtp_active_hostname },
538 { "smtp_command", vtype_stringptr, &smtp_cmd_buffer },
539 { "smtp_command_argument", vtype_stringptr, &smtp_cmd_argument },
540 { "smtp_count_at_connection_start", vtype_int, &smtp_accept_count },
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] },
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
563 { "spool_directory", vtype_stringptr, &spool_directory },
564 { "spool_inodes", vtype_pinodes, (void *)TRUE },
565 { "spool_space", vtype_pspace, (void *)TRUE },
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
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
595 static int var_table_size = sizeof(var_table)/sizeof(var_entry);
596 static uschar var_buffer[256];
597 static BOOL malformed_header;
598
599 /* For textual hashes */
600
601 static char *hashcodes = "abcdefghijklmnopqrtsuvwxyz"
602 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
603 "0123456789";
604
605 enum { HMAC_MD5, HMAC_SHA1 };
606
607 /* For numeric hashes */
608
609 static 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
616 static uschar *mtable_normal[] =
617 { US"---", US"--x", US"-w-", US"-wx", US"r--", US"r-x", US"rw-", US"rwx" };
618
619 static uschar *mtable_setid[] =
620 { US"--S", US"--s", US"-wS", US"-ws", US"r-S", US"r-s", US"rwS", US"rws" };
621
622 static 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
632 masked with 0x3f. The highest number for a valid UTF-8 character is in fact
633 0x3d. */
634
635 static 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,
642 indexed by the number of additional bytes. */
643
644 static 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
669 Arguments:
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
674 Returns: the offset in the table, or -1
675 */
676
677 static int
678 chop_match(uschar *name, uschar **table, int table_size)
679 {
680 uschar **bot = table;
681 uschar **top = table + table_size;
682
683 while (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
691 return -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"
701 or "false" value. Failure of the expansion yields FALSE; logged unless it was a
702 forced fail or lookup defer. All store used by the function can be released on
703 exit.
704
705 Arguments:
706 condition the condition string
707 m1 text to be incorporated in panic error
708 m2 ditto
709
710 Returns: TRUE if condition is met, FALSE if not
711 */
712
713 BOOL
714 expand_check_condition(uschar *condition, uschar *m1, uschar *m2)
715 {
716 int rc;
717 void *reset_point = store_get(0);
718 uschar *ss = expand_string(condition);
719 if (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 }
726 rc = ss[0] != 0 && Ustrcmp(ss, "0") != 0 && strcmpic(ss, US"no") != 0 &&
727 strcmpic(ss, US"false") != 0;
728 store_reset(reset_point);
729 return 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
740 Arguments:
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
746 Returns: pointer to the first character after the name
747
748 Note: The test for *s != 0 in the while loop is necessary because
749 Ustrchr() yields non-NULL if the character is zero (which is not something
750 I expected). */
751
752 static uschar *
753 read_name(uschar *name, int max, uschar *s, uschar *extras)
754 {
755 int ptr = 0;
756 while (*s != 0 && (isalnum(*s) || Ustrchr(extras, *s) != NULL))
757 {
758 if (ptr < max-1) name[ptr++] = *s;
759 s++;
760 }
761 name[ptr] = 0;
762 return 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
772 abbreviations) might not be the complete header name because headers can
773 contain any printing characters in their names, except ':'. This function is
774 called to read the rest of the name, chop h[eader]_ off the front, and put ':'
775 on the end, if the name was terminated by white space.
776
777 Arguments:
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
783 Returns: a pointer to the first character after the header name
784 */
785
786 static uschar *
787 read_header_name(uschar *name, int max, uschar *s)
788 {
789 int prelen = Ustrchr(name, '_') - name + 1;
790 int ptr = Ustrlen(name) - prelen;
791 if (ptr > 0) memmove(name, name+prelen, ptr);
792 while (mac_isgraph(*s) && *s != ':')
793 {
794 if (ptr < max-1) name[ptr++] = *s;
795 s++;
796 }
797 if (*s == ':') s++;
798 name[ptr++] = ':';
799 name[ptr] = 0;
800 return 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
813 Returns: a pointer to the character after the last digit
814 */
815
816 static uschar *
817 read_number(int *n, uschar *s)
818 {
819 *n = 0;
820 while (isdigit(*s)) *n = *n * 10 + (*s++ - '0');
821 return 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
832 Arguments:
833 key points to the name of the key
834 s points to the string from which to extract the subfield
835
836 Returns: NULL if the subfield was not found, or
837 a pointer to the subfield's data
838 */
839
840 static uschar *
841 expand_getkeyed(uschar *key, uschar *s)
842 {
843 int length = Ustrlen(key);
844 while (isspace(*s)) s++;
845
846 /* Loop to search for the key */
847
848 while (*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
866 return 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
877 example a line from /etc/passwd is divided by colon characters. First field is
878 numbered one. Negative arguments count from the right. Zero returns the whole
879 string. Returns NULL if there are insufficient tokens in the string
880
881 ***WARNING***
882 Modifies final argument - this is a dynamically generated string, so that's OK.
883
884 Arguments:
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
890 Returns: NULL if the field was not found,
891 a pointer to the field's data inside s (modified to add 0)
892 */
893
894 static uschar *
895 expand_gettokened (int field, uschar *separators, uschar *s)
896 {
897 int sep = 1;
898 int count;
899 uschar *ss = s;
900 uschar *fieldtext = NULL;
901
902 if (field == 0) return s;
903
904 /* Break the line up into fields in place; for field > 0 we stop when we have
905 done the number of fields we want. For field < 0 we continue till the end of
906 the string, counting the number of fields. */
907
908 count = (field > 0)? field : INT_MAX;
909
910 while (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
941 return fieldtext;
942 }
943
944
945
946 /*************************************************
947 * Extract a substring from a string *
948 *************************************************/
949
950 /* Perform the ${substr or ${length expansion operations.
951
952 Arguments:
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
961 Returns: pointer to the output string, or NULL if there is an error
962 */
963
964 static uschar *
965 extract_substr(uschar *subject, int value1, int value2, int *len)
966 {
967 int sublen = Ustrlen(subject);
968
969 if (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
995 string, 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
998 else
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
1009 the required characters. */
1010
1011 if (value1 + value2 > sublen) value2 = sublen - value1;
1012 *len = value2;
1013 return subject + value1;
1014 }
1015
1016
1017
1018
1019 /*************************************************
1020 * Old-style hash of a string *
1021 *************************************************/
1022
1023 /* Perform the ${hash expansion operation.
1024
1025 Arguments:
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
1032 Returns: pointer to the output string, or NULL if there is an error
1033 */
1034
1035 static uschar *
1036 compute_hash(uschar *subject, int value1, int value2, int *len)
1037 {
1038 int sublen = Ustrlen(subject);
1039
1040 if (value2 < 0) value2 = 26;
1041 else 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
1049 can safely place it in subject[] (we know that subject is always itself an
1050 expanded substring). */
1051
1052 if (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 }
1066 else value1 = sublen;
1067
1068 *len = value1;
1069 return 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
1080 string are treated as most important, and get the highest prime numbers.
1081
1082 Arguments:
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
1089 Returns: pointer to the output string, or NULL if there is an error.
1090 */
1091
1092 static uschar *
1093 compute_nhash (uschar *subject, int value1, int value2, int *len)
1094 {
1095 uschar *s = subject;
1096 int i = 0;
1097 unsigned long int total = 0; /* no overflow */
1098
1099 while (*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
1107 if (value2 < 0)
1108 {
1109 s = string_sprintf("%d", total % value1);
1110 }
1111
1112 /* Otherwise do a div/mod hash */
1113
1114 else
1115 {
1116 total = total % (value1 * value2);
1117 s = string_sprintf("%d/%d", total/value2, total % value2);
1118 }
1119
1120 *len = Ustrlen(s);
1121 return 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
1133 can also return a concatenation of all the header lines. When concatenating
1134 specific headers that contain lists of addresses, a comma is inserted between
1135 them. Otherwise we use a straight concatenation. Because some messages can have
1136 pathologically large number of lines, there is a limit on the length that is
1137 returned. Also, to avoid massive store use which would result from using
1138 string_cat() as it copies and extends strings, we do a preliminary pass to find
1139 out exactly how much store will be needed. On "normal" messages this will be
1140 pretty trivial.
1141
1142 Arguments:
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,
1151 other than concatenating, will be done on the header. Also used
1152 for $message_headers_raw.
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
1157 Returns: NULL if the header does not exist, else a pointer to a new
1158 store block
1159 */
1160
1161 static uschar *
1162 find_header(uschar *name, BOOL exists_only, int *newsize, BOOL want_raw,
1163 uschar *charset)
1164 {
1165 BOOL found = name == NULL;
1166 int comma = 0;
1167 int len = found? 0 : Ustrlen(name);
1168 int i;
1169 uschar *yield = NULL;
1170 uschar *ptr = NULL;
1171
1172 /* Loop for two passes - saves code repetition */
1173
1174 for (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
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
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
1212 size += ilen + comma + 1; /* +1 for the newline */
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 {
1221 ilen -= size - header_insert_maxlen - 1;
1222 comma = 0;
1223 }
1224 Ustrncpy(ptr, t, ilen);
1225 ptr += ilen;
1226
1227 /* For a non-raw header, put in the comma if needed, then add
1228 back the newline we removed above, provided there was some text in
1229 the header. */
1230
1231 if (!want_raw && ilen > 0)
1232 {
1233 if (comma != 0) *ptr++ = ',';
1234 *ptr++ = '\n';
1235 }
1236 }
1237 }
1238 }
1239 }
1240
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 */
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
1254 /* That's all we do for raw header expansion. */
1255
1256 if (want_raw)
1257 {
1258 *ptr = 0;
1259 }
1260
1261 /* Otherwise, remove a final newline and a redundant added comma. Then we do
1262 RFC 2047 decoding, translating the charset if requested. The rfc2047_decode2()
1263 function can return an error with decoded data if the charset translation
1264 fails. If decoding fails, it returns NULL. */
1265
1266 else
1267 {
1268 uschar *decoded, *error;
1269 if (ptr > yield && ptr[-1] == '\n') ptr--;
1270 if (ptr > yield && comma != 0 && ptr[-1] == ',') ptr--;
1271 *ptr = 0;
1272 decoded = rfc2047_decode2(yield, check_rfc2047_length, charset, '?', NULL,
1273 newsize, &error);
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
1282 return 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
1293 using a binary chop. The "choplen" variable is nothing to do with the binary
1294 chop.
1295
1296 Arguments:
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
1305 Returns: 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
1310 static uschar *
1311 find_variable(uschar *name, BOOL exists_only, BOOL skipping, int *newsize)
1312 {
1313 int first = 0;
1314 int last = var_table_size;
1315
1316 /* Handle ACL variables, whose names are of the form acl_cxxx or acl_mxxx.
1317 Originally, xxx had to be a number in the range 0-9 (later 0-19), but from
1318 release 4.64 onwards arbitrary names are permitted, as long as the first 5
1319 characters 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
1321 variables whose names start acl_ but they should never start in this way. This
1322 slightly messy specification is a consequence of the history, needless to say.
1323
1324 If an ACL variable does not exist, treat it as empty, unless strict_acl_vars is
1325 set, in which case give an error. */
1326
1327 if ((Ustrncmp(name, "acl_c", 5) == 0 || Ustrncmp(name, "acl_m", 5) == 0) &&
1328 !isalpha(name[5]))
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;
1333 }
1334
1335 /* Handle $auth<n> variables. */
1336
1337 if (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
1345 /* For all other variables, search the table */
1346
1347 while (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,
1358 and we want to avoid processing (such as looking up the host name). */
1359
1360 if (skipping) return US"";
1361
1362 switch (var_table[middle].type)
1363 {
1364 #ifdef EXPERIMENTAL_DOMAINKEYS
1365
1366 case vtype_dk_verify:
1367 if (dk_verify_block == NULL) return US"";
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;
1377
1378 if (Ustrcmp(var_table[middle].name, "dk_sender_source") == 0)
1379 switch(dk_verify_block->address_source) {
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;
1383 }
1384
1385 if (Ustrcmp(var_table[middle].name, "dk_status") == 0)
1386 switch(dk_verify_block->result) {
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;
1395 }
1396
1397 if (Ustrcmp(var_table[middle].name, "dk_signsall") == 0)
1398 s = (dk_verify_block->signsall)? US"1" : US"0";
1399
1400 if (Ustrcmp(var_table[middle].name, "dk_testing") == 0)
1401 s = (dk_verify_block->testing)? US"1" : US"0";
1402
1403 if (Ustrcmp(var_table[middle].name, "dk_is_signed") == 0)
1404 s = (dk_verify_block->is_signed)? US"1" : US"0";
1405
1406 return (s == NULL)? US"" : s;
1407 #endif
1408
1409 case vtype_filter_int:
1410 if (!filter_running) return NULL;
1411 /* Fall through */
1412 /* VVVVVVVVVVVV */
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
1468 case vtype_msgheaders_raw:
1469 return find_header(NULL, exists_only, newsize, TRUE, NULL);
1470
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;
1477 off_t start_offset = SPOOL_DATA_START_OFFSET;
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 */
1527 s = find_header(US"reply-to:", exists_only, newsize, TRUE,
1528 headers_charset);
1529 if (s != NULL) while (isspace(*s)) s++;
1530 if (s == NULL || *s == 0)
1531 {
1532 *newsize = 0; /* For the *s==0 case */
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 = ' ';
1540 while (t > s && isspace(t[-1])) t--;
1541 *t = 0;
1542 }
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;
1565
1566 case vtype_pspace:
1567 {
1568 int inodes;
1569 sprintf(CS var_buffer, "%d",
1570 receive_statvfs(var_table[middle].value == (void *)TRUE, &inodes));
1571 }
1572 return var_buffer;
1573
1574 case vtype_pinodes:
1575 {
1576 int inodes;
1577 (void) receive_statvfs(var_table[middle].value == (void *)TRUE, &inodes);
1578 sprintf(CS var_buffer, "%d", inodes);
1579 }
1580 return var_buffer;
1581 }
1582 }
1583
1584 return 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
1595 expansion items. Some have a minimum requirement that is less than the maximum;
1596 in these cases, the first non-present one is set to NULL.
1597
1598 Arguments:
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
1607 Returns: 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
1613 static int
1614 read_subs(uschar **sub, int n, int m, uschar **sptr, BOOL skipping,
1615 BOOL check_end, uschar *name)
1616 {
1617 int i;
1618 uschar *s = *sptr;
1619
1620 while (isspace(*s)) s++;
1621 for (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 }
1634 if (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;
1646 return 0;
1647 }
1648
1649
1650
1651
1652 /*************************************************
1653 * Elaborate message for bad variable *
1654 *************************************************/
1655
1656 /* For the "unknown variable" message, take a look at the variable's name, and
1657 give additional information about possible ACL variables. The extra information
1658 is added on to expand_string_message.
1659
1660 Argument: the name of the variable
1661 Returns: nothing
1662 */
1663
1664 static void
1665 check_variable_error_message(uschar *name)
1666 {
1667 if (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
1679 /*************************************************
1680 * Read and evaluate a condition *
1681 *************************************************/
1682
1683 /*
1684 Arguments:
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
1691 Returns: a pointer to the first character after the condition, or
1692 NULL after an error
1693 */
1694
1695 static uschar *
1696 eval_condition(uschar *s, BOOL *yield)
1697 {
1698 BOOL testfor = TRUE;
1699 BOOL tempcond, combined_cond;
1700 BOOL *subcondptr;
1701 int i, rc, cond_type, roffset;
1702 int num[2];
1703 struct stat statbuf;
1704 uschar name[256];
1705 uschar *sub[4];
1706
1707 const pcre *re;
1708 const uschar *rerror;
1709
1710 for (;;)
1711 {
1712 while (isspace(*s)) s++;
1713 if (*s == '!') { testfor = !testfor; s++; } else break;
1714 }
1715
1716 /* Numeric comparisons are symbolic */
1717
1718 if (*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
1732 else 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
1736 if (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
1745 cond_type = chop_match(name, cond_table, sizeof(cond_table)/sizeof(uschar *));
1746 switch(cond_type)
1747 {
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. */
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
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. */
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);
1772 if (Ustrchr(name, '}') != NULL) malformed_header = TRUE;
1773 if (yield != NULL) *yield =
1774 (find_header(name, TRUE, NULL, FALSE, NULL) != NULL) == testfor;
1775 }
1776
1777 /* Test for a variable's having a non-empty value. A non-existent variable
1778 causes an expansion failure. */
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);
1788 check_variable_error_message(name);
1789 return NULL;
1790 }
1791 if (yield != NULL) *yield = (value[0] != 0) == testfor;
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);
1854 *yield = ((cond_type == ECOND_ISIP)? (rc != 0) :
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
1950 match_ip: matches a host list that is restricted to IP addresses
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:
1959 case ECOND_MATCH_IP:
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
1999 if (!isalpha(name[0]) && yield != NULL)
2000 {
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 }
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
2105 case ECOND_MATCH_IP: /* Match IP address in a host list */
2106 if (sub[0][0] != 0 && string_is_ip_address(sub[0], NULL) == 0)
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
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 */
2144 /* VVVVVVVVVVVV */
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
2357 /* forall/forany: iterates a condition with different values */
2358
2359 case ECOND_FORALL:
2360 case ECOND_FORANY:
2361 {
2362 int sep = 0;
2363 uschar *save_iterate_item = iterate_item;
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
2414 iterate_item = save_iterate_item;
2415 return s;
2416 }
2417
2418
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
2428 COND_FAILED_CURLY_START:
2429 expand_string_message = string_sprintf("missing { after \"%s\"", name);
2430 return NULL;
2431
2432 COND_FAILED_CURLY_END:
2433 expand_string_message = string_sprintf("missing } at end of \"%s\" condition",
2434 name);
2435 return 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)
2442 COND_FAILED_NOT_COMPILED:
2443 expand_string_message = string_sprintf("support for \"%s\" not compiled",
2444 name);
2445 return 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
2457 restore the numbered variables.
2458
2459 Arguments:
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
2463 Returns: the value of expand max to save
2464 */
2465
2466 static int
2467 save_expand_strings(uschar **save_expand_nstring, int *save_expand_nlength)
2468 {
2469 int i;
2470 for (i = 0; i <= expand_nmax; i++)
2471 {
2472 save_expand_nstring[i] = expand_nstring[i];
2473 save_expand_nlength[i] = expand_nlength[i];
2474 }
2475 return expand_nmax;
2476 }
2477
2478
2479
2480 /*************************************************
2481 * Restore numerical variables *
2482 *************************************************/
2483
2484 /* This function restored saved values of numerical strings.
2485
2486 Arguments:
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
2491 Returns: nothing
2492 */
2493
2494 static void
2495 restore_expand_strings(int save_expand_nmax, uschar **save_expand_nstring,
2496 int *save_expand_nlength)
2497 {
2498 int i;
2499 expand_nmax = save_expand_nmax;
2500 for (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
2516 alternative substrings that depend on whether or not the condition was true,
2517 or the lookup or extraction succeeded. The substrings always have to be
2518 expanded, to check their syntax, but "skipping" is set when the result is not
2519 needed - this avoids unnecessary nested lookups.
2520
2521 Arguments:
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
2531 Returns: 0 OK; lookup_value has been reset to save_lookup
2532 1 expansion failed
2533 2 expansion failed because of bracketing error
2534 */
2535
2536 static int
2537 process_yesno(BOOL skipping, BOOL yes, uschar *save_lookup, uschar **sptr,
2538 uschar **yieldptr, int *sizeptr, int *ptrptr, uschar *type)
2539 {
2540 int rc = 0;
2541 uschar *s = *sptr; /* Local value */
2542 uschar *sub1, *sub2;
2543
2544 /* If there are no following strings, we substitute the contents of $value for
2545 lookups and for extractions in the success case. For the ${if item, the string
2546 "true" is substituted. In the fail case, nothing is substituted for all three
2547 items. */
2548
2549 while (isspace(*s)) s++;
2550 if (*s == '}')
2551 {
2552 if (type[0] == 'i')
2553 {
2554 if (yes) *yieldptr = string_cat(*yieldptr, sizeptr, ptrptr, US"true", 4);
2555 }
2556 else
2557 {
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 }
2563 s++;
2564 goto RETURN;
2565 }
2566
2567 /* The first following string must be braced. */
2568
2569 if (*s++ != '{') goto FAILED_CURLY;
2570
2571 /* Expand the first substring. Forced failures are noticed only if we actually
2572 want this string. Set skipping in the call in the fail case (this will always
2573 be the case if we were already skipping). */
2574
2575 sub1 = expand_string_internal(s, TRUE, &s, !yes);
2576 if (sub1 == NULL && (yes || !expand_string_forcedfail)) goto FAILED;
2577 expand_string_forcedfail = FALSE;
2578 if (*s++ != '}') goto FAILED_CURLY;
2579
2580 /* If we want the first string, add it to the output */
2581
2582 if (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
2586 what it was at the start of the item, so that it has this value during the
2587 second string expansion. For the call from "if" or "run" to this function,
2588 save_lookup is set to lookup_value, so that this statement does nothing. */
2589
2590 lookup_value = save_lookup;
2591
2592 /* There now follows either another substring, or "fail", or nothing. This
2593 time, forced failures are noticed only if we want the second string. We must
2594 set skipping in the nested call if we don't want this string, or if we were
2595 already skipping. */
2596
2597 while (isspace(*s)) s++;
2598 if (*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
2612 the second string is wanted, set a flag indicating it was a forced failure
2613 rather than a syntactic error. Swallow the terminating } in case this is nested
2614 inside another lookup or if or extract. */
2615
2616 else 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
2642 while (isspace(*s)) s++;
2643 if (*s++ == '}') goto RETURN;
2644
2645 /* Get here if there is a bracketing failure */
2646
2647 FAILED_CURLY:
2648 rc++;
2649
2650 /* Get here for other failures */
2651
2652 FAILED:
2653 rc++;
2654
2655 /* Update the input pointer value before returning */
2656
2657 RETURN:
2658 *sptr = s;
2659 return rc;
2660 }
2661
2662
2663
2664
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
2670 cleaner. A good compiler will spot the tail recursion.
2671
2672 Arguments:
2673 type HMAC_MD5 or HMAC_SHA1
2674 remaining are as for the cryptographic hash functions
2675
2676 Returns: nothing
2677 */
2678
2679 static void
2680 chash_start(int type, void *base)
2681 {
2682 if (type == HMAC_MD5)
2683 md5_start((md5 *)base);
2684 else
2685 sha1_start((sha1 *)base);
2686 }
2687
2688 static void
2689 chash_mid(int type, void *base, uschar *string)
2690 {
2691 if (type == HMAC_MD5)
2692 md5_mid((md5 *)base, string);
2693 else
2694 sha1_mid((sha1 *)base, string);
2695 }
2696
2697 static void
2698 chash_end(int type, void *base, uschar *string, int length, uschar *digest)
2699 {
2700 if (type == HMAC_MD5)
2701 md5_end((md5 *)base, string, length, digest);
2702 else
2703 sha1_end((sha1 *)base, string, length, digest);
2704 }
2705
2706
2707
2708
2709
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
2717 Argument: integer "days" offset to add or substract to
2718 or from the current number of days.
2719
2720 Returns: 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
2727 static uschar *
2728 prvs_daystamp(int day_offset)
2729 {
2730 uschar *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 */
2732 (time(NULL) + day_offset*86400)/86400);
2733 return (Ustrlen(days) >= 3) ? &days[Ustrlen(days)-3] : US"100";
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
2745 Arguments:
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
2752 Returns: 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
2757 static uschar *
2758 prvs_hmac_sha1(uschar *address, uschar *key, uschar *key_num, uschar *daystamp)
2759 {
2760 uschar *hash_source, *p;
2761 int size = 0,offset = 0,i;
2762 sha1 sha1_base;
2763 void *use_base = &sha1_base;
2764 uschar innerhash[20];
2765 uschar finalhash[20];
2766 uschar innerkey[64];
2767 uschar outerkey[64];
2768 uschar *finalhash_hex = store_get(40);
2769
2770 if (key_num == NULL)
2771 key_num = US"0";
2772
2773 if (Ustrlen(key) > 64)
2774 return NULL;
2775
2776 hash_source = string_cat(NULL,&size,&offset,key_num,1);
2777 string_cat(hash_source,&size,&offset,daystamp,3);
2778 string_cat(hash_source,&size,&offset,address,Ustrlen(address));
2779 hash_source[offset] = '\0';
2780
2781 DEBUG(D_expand) debug_printf("prvs: hash source is '%s'\n", hash_source);
2782
2783 memset(innerkey, 0x36, 64);
2784 memset(outerkey, 0x5c, 64);
2785
2786 for (i = 0; i < Ustrlen(key); i++)
2787 {
2788 innerkey[i] ^= key[i];
2789 outerkey[i] ^= key[i];
2790 }
2791
2792 chash_start(HMAC_SHA1, use_base);
2793 chash_mid(HMAC_SHA1, use_base, innerkey);
2794 chash_end(HMAC_SHA1, use_base, hash_source, offset, innerhash);
2795
2796 chash_start(HMAC_SHA1, use_base);
2797 chash_mid(HMAC_SHA1, use_base, outerkey);
2798 chash_end(HMAC_SHA1, use_base, innerhash, 20, finalhash);
2799
2800 p = finalhash_hex;
2801 for (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
2808 return finalhash_hex;
2809 }
2810
2811
2812
2813
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
2819 of a file onto the output string, globally replacing newlines with a given
2820 string (optionally). The file is closed at the end.
2821
2822 Arguments:
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
2829 Returns: new value of string pointer
2830 */
2831
2832 static uschar *
2833 cat_file(FILE *f, uschar *yield, int *sizep, int *ptrp, uschar *eol)
2834 {
2835 int eollen;
2836 uschar buffer[1024];
2837
2838 eollen = (eol == NULL)? 0 : Ustrlen(eol);
2839
2840 while (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
2849 if (yield != NULL) yield[*ptrp] = 0;
2850
2851 return yield;
2852 }
2853
2854
2855
2856
2857 /*************************************************
2858 * Evaluate numeric expression *
2859 *************************************************/
2860
2861 /* This is a set of mutually recursive functions that evaluate an arithmetic
2862 expression involving + - * / % & | ^ ~ << >> and parentheses. The only one of
2863 these functions that is called from elsewhere is eval_expr, whose interface is:
2864
2865 Arguments:
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
2870
2871 Returns: on success: the value of the expression, with *error still NULL
2872 on failure: an undefined value, with *error = a message
2873 */
2874
2875 static int eval_op_or(uschar **, BOOL, uschar **);
2876
2877
2878 static int
2879 eval_expr(uschar **sptr, BOOL decimal, uschar **error, BOOL endket)
2880 {
2881 uschar *s = *sptr;
2882 int x = eval_op_or(&s, decimal, error);
2883 if (*error == NULL)
2884 {
2885 if (endket)
2886 {
2887 if (*s != ')')
2888 *error = US"expecting closing parenthesis";
2889 else
2890 while (isspace(*(++s)));
2891 }
2892 else if (*s != 0) *error = US"expecting operator";
2893 }
2894 *sptr = s;
2895 return x;
2896 }
2897
2898
2899 static int
2900 eval_number(uschar **sptr, BOOL decimal, uschar **error)
2901 {
2902 register int c;
2903 int n;
2904 uschar *s = *sptr;
2905 while (isspace(*s)) s++;
2906 c = *s;
2907 if (isdigit(c))
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 }
2916 else if (c == '(')
2917 {
2918 s++;
2919 n = eval_expr(&s, decimal, error, 1);
2920 }
2921 else
2922 {
2923 *error = US"expecting number or opening parenthesis";
2924 n = 0;
2925 }
2926 *sptr = s;
2927 return n;
2928 }
2929
2930
2931 static int eval_op_unary(uschar **sptr, BOOL decimal, uschar **error)
2932 {
2933 uschar *s = *sptr;
2934 int x;
2935 while (isspace(*s)) s++;
2936 if (*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 }
2943 else
2944 {
2945 x = eval_number(&s, decimal, error);
2946 }
2947 *sptr = s;
2948 return x;
2949 }
2950
2951
2952 static int eval_op_mult(uschar **sptr, BOOL decimal, uschar **error)
2953 {
2954 uschar *s = *sptr;
2955 int x = eval_op_unary(&s, decimal, error);
2956 if (*error == NULL)
2957 {
2958 while (*s == '*' || *s == '/' || *s == '%')
2959 {
2960 int op = *s++;
2961 int y = eval_op_unary(&s, decimal, error);
2962 if (*error != NULL) break;
2963 if (op == '*') x *= y;
2964 else if (op == '/') x /= y;
2965 else x %= y;
2966 }
2967 }
2968 *sptr = s;
2969 return x;
2970 }
2971
2972
2973 static int eval_op_sum(uschar **sptr, BOOL decimal, uschar **error)
2974 {
2975 uschar *s = *sptr;
2976 int x = eval_op_mult(&s, decimal, error);
2977 if (*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;
2988 return x;
2989 }
2990
2991
2992 static int eval_op_shift(uschar **sptr, BOOL decimal, uschar **error)
2993 {
2994 uschar *s = *sptr;
2995 int x = eval_op_sum(&s, decimal, error);
2996 if (*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;
3009 return x;
3010 }
3011
3012
3013 static int eval_op_and(uschar **sptr, BOOL decimal, uschar **error)
3014 {
3015 uschar *s = *sptr;
3016 int x = eval_op_shift(&s, decimal, error);
3017 if (*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;
3029 return x;
3030 }
3031
3032
3033 static int eval_op_xor(uschar **sptr, BOOL decimal, uschar **error)
3034 {
3035 uschar *s = *sptr;
3036 int x = eval_op_and(&s, decimal, error);
3037 if (*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;
3049 return x;
3050 }
3051
3052
3053 static int eval_op_or(uschar **sptr, BOOL decimal, uschar **error)
3054 {
3055 uschar *s = *sptr;
3056 int x = eval_op_xor(&s, decimal, error);
3057 if (*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;
3069 return x;
3070 }
3071
3072
3073
3074 /*************************************************
3075 * Expand string *
3076 *************************************************/
3077
3078 /* Returns either an unchanged string, or the expanded string in stacking pool
3079 store. 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
3088 There are now far too many operators and item types to make it worth listing
3089 them here in detail any more.
3090
3091 We use an internal routine recursively to handle embedded substrings. The
3092 external function follows. The yield is NULL if the expansion failed, and there
3093 are two cases: if something collapsed syntactically, or if "fail" was given
3094 as the action on a lookup failure. These can be distinguised by looking at the
3095 variable expand_string_forcedfail, which is TRUE in the latter case.
3096
3097 The skipping flag is set true when expanding a substring that isn't actually
3098 going to be used (after "if" or "lookup") and it prevents lookups from
3099 happening lower down.
3100
3101 Store usage: At start, a store block of the length of the input plus 64
3102 is obtained. This is expanded as necessary by string_cat(), which might have to
3103 get a new block, or might be able to expand the original. At the end of the
3104 function we can release any store above that portion of the yield block that
3105 was actually used. In many cases this will be optimal.
3106
3107 However: if the first item in the expansion is a variable name or header name,
3108 we reset the store before processing it; if the result is in fresh store, we
3109 use that without copying. This is helpful for expanding strings like
3110 $message_headers which can get very long.
3111
3112 Arguments:
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
3120 Returns: 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
3126 static uschar *
3127 expand_string_internal(uschar *string, BOOL ket_ends, uschar **left,
3128 BOOL skipping)
3129 {
3130 int ptr = 0;
3131 int size = Ustrlen(string)+ 64;
3132 int item_type;
3133 uschar *yield = store_get(size);
3134 uschar *s = string;
3135 uschar *save_expand_nstring[EXPAND_MAXN+1];
3136 int save_expand_nlength[EXPAND_MAXN+1];
3137
3138 expand_string_forcedfail = FALSE;
3139 expand_string_message = US"";
3140
3141 while (*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
3229 character, this may be a user error where the terminating colon
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);
3249 check_variable_error_message(name);
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
3440 if (!mac_islookup(stype, lookup_querystyle|lookup_absfilequery))
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
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. */
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
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. */
3474
3475 if (key == NULL)
3476 {
3477 while (isspace(*filename)) filename++;
3478 key = filename;
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 }
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
3562 #define EXIM_PERL_MAX_ARGS 8
3563
3564 case EITEM_PERL:
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 */
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
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 {
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";
3679 goto EXPAND_FAILED;
3680 }
3681
3682 p = prvs_hmac_sha1(sub_arg[0],sub_arg[1],sub_arg[2],prvs_daystamp(7));
3683 if (p == NULL)
3684 {
3685 expand_string_message = US"prvs hmac-sha1 conversion failed";
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;
3712
3713 /* TF: Ugliness: We want to expand parameter 1 first, then set
3714 up expansion variables that are used in the expansion of
3715 parameter 2. So we clone the string for the first
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 */
3722
3723 /* Reset expansion variables */
3724 prvscheck_result = NULL;
3725 prvscheck_address = NULL;
3726 prvscheck_keynum = NULL;
3727
3728 switch(read_subs(sub_arg, 1, 1, &s, skipping, FALSE, US"prvs"))
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
3738 if (regex_match_and_setup(re,sub_arg[0],0,-1))
3739 {
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));
3754 string_cat(prvscheck_address,&mysize,&myptr,US"@",1);
3755 string_cat(prvscheck_address,&mysize,&myptr,domain,Ustrlen(domain));
3756 prvscheck_address[myptr] = '\0';
3757 prvscheck_keynum = string_copy(key_num);
3758
3759 /* Now expand the second argument */
3760 switch(read_subs(sub_arg, 1, 1, &s, skipping, FALSE, US"prvs"))
3761 {
3762 case 1: goto EXPAND_FAILED_CURLY;
3763 case 2:
3764 case 3: goto EXPAND_FAILED;
3765 }
3766
3767 /* Now we have the key and can check the address. */
3768
3769 p = prvs_hmac_sha1(prvscheck_address, sub_arg[0], prvscheck_keynum,
3770 daystamp);
3771
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);
3780
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
3787 (void)sscanf(CS now,"%u",&inow);
3788 (void)sscanf(CS daystamp,"%u",&iexpire);
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 }
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 }
3832 else
3833 {
3834 /* Does not look like a prvs encoded address, return the empty string.
3835 We need to make sure all subs are expanded first, so as to skip over
3836 the entire item. */
3837
3838 switch(read_subs(sub_arg, 2, 1, &s, skipping, TRUE, US"prvs"))
3839 {
3840 case 1: goto EXPAND_FAILED_CURLY;
3841 case 2:
3842 case 3: goto EXPAND_FAILED;
3843 }
3844 }
3845
3846 continue;
3847 }
3848
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]);
3883 (void)fclose(f);
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
3929 /* If skipping, we don't actually do anything. Otherwise, arrange to
3930 connect to either an IP or a Unix socket. */
3931
3932 if (!skipping)
3933 {
3934 /* Handle an IP (internet) domain */
3935
3936 if (Ustrncmp(sub_arg[0], "inet:", 5) == 0)
3937 {
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;
4013 if (host_find_byname(&shost, NULL, HOST_FIND_QUALIFY_SINGLE, NULL,
4014 FALSE) != HOST_FOUND)
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 }
4048 }
4049
4050 /* Handle a Unix domain socket */
4051
4052 else
4053 {
4054 int rc;
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]);
4065
4066 sigalrm_seen = FALSE;
4067 alarm(timeout);
4068 rc = connect(fd, (struct sockaddr *)(&sockun), sizeof(sockun));
4069 alarm(0);
4070 if (sigalrm_seen)
4071 {
4072 expand_string_message = US "socket connect timed out";
4073 goto SOCK_FAIL;
4074 }
4075 if (rc < 0)
4076 {
4077 expand_string_message = string_sprintf("failed to connect to socket "
4078 "%s: %s", sub_arg[0], strerror(errno));
4079 goto SOCK_FAIL;
4080 }
4081 }
4082
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
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
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);
4116 (void)fclose(f);
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;
4124 expand_string_message = US "socket read timed out";
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;
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
4213 (void)close(fd_in);
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");
4242 lookup_value = NULL;
4243 lookup_value = cat_file(f, lookup_value, &lsize, &lptr, NULL);
4244 (void)fclose(f);
4245 }
4246
4247 /* Process the yes/no strings; $value may be useful in both cases */
4248
4249 switch(process_yesno(
4250 skipping, /* were previously skipping */
4251 runrc == 0, /* success/failure indicator */
4252 lookup_value, /* value to reset for string2 */
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 {
4630 expand_string_message = US"first argument of \"extract\" must "
4631 "not be empty";
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 }
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());
4753 log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message);
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 */
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
4843 /* Note that for Darwin and Cygwin, BASE_62 actually has the value 36 */
4844
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 "
4856 "operator is \"%s\", which is not a base %d number", sub,
4857 BASE_62);
4858 goto EXPAND_FAILED;
4859 }
4860 n = n * BASE_62 + (t - base62_chars);
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,
5017 host_nmtoa(count, binary, mask, buffer, '.'));
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 {
5149 uschar buffer[2048];
5150 uschar *string = parse_quote_2047(sub, Ustrlen(sub), headers_charset,
5151 buffer, sizeof(buffer), FALSE);
5152 yield = string_cat(yield, &size, &ptr, string, Ustrlen(string));
5153 continue;
5154 }
5155
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
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
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
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
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
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 "
5406 "uid=%ld gid=%ld size=" OFF_T_FMT " atime=%ld mtime=%ld ctime=%ld",
5407 (long)(st.st_mode & 077777), smode, (long)st.st_ino,
5408 (long)st.st_dev, (long)st.st_nlink, (long)st.st_uid,
5409 (long)st.st_gid, st.st_size, (long)st.st_atime,
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);
5446 check_variable_error_message(name);
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
5469 terminating brace. */
5470
5471 if (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
5481 added to the string. If so, set up an empty string. Add a terminating zero. If
5482 left != NULL, return a pointer to the terminator. */
5483
5484 if (yield == NULL) yield = store_get(1);
5485 yield[ptr] = 0;
5486 if (left != NULL) *left = s;
5487
5488 /* Any stacking store that was used above the final string is no longer needed.
5489 In many cases the final string will be the first one that was got and so there
5490 will be optimal store usage. */
5491
5492 store_reset(yield + ptr + 1);
5493 DEBUG(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 }
5499 return yield;
5500
5501 /* This is the failure exit: easiest to program with a goto. We still need
5502 to update the pointer to the terminator, for cases of nested calls with "fail".
5503 */
5504
5505 EXPAND_FAILED_CURLY:
5506 expand_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
5512 that is a bad idea, because expand_string_message is in dynamic store. */
5513
5514 EXPAND_FAILED:
5515 if (left != NULL) *left = s;
5516 DEBUG(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 }
5522 return NULL;
5523 }
5524
5525
5526 /* This is the external function call. Do a quick check for any expansion
5527 metacharacters, and if there are none, just return the input string.
5528
5529 Argument: the string to be expanded
5530 Returns: 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
5534 uschar *
5535 expand_string(uschar *string)
5536 {
5537 search_find_defer = FALSE;
5538 malformed_header = FALSE;
5539 return (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
5550 new bit of store. This function does that.
5551
5552 Argument: the string to be expanded
5553 Returns: the expanded string, always in a new bit of store, or NULL
5554 */
5555
5556 uschar *
5557 expand_string_copy(uschar *string)
5558 {
5559 uschar *yield = expand_string(string);
5560 if (yield == string) yield = string_copy(string);
5561 return 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
5572 Arguments:
5573 string the string to be expanded
5574 isplus TRUE if a non-negative number is expected
5575
5576 Returns: 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
5579 expand_string_message is set NULL for an OK integer
5580 */
5581
5582 int
5583 expand_string_integer(uschar *string, BOOL isplus)
5584 {
5585 long int value;
5586 uschar *s = expand_string(string);
5587 uschar *msg = US"invalid integer \"%s\"";
5588 uschar *endptr;
5589
5590 /* If expansion failed, expand_string_message will be set. */
5591
5592 if (s == NULL) return -1;
5593
5594 /* On an overflow, strtol() returns LONG_MAX or LONG_MIN, and sets errno
5595 to ERANGE. When there isn't an overflow, errno is not changed, at least on some
5596 systems, so we set it zero ourselves. */
5597
5598 errno = 0;
5599 expand_string_message = NULL; /* Indicates no error */
5600 value = strtol(CS s, CSS &endptr, 10);
5601
5602 if (endptr == s)
5603 {
5604 msg = US"integer expected but \"%s\" found";
5605 }
5606 else if (value < 0 && isplus)
5607 {
5608 msg = US"non-negative integer expected but \"%s\" found";
5609 }
5610 else
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
5640 expand_string_message = string_sprintf(CS msg, s);
5641 return -2;
5642 }
5643
5644
5645 /*************************************************
5646 **************************************************
5647 * Stand-alone test program *
5648 **************************************************
5649 *************************************************/
5650
5651 #ifdef STAND_ALONE
5652
5653
5654 BOOL
5655 regex_match_and_setup(const pcre *re, uschar *subject, int options, int setup)
5656 {
5657 int ovector[3*(EXPAND_MAXN+1)];
5658 int n = pcre_exec(re, NULL, subject, Ustrlen(subject), 0, PCRE_EOPT|options,
5659 ovector, sizeof(ovector)/sizeof(int));
5660 BOOL yield = n >= 0;
5661 if (n == 0) n = EXPAND_MAXN + 1;
5662 if (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 }
5673 return yield;
5674 }
5675
5676
5677 int main(int argc, uschar **argv)
5678 {
5679 int i;
5680 uschar buffer[1024];
5681
5682 debug_selector = D_v;
5683 debug_file = stderr;
5684 debug_fd = fileno(debug_file);
5685 big_buffer = malloc(big_buffer_size);
5686
5687 for (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
5715 printf("Testing string expansion: debug_level = %d\n\n", debug_level);
5716
5717 expand_nstring[1] = US"string 1....";
5718 expand_nlength[1] = 8;
5719 expand_nmax = 1;
5720
5721 #ifdef EXIM_PERL
5722 if (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
5735 while (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
5753 search_tidyup();
5754
5755 return 0;
5756 }
5757
5758 #endif
5759
5760 /* End of expand.c */