Add $smtp_command_history variable
[exim.git] / src / src / expand.c
1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2016 */
6 /* See the file NOTICE for conditions of use and distribution. */
7
8
9 /* Functions for handling string expansion. */
10
11
12 #include "exim.h"
13
14 /* Recursively called function */
15
16 static uschar *expand_string_internal(const uschar *, BOOL, const uschar **, BOOL, BOOL, BOOL *);
17 static int_eximarith_t expanded_string_integer(const uschar *, BOOL);
18
19 #ifdef STAND_ALONE
20 #ifndef SUPPORT_CRYPTEQ
21 #define SUPPORT_CRYPTEQ
22 #endif
23 #endif
24
25 #ifdef LOOKUP_LDAP
26 #include "lookups/ldap.h"
27 #endif
28
29 #ifdef SUPPORT_CRYPTEQ
30 #ifdef CRYPT_H
31 #include <crypt.h>
32 #endif
33 #ifndef HAVE_CRYPT16
34 extern char* crypt16(char*, char*);
35 #endif
36 #endif
37
38 /* The handling of crypt16() is a mess. I will record below the analysis of the
39 mess that was sent to me. We decided, however, to make changing this very low
40 priority, because in practice people are moving away from the crypt()
41 algorithms nowadays, so it doesn't seem worth it.
42
43 <quote>
44 There is an algorithm named "crypt16" in Ultrix and Tru64. It crypts
45 the first 8 characters of the password using a 20-round version of crypt
46 (standard crypt does 25 rounds). It then crypts the next 8 characters,
47 or an empty block if the password is less than 9 characters, using a
48 20-round version of crypt and the same salt as was used for the first
49 block. Characters after the first 16 are ignored. It always generates
50 a 16-byte hash, which is expressed together with the salt as a string
51 of 24 base 64 digits. Here are some links to peruse:
52
53 http://cvs.pld.org.pl/pam/pamcrypt/crypt16.c?rev=1.2
54 http://seclists.org/bugtraq/1999/Mar/0076.html
55
56 There's a different algorithm named "bigcrypt" in HP-UX, Digital Unix,
57 and OSF/1. This is the same as the standard crypt if given a password
58 of 8 characters or less. If given more, it first does the same as crypt
59 using the first 8 characters, then crypts the next 8 (the 9th to 16th)
60 using as salt the first two base 64 digits from the first hash block.
61 If the password is more than 16 characters then it crypts the 17th to 24th
62 characters using as salt the first two base 64 digits from the second hash
63 block. And so on: I've seen references to it cutting off the password at
64 40 characters (5 blocks), 80 (10 blocks), or 128 (16 blocks). Some links:
65
66 http://cvs.pld.org.pl/pam/pamcrypt/bigcrypt.c?rev=1.2
67 http://seclists.org/bugtraq/1999/Mar/0109.html
68 http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/HTML/AA-Q0R2D-
69 TET1_html/sec.c222.html#no_id_208
70
71 Exim has something it calls "crypt16". It will either use a native
72 crypt16 or its own implementation. A native crypt16 will presumably
73 be the one that I called "crypt16" above. The internal "crypt16"
74 function, however, is a two-block-maximum implementation of what I called
75 "bigcrypt". The documentation matches the internal code.
76
77 I suspect that whoever did the "crypt16" stuff for Exim didn't realise
78 that crypt16 and bigcrypt were different things.
79
80 Exim uses the LDAP-style scheme identifier "{crypt16}" to refer
81 to whatever it is using under that name. This unfortunately sets a
82 precedent for using "{crypt16}" to identify two incompatible algorithms
83 whose output can't be distinguished. With "{crypt16}" thus rendered
84 ambiguous, I suggest you deprecate it and invent two new identifiers
85 for the two algorithms.
86
87 Both crypt16 and bigcrypt are very poor algorithms, btw. Hashing parts
88 of the password separately means they can be cracked separately, so
89 the double-length hash only doubles the cracking effort instead of
90 squaring it. I recommend salted SHA-1 ({SSHA}), or the Blowfish-based
91 bcrypt ({CRYPT}$2a$).
92 </quote>
93 */
94
95
96
97 /*************************************************
98 * Local statics and tables *
99 *************************************************/
100
101 /* Table of item names, and corresponding switch numbers. The names must be in
102 alphabetical order. */
103
104 static uschar *item_table[] = {
105 US"acl",
106 US"certextract",
107 US"dlfunc",
108 US"env",
109 US"extract",
110 US"filter",
111 US"hash",
112 US"hmac",
113 US"if",
114 #ifdef SUPPORT_I18N
115 US"imapfolder",
116 #endif
117 US"length",
118 US"listextract",
119 US"lookup",
120 US"map",
121 US"nhash",
122 US"perl",
123 US"prvs",
124 US"prvscheck",
125 US"readfile",
126 US"readsocket",
127 US"reduce",
128 US"run",
129 US"sg",
130 US"sort",
131 US"substr",
132 US"tr" };
133
134 enum {
135 EITEM_ACL,
136 EITEM_CERTEXTRACT,
137 EITEM_DLFUNC,
138 EITEM_ENV,
139 EITEM_EXTRACT,
140 EITEM_FILTER,
141 EITEM_HASH,
142 EITEM_HMAC,
143 EITEM_IF,
144 #ifdef SUPPORT_I18N
145 EITEM_IMAPFOLDER,
146 #endif
147 EITEM_LENGTH,
148 EITEM_LISTEXTRACT,
149 EITEM_LOOKUP,
150 EITEM_MAP,
151 EITEM_NHASH,
152 EITEM_PERL,
153 EITEM_PRVS,
154 EITEM_PRVSCHECK,
155 EITEM_READFILE,
156 EITEM_READSOCK,
157 EITEM_REDUCE,
158 EITEM_RUN,
159 EITEM_SG,
160 EITEM_SORT,
161 EITEM_SUBSTR,
162 EITEM_TR };
163
164 /* Tables of operator names, and corresponding switch numbers. The names must be
165 in alphabetical order. There are two tables, because underscore is used in some
166 cases to introduce arguments, whereas for other it is part of the name. This is
167 an historical mis-design. */
168
169 static uschar *op_table_underscore[] = {
170 US"from_utf8",
171 US"local_part",
172 US"quote_local_part",
173 US"reverse_ip",
174 US"time_eval",
175 US"time_interval"
176 #ifdef SUPPORT_I18N
177 ,US"utf8_domain_from_alabel",
178 US"utf8_domain_to_alabel",
179 US"utf8_localpart_from_alabel",
180 US"utf8_localpart_to_alabel"
181 #endif
182 };
183
184 enum {
185 EOP_FROM_UTF8,
186 EOP_LOCAL_PART,
187 EOP_QUOTE_LOCAL_PART,
188 EOP_REVERSE_IP,
189 EOP_TIME_EVAL,
190 EOP_TIME_INTERVAL
191 #ifdef SUPPORT_I18N
192 ,EOP_UTF8_DOMAIN_FROM_ALABEL,
193 EOP_UTF8_DOMAIN_TO_ALABEL,
194 EOP_UTF8_LOCALPART_FROM_ALABEL,
195 EOP_UTF8_LOCALPART_TO_ALABEL
196 #endif
197 };
198
199 static uschar *op_table_main[] = {
200 US"address",
201 US"addresses",
202 US"base32",
203 US"base32d",
204 US"base62",
205 US"base62d",
206 US"base64",
207 US"base64d",
208 US"domain",
209 US"escape",
210 US"escape8bit",
211 US"eval",
212 US"eval10",
213 US"expand",
214 US"h",
215 US"hash",
216 US"hex2b64",
217 US"hexquote",
218 US"ipv6denorm",
219 US"ipv6norm",
220 US"l",
221 US"lc",
222 US"length",
223 US"listcount",
224 US"listnamed",
225 US"mask",
226 US"md5",
227 US"nh",
228 US"nhash",
229 US"quote",
230 US"randint",
231 US"rfc2047",
232 US"rfc2047d",
233 US"rxquote",
234 US"s",
235 US"sha1",
236 US"sha256",
237 US"sha3",
238 US"stat",
239 US"str2b64",
240 US"strlen",
241 US"substr",
242 US"uc",
243 US"utf8clean" };
244
245 enum {
246 EOP_ADDRESS = nelem(op_table_underscore),
247 EOP_ADDRESSES,
248 EOP_BASE32,
249 EOP_BASE32D,
250 EOP_BASE62,
251 EOP_BASE62D,
252 EOP_BASE64,
253 EOP_BASE64D,
254 EOP_DOMAIN,
255 EOP_ESCAPE,
256 EOP_ESCAPE8BIT,
257 EOP_EVAL,
258 EOP_EVAL10,
259 EOP_EXPAND,
260 EOP_H,
261 EOP_HASH,
262 EOP_HEX2B64,
263 EOP_HEXQUOTE,
264 EOP_IPV6DENORM,
265 EOP_IPV6NORM,
266 EOP_L,
267 EOP_LC,
268 EOP_LENGTH,
269 EOP_LISTCOUNT,
270 EOP_LISTNAMED,
271 EOP_MASK,
272 EOP_MD5,
273 EOP_NH,
274 EOP_NHASH,
275 EOP_QUOTE,
276 EOP_RANDINT,
277 EOP_RFC2047,
278 EOP_RFC2047D,
279 EOP_RXQUOTE,
280 EOP_S,
281 EOP_SHA1,
282 EOP_SHA256,
283 EOP_SHA3,
284 EOP_STAT,
285 EOP_STR2B64,
286 EOP_STRLEN,
287 EOP_SUBSTR,
288 EOP_UC,
289 EOP_UTF8CLEAN };
290
291
292 /* Table of condition names, and corresponding switch numbers. The names must
293 be in alphabetical order. */
294
295 static uschar *cond_table[] = {
296 US"<",
297 US"<=",
298 US"=",
299 US"==", /* Backward compatibility */
300 US">",
301 US">=",
302 US"acl",
303 US"and",
304 US"bool",
305 US"bool_lax",
306 US"crypteq",
307 US"def",
308 US"eq",
309 US"eqi",
310 US"exists",
311 US"first_delivery",
312 US"forall",
313 US"forany",
314 US"ge",
315 US"gei",
316 US"gt",
317 US"gti",
318 US"inlist",
319 US"inlisti",
320 US"isip",
321 US"isip4",
322 US"isip6",
323 US"ldapauth",
324 US"le",
325 US"lei",
326 US"lt",
327 US"lti",
328 US"match",
329 US"match_address",
330 US"match_domain",
331 US"match_ip",
332 US"match_local_part",
333 US"or",
334 US"pam",
335 US"pwcheck",
336 US"queue_running",
337 US"radius",
338 US"saslauthd"
339 };
340
341 enum {
342 ECOND_NUM_L,
343 ECOND_NUM_LE,
344 ECOND_NUM_E,
345 ECOND_NUM_EE,
346 ECOND_NUM_G,
347 ECOND_NUM_GE,
348 ECOND_ACL,
349 ECOND_AND,
350 ECOND_BOOL,
351 ECOND_BOOL_LAX,
352 ECOND_CRYPTEQ,
353 ECOND_DEF,
354 ECOND_STR_EQ,
355 ECOND_STR_EQI,
356 ECOND_EXISTS,
357 ECOND_FIRST_DELIVERY,
358 ECOND_FORALL,
359 ECOND_FORANY,
360 ECOND_STR_GE,
361 ECOND_STR_GEI,
362 ECOND_STR_GT,
363 ECOND_STR_GTI,
364 ECOND_INLIST,
365 ECOND_INLISTI,
366 ECOND_ISIP,
367 ECOND_ISIP4,
368 ECOND_ISIP6,
369 ECOND_LDAPAUTH,
370 ECOND_STR_LE,
371 ECOND_STR_LEI,
372 ECOND_STR_LT,
373 ECOND_STR_LTI,
374 ECOND_MATCH,
375 ECOND_MATCH_ADDRESS,
376 ECOND_MATCH_DOMAIN,
377 ECOND_MATCH_IP,
378 ECOND_MATCH_LOCAL_PART,
379 ECOND_OR,
380 ECOND_PAM,
381 ECOND_PWCHECK,
382 ECOND_QUEUE_RUNNING,
383 ECOND_RADIUS,
384 ECOND_SASLAUTHD
385 };
386
387
388 /* Types of table entry */
389
390 enum vtypes {
391 vtype_int, /* value is address of int */
392 vtype_filter_int, /* ditto, but recognized only when filtering */
393 vtype_ino, /* value is address of ino_t (not always an int) */
394 vtype_uid, /* value is address of uid_t (not always an int) */
395 vtype_gid, /* value is address of gid_t (not always an int) */
396 vtype_bool, /* value is address of bool */
397 vtype_stringptr, /* value is address of pointer to string */
398 vtype_msgbody, /* as stringptr, but read when first required */
399 vtype_msgbody_end, /* ditto, the end of the message */
400 vtype_msgheaders, /* the message's headers, processed */
401 vtype_msgheaders_raw, /* the message's headers, unprocessed */
402 vtype_localpart, /* extract local part from string */
403 vtype_domain, /* extract domain from string */
404 vtype_string_func, /* value is string returned by given function */
405 vtype_todbsdin, /* value not used; generate BSD inbox tod */
406 vtype_tode, /* value not used; generate tod in epoch format */
407 vtype_todel, /* value not used; generate tod in epoch/usec format */
408 vtype_todf, /* value not used; generate full tod */
409 vtype_todl, /* value not used; generate log tod */
410 vtype_todlf, /* value not used; generate log file datestamp tod */
411 vtype_todzone, /* value not used; generate time zone only */
412 vtype_todzulu, /* value not used; generate zulu tod */
413 vtype_reply, /* value not used; get reply from headers */
414 vtype_pid, /* value not used; result is pid */
415 vtype_host_lookup, /* value not used; get host name */
416 vtype_load_avg, /* value not used; result is int from os_getloadavg */
417 vtype_pspace, /* partition space; value is T/F for spool/log */
418 vtype_pinodes, /* partition inodes; value is T/F for spool/log */
419 vtype_cert /* SSL certificate */
420 #ifndef DISABLE_DKIM
421 ,vtype_dkim /* Lookup of value in DKIM signature */
422 #endif
423 };
424
425 /* Type for main variable table */
426
427 typedef struct {
428 const char *name;
429 enum vtypes type;
430 void *value;
431 } var_entry;
432
433 /* Type for entries pointing to address/length pairs. Not currently
434 in use. */
435
436 typedef struct {
437 uschar **address;
438 int *length;
439 } alblock;
440
441 static uschar * fn_recipients(void);
442
443 /* This table must be kept in alphabetical order. */
444
445 static var_entry var_table[] = {
446 /* WARNING: Do not invent variables whose names start acl_c or acl_m because
447 they will be confused with user-creatable ACL variables. */
448 { "acl_arg1", vtype_stringptr, &acl_arg[0] },
449 { "acl_arg2", vtype_stringptr, &acl_arg[1] },
450 { "acl_arg3", vtype_stringptr, &acl_arg[2] },
451 { "acl_arg4", vtype_stringptr, &acl_arg[3] },
452 { "acl_arg5", vtype_stringptr, &acl_arg[4] },
453 { "acl_arg6", vtype_stringptr, &acl_arg[5] },
454 { "acl_arg7", vtype_stringptr, &acl_arg[6] },
455 { "acl_arg8", vtype_stringptr, &acl_arg[7] },
456 { "acl_arg9", vtype_stringptr, &acl_arg[8] },
457 { "acl_narg", vtype_int, &acl_narg },
458 { "acl_verify_message", vtype_stringptr, &acl_verify_message },
459 { "address_data", vtype_stringptr, &deliver_address_data },
460 { "address_file", vtype_stringptr, &address_file },
461 { "address_pipe", vtype_stringptr, &address_pipe },
462 { "authenticated_fail_id",vtype_stringptr, &authenticated_fail_id },
463 { "authenticated_id", vtype_stringptr, &authenticated_id },
464 { "authenticated_sender",vtype_stringptr, &authenticated_sender },
465 { "authentication_failed",vtype_int, &authentication_failed },
466 #ifdef WITH_CONTENT_SCAN
467 { "av_failed", vtype_int, &av_failed },
468 #endif
469 #ifdef EXPERIMENTAL_BRIGHTMAIL
470 { "bmi_alt_location", vtype_stringptr, &bmi_alt_location },
471 { "bmi_base64_tracker_verdict", vtype_stringptr, &bmi_base64_tracker_verdict },
472 { "bmi_base64_verdict", vtype_stringptr, &bmi_base64_verdict },
473 { "bmi_deliver", vtype_int, &bmi_deliver },
474 #endif
475 { "body_linecount", vtype_int, &body_linecount },
476 { "body_zerocount", vtype_int, &body_zerocount },
477 { "bounce_recipient", vtype_stringptr, &bounce_recipient },
478 { "bounce_return_size_limit", vtype_int, &bounce_return_size_limit },
479 { "caller_gid", vtype_gid, &real_gid },
480 { "caller_uid", vtype_uid, &real_uid },
481 { "callout_address", vtype_stringptr, &callout_address },
482 { "compile_date", vtype_stringptr, &version_date },
483 { "compile_number", vtype_stringptr, &version_cnumber },
484 { "config_dir", vtype_stringptr, &config_main_directory },
485 { "config_file", vtype_stringptr, &config_main_filename },
486 { "csa_status", vtype_stringptr, &csa_status },
487 #ifdef EXPERIMENTAL_DCC
488 { "dcc_header", vtype_stringptr, &dcc_header },
489 { "dcc_result", vtype_stringptr, &dcc_result },
490 #endif
491 #ifndef DISABLE_DKIM
492 { "dkim_algo", vtype_dkim, (void *)DKIM_ALGO },
493 { "dkim_bodylength", vtype_dkim, (void *)DKIM_BODYLENGTH },
494 { "dkim_canon_body", vtype_dkim, (void *)DKIM_CANON_BODY },
495 { "dkim_canon_headers", vtype_dkim, (void *)DKIM_CANON_HEADERS },
496 { "dkim_copiedheaders", vtype_dkim, (void *)DKIM_COPIEDHEADERS },
497 { "dkim_created", vtype_dkim, (void *)DKIM_CREATED },
498 { "dkim_cur_signer", vtype_stringptr, &dkim_cur_signer },
499 { "dkim_domain", vtype_stringptr, &dkim_signing_domain },
500 { "dkim_expires", vtype_dkim, (void *)DKIM_EXPIRES },
501 { "dkim_headernames", vtype_dkim, (void *)DKIM_HEADERNAMES },
502 { "dkim_identity", vtype_dkim, (void *)DKIM_IDENTITY },
503 { "dkim_key_granularity",vtype_dkim, (void *)DKIM_KEY_GRANULARITY },
504 { "dkim_key_length", vtype_int, &dkim_key_length },
505 { "dkim_key_nosubdomains",vtype_dkim, (void *)DKIM_NOSUBDOMAINS },
506 { "dkim_key_notes", vtype_dkim, (void *)DKIM_KEY_NOTES },
507 { "dkim_key_srvtype", vtype_dkim, (void *)DKIM_KEY_SRVTYPE },
508 { "dkim_key_testing", vtype_dkim, (void *)DKIM_KEY_TESTING },
509 { "dkim_selector", vtype_stringptr, &dkim_signing_selector },
510 { "dkim_signers", vtype_stringptr, &dkim_signers },
511 { "dkim_verify_reason", vtype_dkim, (void *)DKIM_VERIFY_REASON },
512 { "dkim_verify_status", vtype_dkim, (void *)DKIM_VERIFY_STATUS},
513 #endif
514 #ifdef EXPERIMENTAL_DMARC
515 { "dmarc_ar_header", vtype_stringptr, &dmarc_ar_header },
516 { "dmarc_domain_policy", vtype_stringptr, &dmarc_domain_policy },
517 { "dmarc_status", vtype_stringptr, &dmarc_status },
518 { "dmarc_status_text", vtype_stringptr, &dmarc_status_text },
519 { "dmarc_used_domain", vtype_stringptr, &dmarc_used_domain },
520 #endif
521 { "dnslist_domain", vtype_stringptr, &dnslist_domain },
522 { "dnslist_matched", vtype_stringptr, &dnslist_matched },
523 { "dnslist_text", vtype_stringptr, &dnslist_text },
524 { "dnslist_value", vtype_stringptr, &dnslist_value },
525 { "domain", vtype_stringptr, &deliver_domain },
526 { "domain_data", vtype_stringptr, &deliver_domain_data },
527 #ifndef DISABLE_EVENT
528 { "event_data", vtype_stringptr, &event_data },
529
530 /*XXX want to use generic vars for as many of these as possible*/
531 { "event_defer_errno", vtype_int, &event_defer_errno },
532
533 { "event_name", vtype_stringptr, &event_name },
534 #endif
535 { "exim_gid", vtype_gid, &exim_gid },
536 { "exim_path", vtype_stringptr, &exim_path },
537 { "exim_uid", vtype_uid, &exim_uid },
538 { "exim_version", vtype_stringptr, &version_string },
539 { "headers_added", vtype_string_func, &fn_hdrs_added },
540 { "home", vtype_stringptr, &deliver_home },
541 { "host", vtype_stringptr, &deliver_host },
542 { "host_address", vtype_stringptr, &deliver_host_address },
543 { "host_data", vtype_stringptr, &host_data },
544 { "host_lookup_deferred",vtype_int, &host_lookup_deferred },
545 { "host_lookup_failed", vtype_int, &host_lookup_failed },
546 { "host_port", vtype_int, &deliver_host_port },
547 { "initial_cwd", vtype_stringptr, &initial_cwd },
548 { "inode", vtype_ino, &deliver_inode },
549 { "interface_address", vtype_stringptr, &interface_address },
550 { "interface_port", vtype_int, &interface_port },
551 { "item", vtype_stringptr, &iterate_item },
552 #ifdef LOOKUP_LDAP
553 { "ldap_dn", vtype_stringptr, &eldap_dn },
554 #endif
555 { "load_average", vtype_load_avg, NULL },
556 { "local_part", vtype_stringptr, &deliver_localpart },
557 { "local_part_data", vtype_stringptr, &deliver_localpart_data },
558 { "local_part_prefix", vtype_stringptr, &deliver_localpart_prefix },
559 { "local_part_suffix", vtype_stringptr, &deliver_localpart_suffix },
560 { "local_scan_data", vtype_stringptr, &local_scan_data },
561 { "local_user_gid", vtype_gid, &local_user_gid },
562 { "local_user_uid", vtype_uid, &local_user_uid },
563 { "localhost_number", vtype_int, &host_number },
564 { "log_inodes", vtype_pinodes, (void *)FALSE },
565 { "log_space", vtype_pspace, (void *)FALSE },
566 { "lookup_dnssec_authenticated",vtype_stringptr,&lookup_dnssec_authenticated},
567 { "mailstore_basename", vtype_stringptr, &mailstore_basename },
568 #ifdef WITH_CONTENT_SCAN
569 { "malware_name", vtype_stringptr, &malware_name },
570 #endif
571 { "max_received_linelength", vtype_int, &max_received_linelength },
572 { "message_age", vtype_int, &message_age },
573 { "message_body", vtype_msgbody, &message_body },
574 { "message_body_end", vtype_msgbody_end, &message_body_end },
575 { "message_body_size", vtype_int, &message_body_size },
576 { "message_exim_id", vtype_stringptr, &message_id },
577 { "message_headers", vtype_msgheaders, NULL },
578 { "message_headers_raw", vtype_msgheaders_raw, NULL },
579 { "message_id", vtype_stringptr, &message_id },
580 { "message_linecount", vtype_int, &message_linecount },
581 { "message_size", vtype_int, &message_size },
582 #ifdef SUPPORT_I18N
583 { "message_smtputf8", vtype_bool, &message_smtputf8 },
584 #endif
585 #ifdef WITH_CONTENT_SCAN
586 { "mime_anomaly_level", vtype_int, &mime_anomaly_level },
587 { "mime_anomaly_text", vtype_stringptr, &mime_anomaly_text },
588 { "mime_boundary", vtype_stringptr, &mime_boundary },
589 { "mime_charset", vtype_stringptr, &mime_charset },
590 { "mime_content_description", vtype_stringptr, &mime_content_description },
591 { "mime_content_disposition", vtype_stringptr, &mime_content_disposition },
592 { "mime_content_id", vtype_stringptr, &mime_content_id },
593 { "mime_content_size", vtype_int, &mime_content_size },
594 { "mime_content_transfer_encoding",vtype_stringptr, &mime_content_transfer_encoding },
595 { "mime_content_type", vtype_stringptr, &mime_content_type },
596 { "mime_decoded_filename", vtype_stringptr, &mime_decoded_filename },
597 { "mime_filename", vtype_stringptr, &mime_filename },
598 { "mime_is_coverletter", vtype_int, &mime_is_coverletter },
599 { "mime_is_multipart", vtype_int, &mime_is_multipart },
600 { "mime_is_rfc822", vtype_int, &mime_is_rfc822 },
601 { "mime_part_count", vtype_int, &mime_part_count },
602 #endif
603 { "n0", vtype_filter_int, &filter_n[0] },
604 { "n1", vtype_filter_int, &filter_n[1] },
605 { "n2", vtype_filter_int, &filter_n[2] },
606 { "n3", vtype_filter_int, &filter_n[3] },
607 { "n4", vtype_filter_int, &filter_n[4] },
608 { "n5", vtype_filter_int, &filter_n[5] },
609 { "n6", vtype_filter_int, &filter_n[6] },
610 { "n7", vtype_filter_int, &filter_n[7] },
611 { "n8", vtype_filter_int, &filter_n[8] },
612 { "n9", vtype_filter_int, &filter_n[9] },
613 { "original_domain", vtype_stringptr, &deliver_domain_orig },
614 { "original_local_part", vtype_stringptr, &deliver_localpart_orig },
615 { "originator_gid", vtype_gid, &originator_gid },
616 { "originator_uid", vtype_uid, &originator_uid },
617 { "parent_domain", vtype_stringptr, &deliver_domain_parent },
618 { "parent_local_part", vtype_stringptr, &deliver_localpart_parent },
619 { "pid", vtype_pid, NULL },
620 #ifndef DISABLE_PRDR
621 { "prdr_requested", vtype_bool, &prdr_requested },
622 #endif
623 { "primary_hostname", vtype_stringptr, &primary_hostname },
624 #if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS)
625 { "proxy_external_address",vtype_stringptr, &proxy_external_address },
626 { "proxy_external_port", vtype_int, &proxy_external_port },
627 { "proxy_local_address", vtype_stringptr, &proxy_local_address },
628 { "proxy_local_port", vtype_int, &proxy_local_port },
629 { "proxy_session", vtype_bool, &proxy_session },
630 #endif
631 { "prvscheck_address", vtype_stringptr, &prvscheck_address },
632 { "prvscheck_keynum", vtype_stringptr, &prvscheck_keynum },
633 { "prvscheck_result", vtype_stringptr, &prvscheck_result },
634 { "qualify_domain", vtype_stringptr, &qualify_domain_sender },
635 { "qualify_recipient", vtype_stringptr, &qualify_domain_recipient },
636 { "queue_name", vtype_stringptr, &queue_name },
637 { "rcpt_count", vtype_int, &rcpt_count },
638 { "rcpt_defer_count", vtype_int, &rcpt_defer_count },
639 { "rcpt_fail_count", vtype_int, &rcpt_fail_count },
640 { "received_count", vtype_int, &received_count },
641 { "received_for", vtype_stringptr, &received_for },
642 { "received_ip_address", vtype_stringptr, &interface_address },
643 { "received_port", vtype_int, &interface_port },
644 { "received_protocol", vtype_stringptr, &received_protocol },
645 { "received_time", vtype_int, &received_time },
646 { "recipient_data", vtype_stringptr, &recipient_data },
647 { "recipient_verify_failure",vtype_stringptr,&recipient_verify_failure },
648 { "recipients", vtype_string_func, &fn_recipients },
649 { "recipients_count", vtype_int, &recipients_count },
650 #ifdef WITH_CONTENT_SCAN
651 { "regex_match_string", vtype_stringptr, &regex_match_string },
652 #endif
653 { "reply_address", vtype_reply, NULL },
654 { "return_path", vtype_stringptr, &return_path },
655 { "return_size_limit", vtype_int, &bounce_return_size_limit },
656 { "router_name", vtype_stringptr, &router_name },
657 { "runrc", vtype_int, &runrc },
658 { "self_hostname", vtype_stringptr, &self_hostname },
659 { "sender_address", vtype_stringptr, &sender_address },
660 { "sender_address_data", vtype_stringptr, &sender_address_data },
661 { "sender_address_domain", vtype_domain, &sender_address },
662 { "sender_address_local_part", vtype_localpart, &sender_address },
663 { "sender_data", vtype_stringptr, &sender_data },
664 { "sender_fullhost", vtype_stringptr, &sender_fullhost },
665 { "sender_helo_dnssec", vtype_bool, &sender_helo_dnssec },
666 { "sender_helo_name", vtype_stringptr, &sender_helo_name },
667 { "sender_host_address", vtype_stringptr, &sender_host_address },
668 { "sender_host_authenticated",vtype_stringptr, &sender_host_authenticated },
669 { "sender_host_dnssec", vtype_bool, &sender_host_dnssec },
670 { "sender_host_name", vtype_host_lookup, NULL },
671 { "sender_host_port", vtype_int, &sender_host_port },
672 { "sender_ident", vtype_stringptr, &sender_ident },
673 { "sender_rate", vtype_stringptr, &sender_rate },
674 { "sender_rate_limit", vtype_stringptr, &sender_rate_limit },
675 { "sender_rate_period", vtype_stringptr, &sender_rate_period },
676 { "sender_rcvhost", vtype_stringptr, &sender_rcvhost },
677 { "sender_verify_failure",vtype_stringptr, &sender_verify_failure },
678 { "sending_ip_address", vtype_stringptr, &sending_ip_address },
679 { "sending_port", vtype_int, &sending_port },
680 { "smtp_active_hostname", vtype_stringptr, &smtp_active_hostname },
681 { "smtp_command", vtype_stringptr, &smtp_cmd_buffer },
682 { "smtp_command_argument", vtype_stringptr, &smtp_cmd_argument },
683 { "smtp_command_history", vtype_string_func, &smtp_cmd_hist },
684 { "smtp_count_at_connection_start", vtype_int, &smtp_accept_count },
685 { "smtp_notquit_reason", vtype_stringptr, &smtp_notquit_reason },
686 { "sn0", vtype_filter_int, &filter_sn[0] },
687 { "sn1", vtype_filter_int, &filter_sn[1] },
688 { "sn2", vtype_filter_int, &filter_sn[2] },
689 { "sn3", vtype_filter_int, &filter_sn[3] },
690 { "sn4", vtype_filter_int, &filter_sn[4] },
691 { "sn5", vtype_filter_int, &filter_sn[5] },
692 { "sn6", vtype_filter_int, &filter_sn[6] },
693 { "sn7", vtype_filter_int, &filter_sn[7] },
694 { "sn8", vtype_filter_int, &filter_sn[8] },
695 { "sn9", vtype_filter_int, &filter_sn[9] },
696 #ifdef WITH_CONTENT_SCAN
697 { "spam_action", vtype_stringptr, &spam_action },
698 { "spam_bar", vtype_stringptr, &spam_bar },
699 { "spam_report", vtype_stringptr, &spam_report },
700 { "spam_score", vtype_stringptr, &spam_score },
701 { "spam_score_int", vtype_stringptr, &spam_score_int },
702 #endif
703 #ifdef EXPERIMENTAL_SPF
704 { "spf_guess", vtype_stringptr, &spf_guess },
705 { "spf_header_comment", vtype_stringptr, &spf_header_comment },
706 { "spf_received", vtype_stringptr, &spf_received },
707 { "spf_result", vtype_stringptr, &spf_result },
708 { "spf_smtp_comment", vtype_stringptr, &spf_smtp_comment },
709 #endif
710 { "spool_directory", vtype_stringptr, &spool_directory },
711 { "spool_inodes", vtype_pinodes, (void *)TRUE },
712 { "spool_space", vtype_pspace, (void *)TRUE },
713 #ifdef EXPERIMENTAL_SRS
714 { "srs_db_address", vtype_stringptr, &srs_db_address },
715 { "srs_db_key", vtype_stringptr, &srs_db_key },
716 { "srs_orig_recipient", vtype_stringptr, &srs_orig_recipient },
717 { "srs_orig_sender", vtype_stringptr, &srs_orig_sender },
718 { "srs_recipient", vtype_stringptr, &srs_recipient },
719 { "srs_status", vtype_stringptr, &srs_status },
720 #endif
721 { "thisaddress", vtype_stringptr, &filter_thisaddress },
722
723 /* The non-(in,out) variables are now deprecated */
724 { "tls_bits", vtype_int, &tls_in.bits },
725 { "tls_certificate_verified", vtype_int, &tls_in.certificate_verified },
726 { "tls_cipher", vtype_stringptr, &tls_in.cipher },
727
728 { "tls_in_bits", vtype_int, &tls_in.bits },
729 { "tls_in_certificate_verified", vtype_int, &tls_in.certificate_verified },
730 { "tls_in_cipher", vtype_stringptr, &tls_in.cipher },
731 { "tls_in_ocsp", vtype_int, &tls_in.ocsp },
732 { "tls_in_ourcert", vtype_cert, &tls_in.ourcert },
733 { "tls_in_peercert", vtype_cert, &tls_in.peercert },
734 { "tls_in_peerdn", vtype_stringptr, &tls_in.peerdn },
735 #if defined(SUPPORT_TLS)
736 { "tls_in_sni", vtype_stringptr, &tls_in.sni },
737 #endif
738 { "tls_out_bits", vtype_int, &tls_out.bits },
739 { "tls_out_certificate_verified", vtype_int,&tls_out.certificate_verified },
740 { "tls_out_cipher", vtype_stringptr, &tls_out.cipher },
741 #ifdef EXPERIMENTAL_DANE
742 { "tls_out_dane", vtype_bool, &tls_out.dane_verified },
743 #endif
744 { "tls_out_ocsp", vtype_int, &tls_out.ocsp },
745 { "tls_out_ourcert", vtype_cert, &tls_out.ourcert },
746 { "tls_out_peercert", vtype_cert, &tls_out.peercert },
747 { "tls_out_peerdn", vtype_stringptr, &tls_out.peerdn },
748 #if defined(SUPPORT_TLS)
749 { "tls_out_sni", vtype_stringptr, &tls_out.sni },
750 #endif
751 #ifdef EXPERIMENTAL_DANE
752 { "tls_out_tlsa_usage", vtype_int, &tls_out.tlsa_usage },
753 #endif
754
755 { "tls_peerdn", vtype_stringptr, &tls_in.peerdn }, /* mind the alphabetical order! */
756 #if defined(SUPPORT_TLS)
757 { "tls_sni", vtype_stringptr, &tls_in.sni }, /* mind the alphabetical order! */
758 #endif
759
760 { "tod_bsdinbox", vtype_todbsdin, NULL },
761 { "tod_epoch", vtype_tode, NULL },
762 { "tod_epoch_l", vtype_todel, NULL },
763 { "tod_full", vtype_todf, NULL },
764 { "tod_log", vtype_todl, NULL },
765 { "tod_logfile", vtype_todlf, NULL },
766 { "tod_zone", vtype_todzone, NULL },
767 { "tod_zulu", vtype_todzulu, NULL },
768 { "transport_name", vtype_stringptr, &transport_name },
769 { "value", vtype_stringptr, &lookup_value },
770 { "verify_mode", vtype_stringptr, &verify_mode },
771 { "version_number", vtype_stringptr, &version_string },
772 { "warn_message_delay", vtype_stringptr, &warnmsg_delay },
773 { "warn_message_recipient",vtype_stringptr, &warnmsg_recipients },
774 { "warn_message_recipients",vtype_stringptr,&warnmsg_recipients },
775 { "warnmsg_delay", vtype_stringptr, &warnmsg_delay },
776 { "warnmsg_recipient", vtype_stringptr, &warnmsg_recipients },
777 { "warnmsg_recipients", vtype_stringptr, &warnmsg_recipients }
778 };
779
780 static int var_table_size = nelem(var_table);
781 static uschar var_buffer[256];
782 static BOOL malformed_header;
783
784 /* For textual hashes */
785
786 static const char *hashcodes = "abcdefghijklmnopqrtsuvwxyz"
787 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
788 "0123456789";
789
790 enum { HMAC_MD5, HMAC_SHA1 };
791
792 /* For numeric hashes */
793
794 static unsigned int prime[] = {
795 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
796 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
797 73, 79, 83, 89, 97, 101, 103, 107, 109, 113};
798
799 /* For printing modes in symbolic form */
800
801 static uschar *mtable_normal[] =
802 { US"---", US"--x", US"-w-", US"-wx", US"r--", US"r-x", US"rw-", US"rwx" };
803
804 static uschar *mtable_setid[] =
805 { US"--S", US"--s", US"-wS", US"-ws", US"r-S", US"r-s", US"rwS", US"rws" };
806
807 static uschar *mtable_sticky[] =
808 { US"--T", US"--t", US"-wT", US"-wt", US"r-T", US"r-t", US"rwT", US"rwt" };
809
810
811
812 /*************************************************
813 * Tables for UTF-8 support *
814 *************************************************/
815
816 /* Table of the number of extra characters, indexed by the first character
817 masked with 0x3f. The highest number for a valid UTF-8 character is in fact
818 0x3d. */
819
820 static uschar utf8_table1[] = {
821 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
822 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
823 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
824 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
825
826 /* These are the masks for the data bits in the first byte of a character,
827 indexed by the number of additional bytes. */
828
829 static int utf8_table2[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
830
831 /* Get the next UTF-8 character, advancing the pointer. */
832
833 #define GETUTF8INC(c, ptr) \
834 c = *ptr++; \
835 if ((c & 0xc0) == 0xc0) \
836 { \
837 int a = utf8_table1[c & 0x3f]; /* Number of additional bytes */ \
838 int s = 6*a; \
839 c = (c & utf8_table2[a]) << s; \
840 while (a-- > 0) \
841 { \
842 s -= 6; \
843 c |= (*ptr++ & 0x3f) << s; \
844 } \
845 }
846
847
848
849 static uschar * base32_chars = US"abcdefghijklmnopqrstuvwxyz234567";
850
851 /*************************************************
852 * Binary chop search on a table *
853 *************************************************/
854
855 /* This is used for matching expansion items and operators.
856
857 Arguments:
858 name the name that is being sought
859 table the table to search
860 table_size the number of items in the table
861
862 Returns: the offset in the table, or -1
863 */
864
865 static int
866 chop_match(uschar *name, uschar **table, int table_size)
867 {
868 uschar **bot = table;
869 uschar **top = table + table_size;
870
871 while (top > bot)
872 {
873 uschar **mid = bot + (top - bot)/2;
874 int c = Ustrcmp(name, *mid);
875 if (c == 0) return mid - table;
876 if (c > 0) bot = mid + 1; else top = mid;
877 }
878
879 return -1;
880 }
881
882
883
884 /*************************************************
885 * Check a condition string *
886 *************************************************/
887
888 /* This function is called to expand a string, and test the result for a "true"
889 or "false" value. Failure of the expansion yields FALSE; logged unless it was a
890 forced fail or lookup defer.
891
892 We used to release all store used, but this is not not safe due
893 to ${dlfunc } and ${acl }. In any case expand_string_internal()
894 is reasonably careful to release what it can.
895
896 The actual false-value tests should be replicated for ECOND_BOOL_LAX.
897
898 Arguments:
899 condition the condition string
900 m1 text to be incorporated in panic error
901 m2 ditto
902
903 Returns: TRUE if condition is met, FALSE if not
904 */
905
906 BOOL
907 expand_check_condition(uschar *condition, uschar *m1, uschar *m2)
908 {
909 int rc;
910 uschar *ss = expand_string(condition);
911 if (ss == NULL)
912 {
913 if (!expand_string_forcedfail && !search_find_defer)
914 log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand condition \"%s\" "
915 "for %s %s: %s", condition, m1, m2, expand_string_message);
916 return FALSE;
917 }
918 rc = ss[0] != 0 && Ustrcmp(ss, "0") != 0 && strcmpic(ss, US"no") != 0 &&
919 strcmpic(ss, US"false") != 0;
920 return rc;
921 }
922
923
924
925
926 /*************************************************
927 * Pseudo-random number generation *
928 *************************************************/
929
930 /* Pseudo-random number generation. The result is not "expected" to be
931 cryptographically strong but not so weak that someone will shoot themselves
932 in the foot using it as a nonce in some email header scheme or whatever
933 weirdness they'll twist this into. The result should ideally handle fork().
934
935 However, if we're stuck unable to provide this, then we'll fall back to
936 appallingly bad randomness.
937
938 If SUPPORT_TLS is defined then this will not be used except as an emergency
939 fallback.
940
941 Arguments:
942 max range maximum
943 Returns a random number in range [0, max-1]
944 */
945
946 #ifdef SUPPORT_TLS
947 # define vaguely_random_number vaguely_random_number_fallback
948 #endif
949 int
950 vaguely_random_number(int max)
951 {
952 #ifdef SUPPORT_TLS
953 # undef vaguely_random_number
954 #endif
955 static pid_t pid = 0;
956 pid_t p2;
957 #if defined(HAVE_SRANDOM) && !defined(HAVE_SRANDOMDEV)
958 struct timeval tv;
959 #endif
960
961 p2 = getpid();
962 if (p2 != pid)
963 {
964 if (pid != 0)
965 {
966
967 #ifdef HAVE_ARC4RANDOM
968 /* cryptographically strong randomness, common on *BSD platforms, not
969 so much elsewhere. Alas. */
970 #ifndef NOT_HAVE_ARC4RANDOM_STIR
971 arc4random_stir();
972 #endif
973 #elif defined(HAVE_SRANDOM) || defined(HAVE_SRANDOMDEV)
974 #ifdef HAVE_SRANDOMDEV
975 /* uses random(4) for seeding */
976 srandomdev();
977 #else
978 gettimeofday(&tv, NULL);
979 srandom(tv.tv_sec | tv.tv_usec | getpid());
980 #endif
981 #else
982 /* Poor randomness and no seeding here */
983 #endif
984
985 }
986 pid = p2;
987 }
988
989 #ifdef HAVE_ARC4RANDOM
990 return arc4random() % max;
991 #elif defined(HAVE_SRANDOM) || defined(HAVE_SRANDOMDEV)
992 return random() % max;
993 #else
994 /* This one returns a 16-bit number, definitely not crypto-strong */
995 return random_number(max);
996 #endif
997 }
998
999
1000
1001
1002 /*************************************************
1003 * Pick out a name from a string *
1004 *************************************************/
1005
1006 /* If the name is too long, it is silently truncated.
1007
1008 Arguments:
1009 name points to a buffer into which to put the name
1010 max is the length of the buffer
1011 s points to the first alphabetic character of the name
1012 extras chars other than alphanumerics to permit
1013
1014 Returns: pointer to the first character after the name
1015
1016 Note: The test for *s != 0 in the while loop is necessary because
1017 Ustrchr() yields non-NULL if the character is zero (which is not something
1018 I expected). */
1019
1020 static const uschar *
1021 read_name(uschar *name, int max, const uschar *s, uschar *extras)
1022 {
1023 int ptr = 0;
1024 while (*s != 0 && (isalnum(*s) || Ustrchr(extras, *s) != NULL))
1025 {
1026 if (ptr < max-1) name[ptr++] = *s;
1027 s++;
1028 }
1029 name[ptr] = 0;
1030 return s;
1031 }
1032
1033
1034
1035 /*************************************************
1036 * Pick out the rest of a header name *
1037 *************************************************/
1038
1039 /* A variable name starting $header_ (or just $h_ for those who like
1040 abbreviations) might not be the complete header name because headers can
1041 contain any printing characters in their names, except ':'. This function is
1042 called to read the rest of the name, chop h[eader]_ off the front, and put ':'
1043 on the end, if the name was terminated by white space.
1044
1045 Arguments:
1046 name points to a buffer in which the name read so far exists
1047 max is the length of the buffer
1048 s points to the first character after the name so far, i.e. the
1049 first non-alphameric character after $header_xxxxx
1050
1051 Returns: a pointer to the first character after the header name
1052 */
1053
1054 static const uschar *
1055 read_header_name(uschar *name, int max, const uschar *s)
1056 {
1057 int prelen = Ustrchr(name, '_') - name + 1;
1058 int ptr = Ustrlen(name) - prelen;
1059 if (ptr > 0) memmove(name, name+prelen, ptr);
1060 while (mac_isgraph(*s) && *s != ':')
1061 {
1062 if (ptr < max-1) name[ptr++] = *s;
1063 s++;
1064 }
1065 if (*s == ':') s++;
1066 name[ptr++] = ':';
1067 name[ptr] = 0;
1068 return s;
1069 }
1070
1071
1072
1073 /*************************************************
1074 * Pick out a number from a string *
1075 *************************************************/
1076
1077 /* Arguments:
1078 n points to an integer into which to put the number
1079 s points to the first digit of the number
1080
1081 Returns: a pointer to the character after the last digit
1082 */
1083 /*XXX consider expanding to int_eximarith_t. But the test for
1084 "overbig numbers" in 0002 still needs to overflow it. */
1085
1086 static uschar *
1087 read_number(int *n, uschar *s)
1088 {
1089 *n = 0;
1090 while (isdigit(*s)) *n = *n * 10 + (*s++ - '0');
1091 return s;
1092 }
1093
1094 static const uschar *
1095 read_cnumber(int *n, const uschar *s)
1096 {
1097 *n = 0;
1098 while (isdigit(*s)) *n = *n * 10 + (*s++ - '0');
1099 return s;
1100 }
1101
1102
1103
1104 /*************************************************
1105 * Extract keyed subfield from a string *
1106 *************************************************/
1107
1108 /* The yield is in dynamic store; NULL means that the key was not found.
1109
1110 Arguments:
1111 key points to the name of the key
1112 s points to the string from which to extract the subfield
1113
1114 Returns: NULL if the subfield was not found, or
1115 a pointer to the subfield's data
1116 */
1117
1118 static uschar *
1119 expand_getkeyed(uschar *key, const uschar *s)
1120 {
1121 int length = Ustrlen(key);
1122 while (isspace(*s)) s++;
1123
1124 /* Loop to search for the key */
1125
1126 while (*s != 0)
1127 {
1128 int dkeylength;
1129 uschar *data;
1130 const uschar *dkey = s;
1131
1132 while (*s != 0 && *s != '=' && !isspace(*s)) s++;
1133 dkeylength = s - dkey;
1134 while (isspace(*s)) s++;
1135 if (*s == '=') while (isspace((*(++s))));
1136
1137 data = string_dequote(&s);
1138 if (length == dkeylength && strncmpic(key, dkey, length) == 0)
1139 return data;
1140
1141 while (isspace(*s)) s++;
1142 }
1143
1144 return NULL;
1145 }
1146
1147
1148
1149 static var_entry *
1150 find_var_ent(uschar * name)
1151 {
1152 int first = 0;
1153 int last = var_table_size;
1154
1155 while (last > first)
1156 {
1157 int middle = (first + last)/2;
1158 int c = Ustrcmp(name, var_table[middle].name);
1159
1160 if (c > 0) { first = middle + 1; continue; }
1161 if (c < 0) { last = middle; continue; }
1162 return &var_table[middle];
1163 }
1164 return NULL;
1165 }
1166
1167 /*************************************************
1168 * Extract numbered subfield from string *
1169 *************************************************/
1170
1171 /* Extracts a numbered field from a string that is divided by tokens - for
1172 example a line from /etc/passwd is divided by colon characters. First field is
1173 numbered one. Negative arguments count from the right. Zero returns the whole
1174 string. Returns NULL if there are insufficient tokens in the string
1175
1176 ***WARNING***
1177 Modifies final argument - this is a dynamically generated string, so that's OK.
1178
1179 Arguments:
1180 field number of field to be extracted,
1181 first field = 1, whole string = 0, last field = -1
1182 separators characters that are used to break string into tokens
1183 s points to the string from which to extract the subfield
1184
1185 Returns: NULL if the field was not found,
1186 a pointer to the field's data inside s (modified to add 0)
1187 */
1188
1189 static uschar *
1190 expand_gettokened (int field, uschar *separators, uschar *s)
1191 {
1192 int sep = 1;
1193 int count;
1194 uschar *ss = s;
1195 uschar *fieldtext = NULL;
1196
1197 if (field == 0) return s;
1198
1199 /* Break the line up into fields in place; for field > 0 we stop when we have
1200 done the number of fields we want. For field < 0 we continue till the end of
1201 the string, counting the number of fields. */
1202
1203 count = (field > 0)? field : INT_MAX;
1204
1205 while (count-- > 0)
1206 {
1207 size_t len;
1208
1209 /* Previous field was the last one in the string. For a positive field
1210 number, this means there are not enough fields. For a negative field number,
1211 check that there are enough, and scan back to find the one that is wanted. */
1212
1213 if (sep == 0)
1214 {
1215 if (field > 0 || (-field) > (INT_MAX - count - 1)) return NULL;
1216 if ((-field) == (INT_MAX - count - 1)) return s;
1217 while (field++ < 0)
1218 {
1219 ss--;
1220 while (ss[-1] != 0) ss--;
1221 }
1222 fieldtext = ss;
1223 break;
1224 }
1225
1226 /* Previous field was not last in the string; save its start and put a
1227 zero at its end. */
1228
1229 fieldtext = ss;
1230 len = Ustrcspn(ss, separators);
1231 sep = ss[len];
1232 ss[len] = 0;
1233 ss += len + 1;
1234 }
1235
1236 return fieldtext;
1237 }
1238
1239
1240 static uschar *
1241 expand_getlistele(int field, const uschar * list)
1242 {
1243 const uschar * tlist= list;
1244 int sep= 0;
1245 uschar dummy;
1246
1247 if(field<0)
1248 {
1249 for(field++; string_nextinlist(&tlist, &sep, &dummy, 1); ) field++;
1250 sep= 0;
1251 }
1252 if(field==0) return NULL;
1253 while(--field>0 && (string_nextinlist(&list, &sep, &dummy, 1))) ;
1254 return string_nextinlist(&list, &sep, NULL, 0);
1255 }
1256
1257
1258 /* Certificate fields, by name. Worry about by-OID later */
1259 /* Names are chosen to not have common prefixes */
1260
1261 #ifdef SUPPORT_TLS
1262 typedef struct
1263 {
1264 uschar * name;
1265 int namelen;
1266 uschar * (*getfn)(void * cert, uschar * mod);
1267 } certfield;
1268 static certfield certfields[] =
1269 { /* linear search; no special order */
1270 { US"version", 7, &tls_cert_version },
1271 { US"serial_number", 13, &tls_cert_serial_number },
1272 { US"subject", 7, &tls_cert_subject },
1273 { US"notbefore", 9, &tls_cert_not_before },
1274 { US"notafter", 8, &tls_cert_not_after },
1275 { US"issuer", 6, &tls_cert_issuer },
1276 { US"signature", 9, &tls_cert_signature },
1277 { US"sig_algorithm", 13, &tls_cert_signature_algorithm },
1278 { US"subj_altname", 12, &tls_cert_subject_altname },
1279 { US"ocsp_uri", 8, &tls_cert_ocsp_uri },
1280 { US"crl_uri", 7, &tls_cert_crl_uri },
1281 };
1282
1283 static uschar *
1284 expand_getcertele(uschar * field, uschar * certvar)
1285 {
1286 var_entry * vp;
1287 certfield * cp;
1288
1289 if (!(vp = find_var_ent(certvar)))
1290 {
1291 expand_string_message =
1292 string_sprintf("no variable named \"%s\"", certvar);
1293 return NULL; /* Unknown variable name */
1294 }
1295 /* NB this stops us passing certs around in variable. Might
1296 want to do that in future */
1297 if (vp->type != vtype_cert)
1298 {
1299 expand_string_message =
1300 string_sprintf("\"%s\" is not a certificate", certvar);
1301 return NULL; /* Unknown variable name */
1302 }
1303 if (!*(void **)vp->value)
1304 return NULL;
1305
1306 if (*field >= '0' && *field <= '9')
1307 return tls_cert_ext_by_oid(*(void **)vp->value, field, 0);
1308
1309 for(cp = certfields;
1310 cp < certfields + nelem(certfields);
1311 cp++)
1312 if (Ustrncmp(cp->name, field, cp->namelen) == 0)
1313 {
1314 uschar * modifier = *(field += cp->namelen) == ','
1315 ? ++field : NULL;
1316 return (*cp->getfn)( *(void **)vp->value, modifier );
1317 }
1318
1319 expand_string_message =
1320 string_sprintf("bad field selector \"%s\" for certextract", field);
1321 return NULL;
1322 }
1323 #endif /*SUPPORT_TLS*/
1324
1325 /*************************************************
1326 * Extract a substring from a string *
1327 *************************************************/
1328
1329 /* Perform the ${substr or ${length expansion operations.
1330
1331 Arguments:
1332 subject the input string
1333 value1 the offset from the start of the input string to the start of
1334 the output string; if negative, count from the right.
1335 value2 the length of the output string, or negative (-1) for unset
1336 if value1 is positive, unset means "all after"
1337 if value1 is negative, unset means "all before"
1338 len set to the length of the returned string
1339
1340 Returns: pointer to the output string, or NULL if there is an error
1341 */
1342
1343 static uschar *
1344 extract_substr(uschar *subject, int value1, int value2, int *len)
1345 {
1346 int sublen = Ustrlen(subject);
1347
1348 if (value1 < 0) /* count from right */
1349 {
1350 value1 += sublen;
1351
1352 /* If the position is before the start, skip to the start, and adjust the
1353 length. If the length ends up negative, the substring is null because nothing
1354 can precede. This falls out naturally when the length is unset, meaning "all
1355 to the left". */
1356
1357 if (value1 < 0)
1358 {
1359 value2 += value1;
1360 if (value2 < 0) value2 = 0;
1361 value1 = 0;
1362 }
1363
1364 /* Otherwise an unset length => characters before value1 */
1365
1366 else if (value2 < 0)
1367 {
1368 value2 = value1;
1369 value1 = 0;
1370 }
1371 }
1372
1373 /* For a non-negative offset, if the starting position is past the end of the
1374 string, the result will be the null string. Otherwise, an unset length means
1375 "rest"; just set it to the maximum - it will be cut down below if necessary. */
1376
1377 else
1378 {
1379 if (value1 > sublen)
1380 {
1381 value1 = sublen;
1382 value2 = 0;
1383 }
1384 else if (value2 < 0) value2 = sublen;
1385 }
1386
1387 /* Cut the length down to the maximum possible for the offset value, and get
1388 the required characters. */
1389
1390 if (value1 + value2 > sublen) value2 = sublen - value1;
1391 *len = value2;
1392 return subject + value1;
1393 }
1394
1395
1396
1397
1398 /*************************************************
1399 * Old-style hash of a string *
1400 *************************************************/
1401
1402 /* Perform the ${hash expansion operation.
1403
1404 Arguments:
1405 subject the input string (an expanded substring)
1406 value1 the length of the output string; if greater or equal to the
1407 length of the input string, the input string is returned
1408 value2 the number of hash characters to use, or 26 if negative
1409 len set to the length of the returned string
1410
1411 Returns: pointer to the output string, or NULL if there is an error
1412 */
1413
1414 static uschar *
1415 compute_hash(uschar *subject, int value1, int value2, int *len)
1416 {
1417 int sublen = Ustrlen(subject);
1418
1419 if (value2 < 0) value2 = 26;
1420 else if (value2 > Ustrlen(hashcodes))
1421 {
1422 expand_string_message =
1423 string_sprintf("hash count \"%d\" too big", value2);
1424 return NULL;
1425 }
1426
1427 /* Calculate the hash text. We know it is shorter than the original string, so
1428 can safely place it in subject[] (we know that subject is always itself an
1429 expanded substring). */
1430
1431 if (value1 < sublen)
1432 {
1433 int c;
1434 int i = 0;
1435 int j = value1;
1436 while ((c = (subject[j])) != 0)
1437 {
1438 int shift = (c + j++) & 7;
1439 subject[i] ^= (c << shift) | (c >> (8-shift));
1440 if (++i >= value1) i = 0;
1441 }
1442 for (i = 0; i < value1; i++)
1443 subject[i] = hashcodes[(subject[i]) % value2];
1444 }
1445 else value1 = sublen;
1446
1447 *len = value1;
1448 return subject;
1449 }
1450
1451
1452
1453
1454 /*************************************************
1455 * Numeric hash of a string *
1456 *************************************************/
1457
1458 /* Perform the ${nhash expansion operation. The first characters of the
1459 string are treated as most important, and get the highest prime numbers.
1460
1461 Arguments:
1462 subject the input string
1463 value1 the maximum value of the first part of the result
1464 value2 the maximum value of the second part of the result,
1465 or negative to produce only a one-part result
1466 len set to the length of the returned string
1467
1468 Returns: pointer to the output string, or NULL if there is an error.
1469 */
1470
1471 static uschar *
1472 compute_nhash (uschar *subject, int value1, int value2, int *len)
1473 {
1474 uschar *s = subject;
1475 int i = 0;
1476 unsigned long int total = 0; /* no overflow */
1477
1478 while (*s != 0)
1479 {
1480 if (i == 0) i = nelem(prime) - 1;
1481 total += prime[i--] * (unsigned int)(*s++);
1482 }
1483
1484 /* If value2 is unset, just compute one number */
1485
1486 if (value2 < 0)
1487 {
1488 s = string_sprintf("%d", total % value1);
1489 }
1490
1491 /* Otherwise do a div/mod hash */
1492
1493 else
1494 {
1495 total = total % (value1 * value2);
1496 s = string_sprintf("%d/%d", total/value2, total % value2);
1497 }
1498
1499 *len = Ustrlen(s);
1500 return s;
1501 }
1502
1503
1504
1505
1506
1507 /*************************************************
1508 * Find the value of a header or headers *
1509 *************************************************/
1510
1511 /* Multiple instances of the same header get concatenated, and this function
1512 can also return a concatenation of all the header lines. When concatenating
1513 specific headers that contain lists of addresses, a comma is inserted between
1514 them. Otherwise we use a straight concatenation. Because some messages can have
1515 pathologically large number of lines, there is a limit on the length that is
1516 returned. Also, to avoid massive store use which would result from using
1517 string_cat() as it copies and extends strings, we do a preliminary pass to find
1518 out exactly how much store will be needed. On "normal" messages this will be
1519 pretty trivial.
1520
1521 Arguments:
1522 name the name of the header, without the leading $header_ or $h_,
1523 or NULL if a concatenation of all headers is required
1524 exists_only TRUE if called from a def: test; don't need to build a string;
1525 just return a string that is not "" and not "0" if the header
1526 exists
1527 newsize return the size of memory block that was obtained; may be NULL
1528 if exists_only is TRUE
1529 want_raw TRUE if called for $rh_ or $rheader_ variables; no processing,
1530 other than concatenating, will be done on the header. Also used
1531 for $message_headers_raw.
1532 charset name of charset to translate MIME words to; used only if
1533 want_raw is false; if NULL, no translation is done (this is
1534 used for $bh_ and $bheader_)
1535
1536 Returns: NULL if the header does not exist, else a pointer to a new
1537 store block
1538 */
1539
1540 static uschar *
1541 find_header(uschar *name, BOOL exists_only, int *newsize, BOOL want_raw,
1542 uschar *charset)
1543 {
1544 BOOL found = name == NULL;
1545 int comma = 0;
1546 int len = found? 0 : Ustrlen(name);
1547 int i;
1548 uschar *yield = NULL;
1549 uschar *ptr = NULL;
1550
1551 /* Loop for two passes - saves code repetition */
1552
1553 for (i = 0; i < 2; i++)
1554 {
1555 int size = 0;
1556 header_line *h;
1557
1558 for (h = header_list; size < header_insert_maxlen && h; h = h->next)
1559 if (h->type != htype_old && h->text) /* NULL => Received: placeholder */
1560 if (!name || (len <= h->slen && strncmpic(name, h->text, len) == 0))
1561 {
1562 int ilen;
1563 uschar *t;
1564
1565 if (exists_only) return US"1"; /* don't need actual string */
1566 found = TRUE;
1567 t = h->text + len; /* text to insert */
1568 if (!want_raw) /* unless wanted raw, */
1569 while (isspace(*t)) t++; /* remove leading white space */
1570 ilen = h->slen - (t - h->text); /* length to insert */
1571
1572 /* Unless wanted raw, remove trailing whitespace, including the
1573 newline. */
1574
1575 if (!want_raw)
1576 while (ilen > 0 && isspace(t[ilen-1])) ilen--;
1577
1578 /* Set comma = 1 if handling a single header and it's one of those
1579 that contains an address list, except when asked for raw headers. Only
1580 need to do this once. */
1581
1582 if (!want_raw && name && comma == 0 &&
1583 Ustrchr("BCFRST", h->type) != NULL)
1584 comma = 1;
1585
1586 /* First pass - compute total store needed; second pass - compute
1587 total store used, including this header. */
1588
1589 size += ilen + comma + 1; /* +1 for the newline */
1590
1591 /* Second pass - concatenate the data, up to a maximum. Note that
1592 the loop stops when size hits the limit. */
1593
1594 if (i != 0)
1595 {
1596 if (size > header_insert_maxlen)
1597 {
1598 ilen -= size - header_insert_maxlen - 1;
1599 comma = 0;
1600 }
1601 Ustrncpy(ptr, t, ilen);
1602 ptr += ilen;
1603
1604 /* For a non-raw header, put in the comma if needed, then add
1605 back the newline we removed above, provided there was some text in
1606 the header. */
1607
1608 if (!want_raw && ilen > 0)
1609 {
1610 if (comma != 0) *ptr++ = ',';
1611 *ptr++ = '\n';
1612 }
1613 }
1614 }
1615
1616 /* At end of first pass, return NULL if no header found. Then truncate size
1617 if necessary, and get the buffer to hold the data, returning the buffer size.
1618 */
1619
1620 if (i == 0)
1621 {
1622 if (!found) return NULL;
1623 if (size > header_insert_maxlen) size = header_insert_maxlen;
1624 *newsize = size + 1;
1625 ptr = yield = store_get(*newsize);
1626 }
1627 }
1628
1629 /* That's all we do for raw header expansion. */
1630
1631 if (want_raw)
1632 *ptr = 0;
1633
1634 /* Otherwise, remove a final newline and a redundant added comma. Then we do
1635 RFC 2047 decoding, translating the charset if requested. The rfc2047_decode2()
1636 function can return an error with decoded data if the charset translation
1637 fails. If decoding fails, it returns NULL. */
1638
1639 else
1640 {
1641 uschar *decoded, *error;
1642 if (ptr > yield && ptr[-1] == '\n') ptr--;
1643 if (ptr > yield && comma != 0 && ptr[-1] == ',') ptr--;
1644 *ptr = 0;
1645 decoded = rfc2047_decode2(yield, check_rfc2047_length, charset, '?', NULL,
1646 newsize, &error);
1647 if (error != NULL)
1648 {
1649 DEBUG(D_any) debug_printf("*** error in RFC 2047 decoding: %s\n"
1650 " input was: %s\n", error, yield);
1651 }
1652 if (decoded != NULL) yield = decoded;
1653 }
1654
1655 return yield;
1656 }
1657
1658
1659
1660
1661 /*************************************************
1662 * Return list of recipients *
1663 *************************************************/
1664 /* A recipients list is available only during system message filtering,
1665 during ACL processing after DATA, and while expanding pipe commands
1666 generated from a system filter, but not elsewhere. */
1667
1668 static uschar *
1669 fn_recipients(void)
1670 {
1671 if (!enable_dollar_recipients) return NULL; else
1672 {
1673 int size = 128;
1674 int ptr = 0;
1675 int i;
1676 uschar * s = store_get(size);
1677 for (i = 0; i < recipients_count; i++)
1678 {
1679 if (i != 0) s = string_catn(s, &size, &ptr, US", ", 2);
1680 s = string_cat(s, &size, &ptr, recipients_list[i].address);
1681 }
1682 s[ptr] = 0; /* string_cat() leaves room */
1683 return s;
1684 }
1685 }
1686
1687
1688 /*************************************************
1689 * Find value of a variable *
1690 *************************************************/
1691
1692 /* The table of variables is kept in alphabetic order, so we can search it
1693 using a binary chop. The "choplen" variable is nothing to do with the binary
1694 chop.
1695
1696 Arguments:
1697 name the name of the variable being sought
1698 exists_only TRUE if this is a def: test; passed on to find_header()
1699 skipping TRUE => skip any processing evaluation; this is not the same as
1700 exists_only because def: may test for values that are first
1701 evaluated here
1702 newsize pointer to an int which is initially zero; if the answer is in
1703 a new memory buffer, *newsize is set to its size
1704
1705 Returns: NULL if the variable does not exist, or
1706 a pointer to the variable's contents, or
1707 something non-NULL if exists_only is TRUE
1708 */
1709
1710 static uschar *
1711 find_variable(uschar *name, BOOL exists_only, BOOL skipping, int *newsize)
1712 {
1713 var_entry * vp;
1714 uschar *s, *domain;
1715 uschar **ss;
1716 void * val;
1717
1718 /* Handle ACL variables, whose names are of the form acl_cxxx or acl_mxxx.
1719 Originally, xxx had to be a number in the range 0-9 (later 0-19), but from
1720 release 4.64 onwards arbitrary names are permitted, as long as the first 5
1721 characters are acl_c or acl_m and the sixth is either a digit or an underscore
1722 (this gave backwards compatibility at the changeover). There may be built-in
1723 variables whose names start acl_ but they should never start in this way. This
1724 slightly messy specification is a consequence of the history, needless to say.
1725
1726 If an ACL variable does not exist, treat it as empty, unless strict_acl_vars is
1727 set, in which case give an error. */
1728
1729 if ((Ustrncmp(name, "acl_c", 5) == 0 || Ustrncmp(name, "acl_m", 5) == 0) &&
1730 !isalpha(name[5]))
1731 {
1732 tree_node *node =
1733 tree_search((name[4] == 'c')? acl_var_c : acl_var_m, name + 4);
1734 return node ? node->data.ptr : strict_acl_vars ? NULL : US"";
1735 }
1736
1737 /* Handle $auth<n> variables. */
1738
1739 if (Ustrncmp(name, "auth", 4) == 0)
1740 {
1741 uschar *endptr;
1742 int n = Ustrtoul(name + 4, &endptr, 10);
1743 if (*endptr == 0 && n != 0 && n <= AUTH_VARS)
1744 return !auth_vars[n-1] ? US"" : auth_vars[n-1];
1745 }
1746 else if (Ustrncmp(name, "regex", 5) == 0)
1747 {
1748 uschar *endptr;
1749 int n = Ustrtoul(name + 5, &endptr, 10);
1750 if (*endptr == 0 && n != 0 && n <= REGEX_VARS)
1751 return !regex_vars[n-1] ? US"" : regex_vars[n-1];
1752 }
1753
1754 /* For all other variables, search the table */
1755
1756 if (!(vp = find_var_ent(name)))
1757 return NULL; /* Unknown variable name */
1758
1759 /* Found an existing variable. If in skipping state, the value isn't needed,
1760 and we want to avoid processing (such as looking up the host name). */
1761
1762 if (skipping)
1763 return US"";
1764
1765 val = vp->value;
1766 switch (vp->type)
1767 {
1768 case vtype_filter_int:
1769 if (!filter_running) return NULL;
1770 /* Fall through */
1771 /* VVVVVVVVVVVV */
1772 case vtype_int:
1773 sprintf(CS var_buffer, "%d", *(int *)(val)); /* Integer */
1774 return var_buffer;
1775
1776 case vtype_ino:
1777 sprintf(CS var_buffer, "%ld", (long int)(*(ino_t *)(val))); /* Inode */
1778 return var_buffer;
1779
1780 case vtype_gid:
1781 sprintf(CS var_buffer, "%ld", (long int)(*(gid_t *)(val))); /* gid */
1782 return var_buffer;
1783
1784 case vtype_uid:
1785 sprintf(CS var_buffer, "%ld", (long int)(*(uid_t *)(val))); /* uid */
1786 return var_buffer;
1787
1788 case vtype_bool:
1789 sprintf(CS var_buffer, "%s", *(BOOL *)(val) ? "yes" : "no"); /* bool */
1790 return var_buffer;
1791
1792 case vtype_stringptr: /* Pointer to string */
1793 return (s = *((uschar **)(val))) ? s : US"";
1794
1795 case vtype_pid:
1796 sprintf(CS var_buffer, "%d", (int)getpid()); /* pid */
1797 return var_buffer;
1798
1799 case vtype_load_avg:
1800 sprintf(CS var_buffer, "%d", OS_GETLOADAVG()); /* load_average */
1801 return var_buffer;
1802
1803 case vtype_host_lookup: /* Lookup if not done so */
1804 if (sender_host_name == NULL && sender_host_address != NULL &&
1805 !host_lookup_failed && host_name_lookup() == OK)
1806 host_build_sender_fullhost();
1807 return (sender_host_name == NULL)? US"" : sender_host_name;
1808
1809 case vtype_localpart: /* Get local part from address */
1810 s = *((uschar **)(val));
1811 if (s == NULL) return US"";
1812 domain = Ustrrchr(s, '@');
1813 if (domain == NULL) return s;
1814 if (domain - s > sizeof(var_buffer) - 1)
1815 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "local part longer than " SIZE_T_FMT
1816 " in string expansion", sizeof(var_buffer));
1817 Ustrncpy(var_buffer, s, domain - s);
1818 var_buffer[domain - s] = 0;
1819 return var_buffer;
1820
1821 case vtype_domain: /* Get domain from address */
1822 s = *((uschar **)(val));
1823 if (s == NULL) return US"";
1824 domain = Ustrrchr(s, '@');
1825 return (domain == NULL)? US"" : domain + 1;
1826
1827 case vtype_msgheaders:
1828 return find_header(NULL, exists_only, newsize, FALSE, NULL);
1829
1830 case vtype_msgheaders_raw:
1831 return find_header(NULL, exists_only, newsize, TRUE, NULL);
1832
1833 case vtype_msgbody: /* Pointer to msgbody string */
1834 case vtype_msgbody_end: /* Ditto, the end of the msg */
1835 ss = (uschar **)(val);
1836 if (!*ss && deliver_datafile >= 0) /* Read body when needed */
1837 {
1838 uschar *body;
1839 off_t start_offset = SPOOL_DATA_START_OFFSET;
1840 int len = message_body_visible;
1841 if (len > message_size) len = message_size;
1842 *ss = body = store_malloc(len+1);
1843 body[0] = 0;
1844 if (vp->type == vtype_msgbody_end)
1845 {
1846 struct stat statbuf;
1847 if (fstat(deliver_datafile, &statbuf) == 0)
1848 {
1849 start_offset = statbuf.st_size - len;
1850 if (start_offset < SPOOL_DATA_START_OFFSET)
1851 start_offset = SPOOL_DATA_START_OFFSET;
1852 }
1853 }
1854 if (lseek(deliver_datafile, start_offset, SEEK_SET) < 0)
1855 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "deliver_datafile lseek: %s",
1856 strerror(errno));
1857 len = read(deliver_datafile, body, len);
1858 if (len > 0)
1859 {
1860 body[len] = 0;
1861 if (message_body_newlines) /* Separate loops for efficiency */
1862 while (len > 0)
1863 { if (body[--len] == 0) body[len] = ' '; }
1864 else
1865 while (len > 0)
1866 { if (body[--len] == '\n' || body[len] == 0) body[len] = ' '; }
1867 }
1868 }
1869 return *ss ? *ss : US"";
1870
1871 case vtype_todbsdin: /* BSD inbox time of day */
1872 return tod_stamp(tod_bsdin);
1873
1874 case vtype_tode: /* Unix epoch time of day */
1875 return tod_stamp(tod_epoch);
1876
1877 case vtype_todel: /* Unix epoch/usec time of day */
1878 return tod_stamp(tod_epoch_l);
1879
1880 case vtype_todf: /* Full time of day */
1881 return tod_stamp(tod_full);
1882
1883 case vtype_todl: /* Log format time of day */
1884 return tod_stamp(tod_log_bare); /* (without timezone) */
1885
1886 case vtype_todzone: /* Time zone offset only */
1887 return tod_stamp(tod_zone);
1888
1889 case vtype_todzulu: /* Zulu time */
1890 return tod_stamp(tod_zulu);
1891
1892 case vtype_todlf: /* Log file datestamp tod */
1893 return tod_stamp(tod_log_datestamp_daily);
1894
1895 case vtype_reply: /* Get reply address */
1896 s = find_header(US"reply-to:", exists_only, newsize, TRUE,
1897 headers_charset);
1898 if (s != NULL) while (isspace(*s)) s++;
1899 if (s == NULL || *s == 0)
1900 {
1901 *newsize = 0; /* For the *s==0 case */
1902 s = find_header(US"from:", exists_only, newsize, TRUE, headers_charset);
1903 }
1904 if (s != NULL)
1905 {
1906 uschar *t;
1907 while (isspace(*s)) s++;
1908 for (t = s; *t != 0; t++) if (*t == '\n') *t = ' ';
1909 while (t > s && isspace(t[-1])) t--;
1910 *t = 0;
1911 }
1912 return (s == NULL)? US"" : s;
1913
1914 case vtype_string_func:
1915 {
1916 uschar * (*fn)() = val;
1917 return fn();
1918 }
1919
1920 case vtype_pspace:
1921 {
1922 int inodes;
1923 sprintf(CS var_buffer, "%d",
1924 receive_statvfs(val == (void *)TRUE, &inodes));
1925 }
1926 return var_buffer;
1927
1928 case vtype_pinodes:
1929 {
1930 int inodes;
1931 (void) receive_statvfs(val == (void *)TRUE, &inodes);
1932 sprintf(CS var_buffer, "%d", inodes);
1933 }
1934 return var_buffer;
1935
1936 case vtype_cert:
1937 return *(void **)val ? US"<cert>" : US"";
1938
1939 #ifndef DISABLE_DKIM
1940 case vtype_dkim:
1941 return dkim_exim_expand_query((int)(long)val);
1942 #endif
1943
1944 }
1945
1946 return NULL; /* Unknown variable. Silences static checkers. */
1947 }
1948
1949
1950
1951
1952 void
1953 modify_variable(uschar *name, void * value)
1954 {
1955 var_entry * vp;
1956 if ((vp = find_var_ent(name))) vp->value = value;
1957 return; /* Unknown variable name, fail silently */
1958 }
1959
1960
1961
1962
1963
1964
1965 /*************************************************
1966 * Read and expand substrings *
1967 *************************************************/
1968
1969 /* This function is called to read and expand argument substrings for various
1970 expansion items. Some have a minimum requirement that is less than the maximum;
1971 in these cases, the first non-present one is set to NULL.
1972
1973 Arguments:
1974 sub points to vector of pointers to set
1975 n maximum number of substrings
1976 m minimum required
1977 sptr points to current string pointer
1978 skipping the skipping flag
1979 check_end if TRUE, check for final '}'
1980 name name of item, for error message
1981 resetok if not NULL, pointer to flag - write FALSE if unsafe to reset
1982 the store.
1983
1984 Returns: 0 OK; string pointer updated
1985 1 curly bracketing error (too few arguments)
1986 2 too many arguments (only if check_end is set); message set
1987 3 other error (expansion failure)
1988 */
1989
1990 static int
1991 read_subs(uschar **sub, int n, int m, const uschar **sptr, BOOL skipping,
1992 BOOL check_end, uschar *name, BOOL *resetok)
1993 {
1994 int i;
1995 const uschar *s = *sptr;
1996
1997 while (isspace(*s)) s++;
1998 for (i = 0; i < n; i++)
1999 {
2000 if (*s != '{')
2001 {
2002 if (i < m)
2003 {
2004 expand_string_message = string_sprintf("Not enough arguments for '%s' "
2005 "(min is %d)", name, m);
2006 return 1;
2007 }
2008 sub[i] = NULL;
2009 break;
2010 }
2011 if (!(sub[i] = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, resetok)))
2012 return 3;
2013 if (*s++ != '}') return 1;
2014 while (isspace(*s)) s++;
2015 }
2016 if (check_end && *s++ != '}')
2017 {
2018 if (s[-1] == '{')
2019 {
2020 expand_string_message = string_sprintf("Too many arguments for '%s' "
2021 "(max is %d)", name, n);
2022 return 2;
2023 }
2024 expand_string_message = string_sprintf("missing '}' after '%s'", name);
2025 return 1;
2026 }
2027
2028 *sptr = s;
2029 return 0;
2030 }
2031
2032
2033
2034
2035 /*************************************************
2036 * Elaborate message for bad variable *
2037 *************************************************/
2038
2039 /* For the "unknown variable" message, take a look at the variable's name, and
2040 give additional information about possible ACL variables. The extra information
2041 is added on to expand_string_message.
2042
2043 Argument: the name of the variable
2044 Returns: nothing
2045 */
2046
2047 static void
2048 check_variable_error_message(uschar *name)
2049 {
2050 if (Ustrncmp(name, "acl_", 4) == 0)
2051 expand_string_message = string_sprintf("%s (%s)", expand_string_message,
2052 (name[4] == 'c' || name[4] == 'm')?
2053 (isalpha(name[5])?
2054 US"6th character of a user-defined ACL variable must be a digit or underscore" :
2055 US"strict_acl_vars is set" /* Syntax is OK, it has to be this */
2056 ) :
2057 US"user-defined ACL variables must start acl_c or acl_m");
2058 }
2059
2060
2061
2062 /*
2063 Load args from sub array to globals, and call acl_check().
2064 Sub array will be corrupted on return.
2065
2066 Returns: OK access is granted by an ACCEPT verb
2067 DISCARD access is (apparently) granted by a DISCARD verb
2068 FAIL access is denied
2069 FAIL_DROP access is denied; drop the connection
2070 DEFER can't tell at the moment
2071 ERROR disaster
2072 */
2073 static int
2074 eval_acl(uschar ** sub, int nsub, uschar ** user_msgp)
2075 {
2076 int i;
2077 int sav_narg = acl_narg;
2078 int ret;
2079 uschar * dummy_logmsg;
2080 extern int acl_where;
2081
2082 if(--nsub > nelem(acl_arg)) nsub = nelem(acl_arg);
2083 for (i = 0; i < nsub && sub[i+1]; i++)
2084 {
2085 uschar * tmp = acl_arg[i];
2086 acl_arg[i] = sub[i+1]; /* place callers args in the globals */
2087 sub[i+1] = tmp; /* stash the old args using our caller's storage */
2088 }
2089 acl_narg = i;
2090 while (i < nsub)
2091 {
2092 sub[i+1] = acl_arg[i];
2093 acl_arg[i++] = NULL;
2094 }
2095
2096 DEBUG(D_expand)
2097 debug_printf_indent("expanding: acl: %s arg: %s%s\n",
2098 sub[0],
2099 acl_narg>0 ? acl_arg[0] : US"<none>",
2100 acl_narg>1 ? " +more" : "");
2101
2102 ret = acl_eval(acl_where, sub[0], user_msgp, &dummy_logmsg);
2103
2104 for (i = 0; i < nsub; i++)
2105 acl_arg[i] = sub[i+1]; /* restore old args */
2106 acl_narg = sav_narg;
2107
2108 return ret;
2109 }
2110
2111
2112
2113
2114 /*************************************************
2115 * Read and evaluate a condition *
2116 *************************************************/
2117
2118 /*
2119 Arguments:
2120 s points to the start of the condition text
2121 resetok points to a BOOL which is written false if it is unsafe to
2122 free memory. Certain condition types (acl) may have side-effect
2123 allocation which must be preserved.
2124 yield points to a BOOL to hold the result of the condition test;
2125 if NULL, we are just reading through a condition that is
2126 part of an "or" combination to check syntax, or in a state
2127 where the answer isn't required
2128
2129 Returns: a pointer to the first character after the condition, or
2130 NULL after an error
2131 */
2132
2133 static const uschar *
2134 eval_condition(const uschar *s, BOOL *resetok, BOOL *yield)
2135 {
2136 BOOL testfor = TRUE;
2137 BOOL tempcond, combined_cond;
2138 BOOL *subcondptr;
2139 BOOL sub2_honour_dollar = TRUE;
2140 int i, rc, cond_type, roffset;
2141 int_eximarith_t num[2];
2142 struct stat statbuf;
2143 uschar name[256];
2144 const uschar *sub[10];
2145
2146 const pcre *re;
2147 const uschar *rerror;
2148
2149 for (;;)
2150 {
2151 while (isspace(*s)) s++;
2152 if (*s == '!') { testfor = !testfor; s++; } else break;
2153 }
2154
2155 /* Numeric comparisons are symbolic */
2156
2157 if (*s == '=' || *s == '>' || *s == '<')
2158 {
2159 int p = 0;
2160 name[p++] = *s++;
2161 if (*s == '=')
2162 {
2163 name[p++] = '=';
2164 s++;
2165 }
2166 name[p] = 0;
2167 }
2168
2169 /* All other conditions are named */
2170
2171 else s = read_name(name, 256, s, US"_");
2172
2173 /* If we haven't read a name, it means some non-alpha character is first. */
2174
2175 if (name[0] == 0)
2176 {
2177 expand_string_message = string_sprintf("condition name expected, "
2178 "but found \"%.16s\"", s);
2179 return NULL;
2180 }
2181
2182 /* Find which condition we are dealing with, and switch on it */
2183
2184 cond_type = chop_match(name, cond_table, nelem(cond_table));
2185 switch(cond_type)
2186 {
2187 /* def: tests for a non-empty variable, or for the existence of a header. If
2188 yield == NULL we are in a skipping state, and don't care about the answer. */
2189
2190 case ECOND_DEF:
2191 if (*s != ':')
2192 {
2193 expand_string_message = US"\":\" expected after \"def\"";
2194 return NULL;
2195 }
2196
2197 s = read_name(name, 256, s+1, US"_");
2198
2199 /* Test for a header's existence. If the name contains a closing brace
2200 character, this may be a user error where the terminating colon has been
2201 omitted. Set a flag to adjust a subsequent error message in this case. */
2202
2203 if (Ustrncmp(name, "h_", 2) == 0 ||
2204 Ustrncmp(name, "rh_", 3) == 0 ||
2205 Ustrncmp(name, "bh_", 3) == 0 ||
2206 Ustrncmp(name, "header_", 7) == 0 ||
2207 Ustrncmp(name, "rheader_", 8) == 0 ||
2208 Ustrncmp(name, "bheader_", 8) == 0)
2209 {
2210 s = read_header_name(name, 256, s);
2211 /* {-for-text-editors */
2212 if (Ustrchr(name, '}') != NULL) malformed_header = TRUE;
2213 if (yield != NULL) *yield =
2214 (find_header(name, TRUE, NULL, FALSE, NULL) != NULL) == testfor;
2215 }
2216
2217 /* Test for a variable's having a non-empty value. A non-existent variable
2218 causes an expansion failure. */
2219
2220 else
2221 {
2222 uschar *value = find_variable(name, TRUE, yield == NULL, NULL);
2223 if (value == NULL)
2224 {
2225 expand_string_message = (name[0] == 0)?
2226 string_sprintf("variable name omitted after \"def:\"") :
2227 string_sprintf("unknown variable \"%s\" after \"def:\"", name);
2228 check_variable_error_message(name);
2229 return NULL;
2230 }
2231 if (yield != NULL) *yield = (value[0] != 0) == testfor;
2232 }
2233
2234 return s;
2235
2236
2237 /* first_delivery tests for first delivery attempt */
2238
2239 case ECOND_FIRST_DELIVERY:
2240 if (yield != NULL) *yield = deliver_firsttime == testfor;
2241 return s;
2242
2243
2244 /* queue_running tests for any process started by a queue runner */
2245
2246 case ECOND_QUEUE_RUNNING:
2247 if (yield != NULL) *yield = (queue_run_pid != (pid_t)0) == testfor;
2248 return s;
2249
2250
2251 /* exists: tests for file existence
2252 isip: tests for any IP address
2253 isip4: tests for an IPv4 address
2254 isip6: tests for an IPv6 address
2255 pam: does PAM authentication
2256 radius: does RADIUS authentication
2257 ldapauth: does LDAP authentication
2258 pwcheck: does Cyrus SASL pwcheck authentication
2259 */
2260
2261 case ECOND_EXISTS:
2262 case ECOND_ISIP:
2263 case ECOND_ISIP4:
2264 case ECOND_ISIP6:
2265 case ECOND_PAM:
2266 case ECOND_RADIUS:
2267 case ECOND_LDAPAUTH:
2268 case ECOND_PWCHECK:
2269
2270 while (isspace(*s)) s++;
2271 if (*s != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2272
2273 sub[0] = expand_string_internal(s+1, TRUE, &s, yield == NULL, TRUE, resetok);
2274 if (sub[0] == NULL) return NULL;
2275 /* {-for-text-editors */
2276 if (*s++ != '}') goto COND_FAILED_CURLY_END;
2277
2278 if (yield == NULL) return s; /* No need to run the test if skipping */
2279
2280 switch(cond_type)
2281 {
2282 case ECOND_EXISTS:
2283 if ((expand_forbid & RDO_EXISTS) != 0)
2284 {
2285 expand_string_message = US"File existence tests are not permitted";
2286 return NULL;
2287 }
2288 *yield = (Ustat(sub[0], &statbuf) == 0) == testfor;
2289 break;
2290
2291 case ECOND_ISIP:
2292 case ECOND_ISIP4:
2293 case ECOND_ISIP6:
2294 rc = string_is_ip_address(sub[0], NULL);
2295 *yield = ((cond_type == ECOND_ISIP)? (rc != 0) :
2296 (cond_type == ECOND_ISIP4)? (rc == 4) : (rc == 6)) == testfor;
2297 break;
2298
2299 /* Various authentication tests - all optionally compiled */
2300
2301 case ECOND_PAM:
2302 #ifdef SUPPORT_PAM
2303 rc = auth_call_pam(sub[0], &expand_string_message);
2304 goto END_AUTH;
2305 #else
2306 goto COND_FAILED_NOT_COMPILED;
2307 #endif /* SUPPORT_PAM */
2308
2309 case ECOND_RADIUS:
2310 #ifdef RADIUS_CONFIG_FILE
2311 rc = auth_call_radius(sub[0], &expand_string_message);
2312 goto END_AUTH;
2313 #else
2314 goto COND_FAILED_NOT_COMPILED;
2315 #endif /* RADIUS_CONFIG_FILE */
2316
2317 case ECOND_LDAPAUTH:
2318 #ifdef LOOKUP_LDAP
2319 {
2320 /* Just to keep the interface the same */
2321 BOOL do_cache;
2322 int old_pool = store_pool;
2323 store_pool = POOL_SEARCH;
2324 rc = eldapauth_find((void *)(-1), NULL, sub[0], Ustrlen(sub[0]), NULL,
2325 &expand_string_message, &do_cache);
2326 store_pool = old_pool;
2327 }
2328 goto END_AUTH;
2329 #else
2330 goto COND_FAILED_NOT_COMPILED;
2331 #endif /* LOOKUP_LDAP */
2332
2333 case ECOND_PWCHECK:
2334 #ifdef CYRUS_PWCHECK_SOCKET
2335 rc = auth_call_pwcheck(sub[0], &expand_string_message);
2336 goto END_AUTH;
2337 #else
2338 goto COND_FAILED_NOT_COMPILED;
2339 #endif /* CYRUS_PWCHECK_SOCKET */
2340
2341 #if defined(SUPPORT_PAM) || defined(RADIUS_CONFIG_FILE) || \
2342 defined(LOOKUP_LDAP) || defined(CYRUS_PWCHECK_SOCKET)
2343 END_AUTH:
2344 if (rc == ERROR || rc == DEFER) return NULL;
2345 *yield = (rc == OK) == testfor;
2346 #endif
2347 }
2348 return s;
2349
2350
2351 /* call ACL (in a conditional context). Accept true, deny false.
2352 Defer is a forced-fail. Anything set by message= goes to $value.
2353 Up to ten parameters are used; we use the braces round the name+args
2354 like the saslauthd condition does, to permit a variable number of args.
2355 See also the expansion-item version EITEM_ACL and the traditional
2356 acl modifier ACLC_ACL.
2357 Since the ACL may allocate new global variables, tell our caller to not
2358 reclaim memory.
2359 */
2360
2361 case ECOND_ACL:
2362 /* ${if acl {{name}{arg1}{arg2}...} {yes}{no}} */
2363 {
2364 uschar *sub[10];
2365 uschar *user_msg;
2366 BOOL cond = FALSE;
2367 int size = 0;
2368 int ptr = 0;
2369
2370 while (isspace(*s)) s++;
2371 if (*s++ != '{') goto COND_FAILED_CURLY_START; /*}*/
2372
2373 switch(read_subs(sub, nelem(sub), 1,
2374 &s, yield == NULL, TRUE, US"acl", resetok))
2375 {
2376 case 1: expand_string_message = US"too few arguments or bracketing "
2377 "error for acl";
2378 case 2:
2379 case 3: return NULL;
2380 }
2381
2382 *resetok = FALSE; /* eval_acl() might allocate; do not reclaim */
2383 if (yield != NULL) switch(eval_acl(sub, nelem(sub), &user_msg))
2384 {
2385 case OK:
2386 cond = TRUE;
2387 case FAIL:
2388 lookup_value = NULL;
2389 if (user_msg)
2390 {
2391 lookup_value = string_cat(NULL, &size, &ptr, user_msg);
2392 lookup_value[ptr] = '\0';
2393 }
2394 *yield = cond == testfor;
2395 break;
2396
2397 case DEFER:
2398 expand_string_forcedfail = TRUE;
2399 /*FALLTHROUGH*/
2400 default:
2401 expand_string_message = string_sprintf("error from acl \"%s\"", sub[0]);
2402 return NULL;
2403 }
2404 return s;
2405 }
2406
2407
2408 /* saslauthd: does Cyrus saslauthd authentication. Four parameters are used:
2409
2410 ${if saslauthd {{username}{password}{service}{realm}} {yes}{no}}
2411
2412 However, the last two are optional. That is why the whole set is enclosed
2413 in their own set of braces. */
2414
2415 case ECOND_SASLAUTHD:
2416 #ifndef CYRUS_SASLAUTHD_SOCKET
2417 goto COND_FAILED_NOT_COMPILED;
2418 #else
2419 {
2420 uschar *sub[4];
2421 while (isspace(*s)) s++;
2422 if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2423 switch(read_subs(sub, nelem(sub), 2, &s, yield == NULL, TRUE, US"saslauthd",
2424 resetok))
2425 {
2426 case 1: expand_string_message = US"too few arguments or bracketing "
2427 "error for saslauthd";
2428 case 2:
2429 case 3: return NULL;
2430 }
2431 if (sub[2] == NULL) sub[3] = NULL; /* realm if no service */
2432 if (yield != NULL)
2433 {
2434 int rc = auth_call_saslauthd(sub[0], sub[1], sub[2], sub[3],
2435 &expand_string_message);
2436 if (rc == ERROR || rc == DEFER) return NULL;
2437 *yield = (rc == OK) == testfor;
2438 }
2439 return s;
2440 }
2441 #endif /* CYRUS_SASLAUTHD_SOCKET */
2442
2443
2444 /* symbolic operators for numeric and string comparison, and a number of
2445 other operators, all requiring two arguments.
2446
2447 crypteq: encrypts plaintext and compares against an encrypted text,
2448 using crypt(), crypt16(), MD5 or SHA-1
2449 inlist/inlisti: checks if first argument is in the list of the second
2450 match: does a regular expression match and sets up the numerical
2451 variables if it succeeds
2452 match_address: matches in an address list
2453 match_domain: matches in a domain list
2454 match_ip: matches a host list that is restricted to IP addresses
2455 match_local_part: matches in a local part list
2456 */
2457
2458 case ECOND_MATCH_ADDRESS:
2459 case ECOND_MATCH_DOMAIN:
2460 case ECOND_MATCH_IP:
2461 case ECOND_MATCH_LOCAL_PART:
2462 #ifndef EXPAND_LISTMATCH_RHS
2463 sub2_honour_dollar = FALSE;
2464 #endif
2465 /* FALLTHROUGH */
2466
2467 case ECOND_CRYPTEQ:
2468 case ECOND_INLIST:
2469 case ECOND_INLISTI:
2470 case ECOND_MATCH:
2471
2472 case ECOND_NUM_L: /* Numerical comparisons */
2473 case ECOND_NUM_LE:
2474 case ECOND_NUM_E:
2475 case ECOND_NUM_EE:
2476 case ECOND_NUM_G:
2477 case ECOND_NUM_GE:
2478
2479 case ECOND_STR_LT: /* String comparisons */
2480 case ECOND_STR_LTI:
2481 case ECOND_STR_LE:
2482 case ECOND_STR_LEI:
2483 case ECOND_STR_EQ:
2484 case ECOND_STR_EQI:
2485 case ECOND_STR_GT:
2486 case ECOND_STR_GTI:
2487 case ECOND_STR_GE:
2488 case ECOND_STR_GEI:
2489
2490 for (i = 0; i < 2; i++)
2491 {
2492 /* Sometimes, we don't expand substrings; too many insecure configurations
2493 created using match_address{}{} and friends, where the second param
2494 includes information from untrustworthy sources. */
2495 BOOL honour_dollar = TRUE;
2496 if ((i > 0) && !sub2_honour_dollar)
2497 honour_dollar = FALSE;
2498
2499 while (isspace(*s)) s++;
2500 if (*s != '{')
2501 {
2502 if (i == 0) goto COND_FAILED_CURLY_START;
2503 expand_string_message = string_sprintf("missing 2nd string in {} "
2504 "after \"%s\"", name);
2505 return NULL;
2506 }
2507 sub[i] = expand_string_internal(s+1, TRUE, &s, yield == NULL,
2508 honour_dollar, resetok);
2509 if (sub[i] == NULL) return NULL;
2510 if (*s++ != '}') goto COND_FAILED_CURLY_END;
2511
2512 /* Convert to numerical if required; we know that the names of all the
2513 conditions that compare numbers do not start with a letter. This just saves
2514 checking for them individually. */
2515
2516 if (!isalpha(name[0]) && yield != NULL)
2517 if (sub[i][0] == 0)
2518 {
2519 num[i] = 0;
2520 DEBUG(D_expand)
2521 debug_printf_indent("empty string cast to zero for numerical comparison\n");
2522 }
2523 else
2524 {
2525 num[i] = expanded_string_integer(sub[i], FALSE);
2526 if (expand_string_message != NULL) return NULL;
2527 }
2528 }
2529
2530 /* Result not required */
2531
2532 if (yield == NULL) return s;
2533
2534 /* Do an appropriate comparison */
2535
2536 switch(cond_type)
2537 {
2538 case ECOND_NUM_E:
2539 case ECOND_NUM_EE:
2540 tempcond = (num[0] == num[1]);
2541 break;
2542
2543 case ECOND_NUM_G:
2544 tempcond = (num[0] > num[1]);
2545 break;
2546
2547 case ECOND_NUM_GE:
2548 tempcond = (num[0] >= num[1]);
2549 break;
2550
2551 case ECOND_NUM_L:
2552 tempcond = (num[0] < num[1]);
2553 break;
2554
2555 case ECOND_NUM_LE:
2556 tempcond = (num[0] <= num[1]);
2557 break;
2558
2559 case ECOND_STR_LT:
2560 tempcond = (Ustrcmp(sub[0], sub[1]) < 0);
2561 break;
2562
2563 case ECOND_STR_LTI:
2564 tempcond = (strcmpic(sub[0], sub[1]) < 0);
2565 break;
2566
2567 case ECOND_STR_LE:
2568 tempcond = (Ustrcmp(sub[0], sub[1]) <= 0);
2569 break;
2570
2571 case ECOND_STR_LEI:
2572 tempcond = (strcmpic(sub[0], sub[1]) <= 0);
2573 break;
2574
2575 case ECOND_STR_EQ:
2576 tempcond = (Ustrcmp(sub[0], sub[1]) == 0);
2577 break;
2578
2579 case ECOND_STR_EQI:
2580 tempcond = (strcmpic(sub[0], sub[1]) == 0);
2581 break;
2582
2583 case ECOND_STR_GT:
2584 tempcond = (Ustrcmp(sub[0], sub[1]) > 0);
2585 break;
2586
2587 case ECOND_STR_GTI:
2588 tempcond = (strcmpic(sub[0], sub[1]) > 0);
2589 break;
2590
2591 case ECOND_STR_GE:
2592 tempcond = (Ustrcmp(sub[0], sub[1]) >= 0);
2593 break;
2594
2595 case ECOND_STR_GEI:
2596 tempcond = (strcmpic(sub[0], sub[1]) >= 0);
2597 break;
2598
2599 case ECOND_MATCH: /* Regular expression match */
2600 re = pcre_compile(CS sub[1], PCRE_COPT, (const char **)&rerror, &roffset,
2601 NULL);
2602 if (re == NULL)
2603 {
2604 expand_string_message = string_sprintf("regular expression error in "
2605 "\"%s\": %s at offset %d", sub[1], rerror, roffset);
2606 return NULL;
2607 }
2608 tempcond = regex_match_and_setup(re, sub[0], 0, -1);
2609 break;
2610
2611 case ECOND_MATCH_ADDRESS: /* Match in an address list */
2612 rc = match_address_list(sub[0], TRUE, FALSE, &(sub[1]), NULL, -1, 0, NULL);
2613 goto MATCHED_SOMETHING;
2614
2615 case ECOND_MATCH_DOMAIN: /* Match in a domain list */
2616 rc = match_isinlist(sub[0], &(sub[1]), 0, &domainlist_anchor, NULL,
2617 MCL_DOMAIN + MCL_NOEXPAND, TRUE, NULL);
2618 goto MATCHED_SOMETHING;
2619
2620 case ECOND_MATCH_IP: /* Match IP address in a host list */
2621 if (sub[0][0] != 0 && string_is_ip_address(sub[0], NULL) == 0)
2622 {
2623 expand_string_message = string_sprintf("\"%s\" is not an IP address",
2624 sub[0]);
2625 return NULL;
2626 }
2627 else
2628 {
2629 unsigned int *nullcache = NULL;
2630 check_host_block cb;
2631
2632 cb.host_name = US"";
2633 cb.host_address = sub[0];
2634
2635 /* If the host address starts off ::ffff: it is an IPv6 address in
2636 IPv4-compatible mode. Find the IPv4 part for checking against IPv4
2637 addresses. */
2638
2639 cb.host_ipv4 = (Ustrncmp(cb.host_address, "::ffff:", 7) == 0)?
2640 cb.host_address + 7 : cb.host_address;
2641
2642 rc = match_check_list(
2643 &sub[1], /* the list */
2644 0, /* separator character */
2645 &hostlist_anchor, /* anchor pointer */
2646 &nullcache, /* cache pointer */
2647 check_host, /* function for testing */
2648 &cb, /* argument for function */
2649 MCL_HOST, /* type of check */
2650 sub[0], /* text for debugging */
2651 NULL); /* where to pass back data */
2652 }
2653 goto MATCHED_SOMETHING;
2654
2655 case ECOND_MATCH_LOCAL_PART:
2656 rc = match_isinlist(sub[0], &(sub[1]), 0, &localpartlist_anchor, NULL,
2657 MCL_LOCALPART + MCL_NOEXPAND, TRUE, NULL);
2658 /* Fall through */
2659 /* VVVVVVVVVVVV */
2660 MATCHED_SOMETHING:
2661 switch(rc)
2662 {
2663 case OK:
2664 tempcond = TRUE;
2665 break;
2666
2667 case FAIL:
2668 tempcond = FALSE;
2669 break;
2670
2671 case DEFER:
2672 expand_string_message = string_sprintf("unable to complete match "
2673 "against \"%s\": %s", sub[1], search_error_message);
2674 return NULL;
2675 }
2676
2677 break;
2678
2679 /* Various "encrypted" comparisons. If the second string starts with
2680 "{" then an encryption type is given. Default to crypt() or crypt16()
2681 (build-time choice). */
2682 /* }-for-text-editors */
2683
2684 case ECOND_CRYPTEQ:
2685 #ifndef SUPPORT_CRYPTEQ
2686 goto COND_FAILED_NOT_COMPILED;
2687 #else
2688 if (strncmpic(sub[1], US"{md5}", 5) == 0)
2689 {
2690 int sublen = Ustrlen(sub[1]+5);
2691 md5 base;
2692 uschar digest[16];
2693
2694 md5_start(&base);
2695 md5_end(&base, sub[0], Ustrlen(sub[0]), digest);
2696
2697 /* If the length that we are comparing against is 24, the MD5 digest
2698 is expressed as a base64 string. This is the way LDAP does it. However,
2699 some other software uses a straightforward hex representation. We assume
2700 this if the length is 32. Other lengths fail. */
2701
2702 if (sublen == 24)
2703 {
2704 uschar *coded = b64encode(digest, 16);
2705 DEBUG(D_auth) debug_printf("crypteq: using MD5+B64 hashing\n"
2706 " subject=%s\n crypted=%s\n", coded, sub[1]+5);
2707 tempcond = (Ustrcmp(coded, sub[1]+5) == 0);
2708 }
2709 else if (sublen == 32)
2710 {
2711 int i;
2712 uschar coded[36];
2713 for (i = 0; i < 16; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
2714 coded[32] = 0;
2715 DEBUG(D_auth) debug_printf("crypteq: using MD5+hex hashing\n"
2716 " subject=%s\n crypted=%s\n", coded, sub[1]+5);
2717 tempcond = (strcmpic(coded, sub[1]+5) == 0);
2718 }
2719 else
2720 {
2721 DEBUG(D_auth) debug_printf("crypteq: length for MD5 not 24 or 32: "
2722 "fail\n crypted=%s\n", sub[1]+5);
2723 tempcond = FALSE;
2724 }
2725 }
2726
2727 else if (strncmpic(sub[1], US"{sha1}", 6) == 0)
2728 {
2729 int sublen = Ustrlen(sub[1]+6);
2730 hctx h;
2731 uschar digest[20];
2732
2733 sha1_start(&h);
2734 sha1_end(&h, sub[0], Ustrlen(sub[0]), digest);
2735
2736 /* If the length that we are comparing against is 28, assume the SHA1
2737 digest is expressed as a base64 string. If the length is 40, assume a
2738 straightforward hex representation. Other lengths fail. */
2739
2740 if (sublen == 28)
2741 {
2742 uschar *coded = b64encode(digest, 20);
2743 DEBUG(D_auth) debug_printf("crypteq: using SHA1+B64 hashing\n"
2744 " subject=%s\n crypted=%s\n", coded, sub[1]+6);
2745 tempcond = (Ustrcmp(coded, sub[1]+6) == 0);
2746 }
2747 else if (sublen == 40)
2748 {
2749 int i;
2750 uschar coded[44];
2751 for (i = 0; i < 20; i++) sprintf(CS (coded+2*i), "%02X", digest[i]);
2752 coded[40] = 0;
2753 DEBUG(D_auth) debug_printf("crypteq: using SHA1+hex hashing\n"
2754 " subject=%s\n crypted=%s\n", coded, sub[1]+6);
2755 tempcond = (strcmpic(coded, sub[1]+6) == 0);
2756 }
2757 else
2758 {
2759 DEBUG(D_auth) debug_printf("crypteq: length for SHA-1 not 28 or 40: "
2760 "fail\n crypted=%s\n", sub[1]+6);
2761 tempcond = FALSE;
2762 }
2763 }
2764
2765 else /* {crypt} or {crypt16} and non-{ at start */
2766 /* }-for-text-editors */
2767 {
2768 int which = 0;
2769 uschar *coded;
2770
2771 if (strncmpic(sub[1], US"{crypt}", 7) == 0)
2772 {
2773 sub[1] += 7;
2774 which = 1;
2775 }
2776 else if (strncmpic(sub[1], US"{crypt16}", 9) == 0)
2777 {
2778 sub[1] += 9;
2779 which = 2;
2780 }
2781 else if (sub[1][0] == '{') /* }-for-text-editors */
2782 {
2783 expand_string_message = string_sprintf("unknown encryption mechanism "
2784 "in \"%s\"", sub[1]);
2785 return NULL;
2786 }
2787
2788 switch(which)
2789 {
2790 case 0: coded = US DEFAULT_CRYPT(CS sub[0], CS sub[1]); break;
2791 case 1: coded = US crypt(CS sub[0], CS sub[1]); break;
2792 default: coded = US crypt16(CS sub[0], CS sub[1]); break;
2793 }
2794
2795 #define STR(s) # s
2796 #define XSTR(s) STR(s)
2797 DEBUG(D_auth) debug_printf("crypteq: using %s()\n"
2798 " subject=%s\n crypted=%s\n",
2799 which == 0 ? XSTR(DEFAULT_CRYPT) : which == 1 ? "crypt" : "crypt16",
2800 coded, sub[1]);
2801 #undef STR
2802 #undef XSTR
2803
2804 /* If the encrypted string contains fewer than two characters (for the
2805 salt), force failure. Otherwise we get false positives: with an empty
2806 string the yield of crypt() is an empty string! */
2807
2808 if (coded)
2809 tempcond = Ustrlen(sub[1]) < 2 ? FALSE : Ustrcmp(coded, sub[1]) == 0;
2810 else if (errno == EINVAL)
2811 tempcond = FALSE;
2812 else
2813 {
2814 expand_string_message = string_sprintf("crypt error: %s\n",
2815 US strerror(errno));
2816 return NULL;
2817 }
2818 }
2819 break;
2820 #endif /* SUPPORT_CRYPTEQ */
2821
2822 case ECOND_INLIST:
2823 case ECOND_INLISTI:
2824 {
2825 const uschar * list = sub[1];
2826 int sep = 0;
2827 uschar *save_iterate_item = iterate_item;
2828 int (*compare)(const uschar *, const uschar *);
2829
2830 DEBUG(D_expand) debug_printf_indent("condition: %s\n", name);
2831
2832 tempcond = FALSE;
2833 compare = cond_type == ECOND_INLISTI
2834 ? strcmpic : (int (*)(const uschar *, const uschar *)) strcmp;
2835
2836 while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)))
2837 if (compare(sub[0], iterate_item) == 0)
2838 {
2839 tempcond = TRUE;
2840 break;
2841 }
2842 iterate_item = save_iterate_item;
2843 }
2844
2845 } /* Switch for comparison conditions */
2846
2847 *yield = tempcond == testfor;
2848 return s; /* End of comparison conditions */
2849
2850
2851 /* and/or: computes logical and/or of several conditions */
2852
2853 case ECOND_AND:
2854 case ECOND_OR:
2855 subcondptr = (yield == NULL)? NULL : &tempcond;
2856 combined_cond = (cond_type == ECOND_AND);
2857
2858 while (isspace(*s)) s++;
2859 if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2860
2861 for (;;)
2862 {
2863 while (isspace(*s)) s++;
2864 /* {-for-text-editors */
2865 if (*s == '}') break;
2866 if (*s != '{') /* }-for-text-editors */
2867 {
2868 expand_string_message = string_sprintf("each subcondition "
2869 "inside an \"%s{...}\" condition must be in its own {}", name);
2870 return NULL;
2871 }
2872
2873 if (!(s = eval_condition(s+1, resetok, subcondptr)))
2874 {
2875 expand_string_message = string_sprintf("%s inside \"%s{...}\" condition",
2876 expand_string_message, name);
2877 return NULL;
2878 }
2879 while (isspace(*s)) s++;
2880
2881 /* {-for-text-editors */
2882 if (*s++ != '}')
2883 {
2884 /* {-for-text-editors */
2885 expand_string_message = string_sprintf("missing } at end of condition "
2886 "inside \"%s\" group", name);
2887 return NULL;
2888 }
2889
2890 if (yield != NULL)
2891 {
2892 if (cond_type == ECOND_AND)
2893 {
2894 combined_cond &= tempcond;
2895 if (!combined_cond) subcondptr = NULL; /* once false, don't */
2896 } /* evaluate any more */
2897 else
2898 {
2899 combined_cond |= tempcond;
2900 if (combined_cond) subcondptr = NULL; /* once true, don't */
2901 } /* evaluate any more */
2902 }
2903 }
2904
2905 if (yield != NULL) *yield = (combined_cond == testfor);
2906 return ++s;
2907
2908
2909 /* forall/forany: iterates a condition with different values */
2910
2911 case ECOND_FORALL:
2912 case ECOND_FORANY:
2913 {
2914 const uschar * list;
2915 int sep = 0;
2916 uschar *save_iterate_item = iterate_item;
2917
2918 DEBUG(D_expand) debug_printf_indent("condition: %s\n", name);
2919
2920 while (isspace(*s)) s++;
2921 if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2922 sub[0] = expand_string_internal(s, TRUE, &s, (yield == NULL), TRUE, resetok);
2923 if (sub[0] == NULL) return NULL;
2924 /* {-for-text-editors */
2925 if (*s++ != '}') goto COND_FAILED_CURLY_END;
2926
2927 while (isspace(*s)) s++;
2928 if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2929
2930 sub[1] = s;
2931
2932 /* Call eval_condition once, with result discarded (as if scanning a
2933 "false" part). This allows us to find the end of the condition, because if
2934 the list it empty, we won't actually evaluate the condition for real. */
2935
2936 if (!(s = eval_condition(sub[1], resetok, NULL)))
2937 {
2938 expand_string_message = string_sprintf("%s inside \"%s\" condition",
2939 expand_string_message, name);
2940 return NULL;
2941 }
2942 while (isspace(*s)) s++;
2943
2944 /* {-for-text-editors */
2945 if (*s++ != '}')
2946 {
2947 /* {-for-text-editors */
2948 expand_string_message = string_sprintf("missing } at end of condition "
2949 "inside \"%s\"", name);
2950 return NULL;
2951 }
2952
2953 if (yield != NULL) *yield = !testfor;
2954 list = sub[0];
2955 while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)) != NULL)
2956 {
2957 DEBUG(D_expand) debug_printf_indent("%s: $item = \"%s\"\n", name, iterate_item);
2958 if (!eval_condition(sub[1], resetok, &tempcond))
2959 {
2960 expand_string_message = string_sprintf("%s inside \"%s\" condition",
2961 expand_string_message, name);
2962 iterate_item = save_iterate_item;
2963 return NULL;
2964 }
2965 DEBUG(D_expand) debug_printf_indent("%s: condition evaluated to %s\n", name,
2966 tempcond? "true":"false");
2967
2968 if (yield != NULL) *yield = (tempcond == testfor);
2969 if (tempcond == (cond_type == ECOND_FORANY)) break;
2970 }
2971
2972 iterate_item = save_iterate_item;
2973 return s;
2974 }
2975
2976
2977 /* The bool{} expansion condition maps a string to boolean.
2978 The values supported should match those supported by the ACL condition
2979 (acl.c, ACLC_CONDITION) so that we keep to a minimum the different ideas
2980 of true/false. Note that Router "condition" rules have a different
2981 interpretation, where general data can be used and only a few values
2982 map to FALSE.
2983 Note that readconf.c boolean matching, for boolean configuration options,
2984 only matches true/yes/false/no.
2985 The bool_lax{} condition matches the Router logic, which is much more
2986 liberal. */
2987 case ECOND_BOOL:
2988 case ECOND_BOOL_LAX:
2989 {
2990 uschar *sub_arg[1];
2991 uschar *t, *t2;
2992 uschar *ourname;
2993 size_t len;
2994 BOOL boolvalue = FALSE;
2995 while (isspace(*s)) s++;
2996 if (*s != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
2997 ourname = cond_type == ECOND_BOOL_LAX ? US"bool_lax" : US"bool";
2998 switch(read_subs(sub_arg, 1, 1, &s, yield == NULL, FALSE, ourname, resetok))
2999 {
3000 case 1: expand_string_message = string_sprintf(
3001 "too few arguments or bracketing error for %s",
3002 ourname);
3003 /*FALLTHROUGH*/
3004 case 2:
3005 case 3: return NULL;
3006 }
3007 t = sub_arg[0];
3008 while (isspace(*t)) t++;
3009 len = Ustrlen(t);
3010 if (len)
3011 {
3012 /* trailing whitespace: seems like a good idea to ignore it too */
3013 t2 = t + len - 1;
3014 while (isspace(*t2)) t2--;
3015 if (t2 != (t + len))
3016 {
3017 *++t2 = '\0';
3018 len = t2 - t;
3019 }
3020 }
3021 DEBUG(D_expand)
3022 debug_printf_indent("considering %s: %s\n", ourname, len ? t : US"<empty>");
3023 /* logic for the lax case from expand_check_condition(), which also does
3024 expands, and the logic is both short and stable enough that there should
3025 be no maintenance burden from replicating it. */
3026 if (len == 0)
3027 boolvalue = FALSE;
3028 else if (*t == '-'
3029 ? Ustrspn(t+1, "0123456789") == len-1
3030 : Ustrspn(t, "0123456789") == len)
3031 {
3032 boolvalue = (Uatoi(t) == 0) ? FALSE : TRUE;
3033 /* expand_check_condition only does a literal string "0" check */
3034 if ((cond_type == ECOND_BOOL_LAX) && (len > 1))
3035 boolvalue = TRUE;
3036 }
3037 else if (strcmpic(t, US"true") == 0 || strcmpic(t, US"yes") == 0)
3038 boolvalue = TRUE;
3039 else if (strcmpic(t, US"false") == 0 || strcmpic(t, US"no") == 0)
3040 boolvalue = FALSE;
3041 else if (cond_type == ECOND_BOOL_LAX)
3042 boolvalue = TRUE;
3043 else
3044 {
3045 expand_string_message = string_sprintf("unrecognised boolean "
3046 "value \"%s\"", t);
3047 return NULL;
3048 }
3049 DEBUG(D_expand) debug_printf_indent("%s: condition evaluated to %s\n", ourname,
3050 boolvalue? "true":"false");
3051 if (yield != NULL) *yield = (boolvalue == testfor);
3052 return s;
3053 }
3054
3055 /* Unknown condition */
3056
3057 default:
3058 expand_string_message = string_sprintf("unknown condition \"%s\"", name);
3059 return NULL;
3060 } /* End switch on condition type */
3061
3062 /* Missing braces at start and end of data */
3063
3064 COND_FAILED_CURLY_START:
3065 expand_string_message = string_sprintf("missing { after \"%s\"", name);
3066 return NULL;
3067
3068 COND_FAILED_CURLY_END:
3069 expand_string_message = string_sprintf("missing } at end of \"%s\" condition",
3070 name);
3071 return NULL;
3072
3073 /* A condition requires code that is not compiled */
3074
3075 #if !defined(SUPPORT_PAM) || !defined(RADIUS_CONFIG_FILE) || \
3076 !defined(LOOKUP_LDAP) || !defined(CYRUS_PWCHECK_SOCKET) || \
3077 !defined(SUPPORT_CRYPTEQ) || !defined(CYRUS_SASLAUTHD_SOCKET)
3078 COND_FAILED_NOT_COMPILED:
3079 expand_string_message = string_sprintf("support for \"%s\" not compiled",
3080 name);
3081 return NULL;
3082 #endif
3083 }
3084
3085
3086
3087
3088 /*************************************************
3089 * Save numerical variables *
3090 *************************************************/
3091
3092 /* This function is called from items such as "if" that want to preserve and
3093 restore the numbered variables.
3094
3095 Arguments:
3096 save_expand_string points to an array of pointers to set
3097 save_expand_nlength points to an array of ints for the lengths
3098
3099 Returns: the value of expand max to save
3100 */
3101
3102 static int
3103 save_expand_strings(uschar **save_expand_nstring, int *save_expand_nlength)
3104 {
3105 int i;
3106 for (i = 0; i <= expand_nmax; i++)
3107 {
3108 save_expand_nstring[i] = expand_nstring[i];
3109 save_expand_nlength[i] = expand_nlength[i];
3110 }
3111 return expand_nmax;
3112 }
3113
3114
3115
3116 /*************************************************
3117 * Restore numerical variables *
3118 *************************************************/
3119
3120 /* This function restored saved values of numerical strings.
3121
3122 Arguments:
3123 save_expand_nmax the number of strings to restore
3124 save_expand_string points to an array of pointers
3125 save_expand_nlength points to an array of ints
3126
3127 Returns: nothing
3128 */
3129
3130 static void
3131 restore_expand_strings(int save_expand_nmax, uschar **save_expand_nstring,
3132 int *save_expand_nlength)
3133 {
3134 int i;
3135 expand_nmax = save_expand_nmax;
3136 for (i = 0; i <= expand_nmax; i++)
3137 {
3138 expand_nstring[i] = save_expand_nstring[i];
3139 expand_nlength[i] = save_expand_nlength[i];
3140 }
3141 }
3142
3143
3144
3145
3146
3147 /*************************************************
3148 * Handle yes/no substrings *
3149 *************************************************/
3150
3151 /* This function is used by ${if}, ${lookup} and ${extract} to handle the
3152 alternative substrings that depend on whether or not the condition was true,
3153 or the lookup or extraction succeeded. The substrings always have to be
3154 expanded, to check their syntax, but "skipping" is set when the result is not
3155 needed - this avoids unnecessary nested lookups.
3156
3157 Arguments:
3158 skipping TRUE if we were skipping when this item was reached
3159 yes TRUE if the first string is to be used, else use the second
3160 save_lookup a value to put back into lookup_value before the 2nd expansion
3161 sptr points to the input string pointer
3162 yieldptr points to the output string pointer
3163 sizeptr points to the output string size
3164 ptrptr points to the output string pointer
3165 type "lookup", "if", "extract", "run", "env", "listextract" or
3166 "certextract" for error message
3167 resetok if not NULL, pointer to flag - write FALSE if unsafe to reset
3168 the store.
3169
3170 Returns: 0 OK; lookup_value has been reset to save_lookup
3171 1 expansion failed
3172 2 expansion failed because of bracketing error
3173 */
3174
3175 static int
3176 process_yesno(BOOL skipping, BOOL yes, uschar *save_lookup, const uschar **sptr,
3177 uschar **yieldptr, int *sizeptr, int *ptrptr, uschar *type, BOOL *resetok)
3178 {
3179 int rc = 0;
3180 const uschar *s = *sptr; /* Local value */
3181 uschar *sub1, *sub2;
3182 const uschar * errwhere;
3183
3184 /* If there are no following strings, we substitute the contents of $value for
3185 lookups and for extractions in the success case. For the ${if item, the string
3186 "true" is substituted. In the fail case, nothing is substituted for all three
3187 items. */
3188
3189 while (isspace(*s)) s++;
3190 if (*s == '}')
3191 {
3192 if (type[0] == 'i')
3193 {
3194 if (yes && !skipping)
3195 *yieldptr = string_catn(*yieldptr, sizeptr, ptrptr, US"true", 4);
3196 }
3197 else
3198 {
3199 if (yes && lookup_value && !skipping)
3200 *yieldptr = string_cat(*yieldptr, sizeptr, ptrptr, lookup_value);
3201 lookup_value = save_lookup;
3202 }
3203 s++;
3204 goto RETURN;
3205 }
3206
3207 /* The first following string must be braced. */
3208
3209 if (*s++ != '{')
3210 {
3211 errwhere = US"'yes' part did not start with '{'";
3212 goto FAILED_CURLY;
3213 }
3214
3215 /* Expand the first substring. Forced failures are noticed only if we actually
3216 want this string. Set skipping in the call in the fail case (this will always
3217 be the case if we were already skipping). */
3218
3219 sub1 = expand_string_internal(s, TRUE, &s, !yes, TRUE, resetok);
3220 if (sub1 == NULL && (yes || !expand_string_forcedfail)) goto FAILED;
3221 expand_string_forcedfail = FALSE;
3222 if (*s++ != '}')
3223 {
3224 errwhere = US"'yes' part did not end with '}'";
3225 goto FAILED_CURLY;
3226 }
3227
3228 /* If we want the first string, add it to the output */
3229
3230 if (yes)
3231 *yieldptr = string_cat(*yieldptr, sizeptr, ptrptr, sub1);
3232
3233 /* If this is called from a lookup/env or a (cert)extract, we want to restore
3234 $value to what it was at the start of the item, so that it has this value
3235 during the second string expansion. For the call from "if" or "run" to this
3236 function, save_lookup is set to lookup_value, so that this statement does
3237 nothing. */
3238
3239 lookup_value = save_lookup;
3240
3241 /* There now follows either another substring, or "fail", or nothing. This
3242 time, forced failures are noticed only if we want the second string. We must
3243 set skipping in the nested call if we don't want this string, or if we were
3244 already skipping. */
3245
3246 while (isspace(*s)) s++;
3247 if (*s == '{')
3248 {
3249 sub2 = expand_string_internal(s+1, TRUE, &s, yes || skipping, TRUE, resetok);
3250 if (sub2 == NULL && (!yes || !expand_string_forcedfail)) goto FAILED;
3251 expand_string_forcedfail = FALSE;
3252 if (*s++ != '}')
3253 {
3254 errwhere = US"'no' part did not start with '{'";
3255 goto FAILED_CURLY;
3256 }
3257
3258 /* If we want the second string, add it to the output */
3259
3260 if (!yes)
3261 *yieldptr = string_cat(*yieldptr, sizeptr, ptrptr, sub2);
3262 }
3263
3264 /* If there is no second string, but the word "fail" is present when the use of
3265 the second string is wanted, set a flag indicating it was a forced failure
3266 rather than a syntactic error. Swallow the terminating } in case this is nested
3267 inside another lookup or if or extract. */
3268
3269 else if (*s != '}')
3270 {
3271 uschar name[256];
3272 /* deconst cast ok here as source is s anyway */
3273 s = US read_name(name, sizeof(name), s, US"_");
3274 if (Ustrcmp(name, "fail") == 0)
3275 {
3276 if (!yes && !skipping)
3277 {
3278 while (isspace(*s)) s++;
3279 if (*s++ != '}')
3280 {
3281 errwhere = US"did not close with '}' after forcedfail";
3282 goto FAILED_CURLY;
3283 }
3284 expand_string_message =
3285 string_sprintf("\"%s\" failed and \"fail\" requested", type);
3286 expand_string_forcedfail = TRUE;
3287 goto FAILED;
3288 }
3289 }
3290 else
3291 {
3292 expand_string_message =
3293 string_sprintf("syntax error in \"%s\" item - \"fail\" expected", type);
3294 goto FAILED;
3295 }
3296 }
3297
3298 /* All we have to do now is to check on the final closing brace. */
3299
3300 while (isspace(*s)) s++;
3301 if (*s++ != '}')
3302 {
3303 errwhere = US"did not close with '}'";
3304 goto FAILED_CURLY;
3305 }
3306
3307
3308 RETURN:
3309 /* Update the input pointer value before returning */
3310 *sptr = s;
3311 return rc;
3312
3313 FAILED_CURLY:
3314 /* Get here if there is a bracketing failure */
3315 expand_string_message = string_sprintf(
3316 "curly-bracket problem in conditional yes/no parsing: %s\n"
3317 " remaining string is '%s'", errwhere, --s);
3318 rc = 2;
3319 goto RETURN;
3320
3321 FAILED:
3322 /* Get here for other failures */
3323 rc = 1;
3324 goto RETURN;
3325 }
3326
3327
3328
3329
3330 /*************************************************
3331 * Handle MD5 or SHA-1 computation for HMAC *
3332 *************************************************/
3333
3334 /* These are some wrapping functions that enable the HMAC code to be a bit
3335 cleaner. A good compiler will spot the tail recursion.
3336
3337 Arguments:
3338 type HMAC_MD5 or HMAC_SHA1
3339 remaining are as for the cryptographic hash functions
3340
3341 Returns: nothing
3342 */
3343
3344 static void
3345 chash_start(int type, void *base)
3346 {
3347 if (type == HMAC_MD5)
3348 md5_start((md5 *)base);
3349 else
3350 sha1_start((hctx *)base);
3351 }
3352
3353 static void
3354 chash_mid(int type, void *base, uschar *string)
3355 {
3356 if (type == HMAC_MD5)
3357 md5_mid((md5 *)base, string);
3358 else
3359 sha1_mid((hctx *)base, string);
3360 }
3361
3362 static void
3363 chash_end(int type, void *base, uschar *string, int length, uschar *digest)
3364 {