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