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