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