Fix taint hybrid-checking on BSD
[exim.git] / src / src / functions.h
... / ...
CommitLineData
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
5/* Copyright (c) University of Cambridge 1995 - 2018 */
6/* See the file NOTICE for conditions of use and distribution. */
7
8
9/* Prototypes for functions that appear in various modules. Gathered together
10to avoid having a lot of tiddly little headers with only a couple of lines in
11them. However, some functions that are used (or not used) by utility programs
12are in in fact in separate headers. */
13#ifndef _FUNCTIONS_H_
14#define _FUNCTIONS_H_
15
16#include <sys/time.h>
17
18
19#ifdef EXIM_PERL
20extern gstring *call_perl_cat(gstring *, uschar **, uschar *,
21 uschar **) WARN_UNUSED_RESULT;
22extern void cleanup_perl(void);
23extern uschar *init_perl(uschar *);
24#endif
25
26
27#ifndef DISABLE_TLS
28extern const char *
29 std_dh_prime_default(void);
30extern const char *
31 std_dh_prime_named(const uschar *);
32
33extern uschar * tls_cert_crl_uri(void *, uschar * mod);
34extern uschar * tls_cert_ext_by_oid(void *, uschar *, int);
35extern uschar * tls_cert_issuer(void *, uschar * mod);
36extern uschar * tls_cert_not_before(void *, uschar * mod);
37extern uschar * tls_cert_not_after(void *, uschar * mod);
38extern uschar * tls_cert_ocsp_uri(void *, uschar * mod);
39extern uschar * tls_cert_serial_number(void *, uschar * mod);
40extern uschar * tls_cert_signature(void *, uschar * mod);
41extern uschar * tls_cert_signature_algorithm(void *, uschar * mod);
42extern uschar * tls_cert_subject(void *, uschar * mod);
43extern uschar * tls_cert_subject_altname(void *, uschar * mod);
44extern uschar * tls_cert_version(void *, uschar * mod);
45
46extern uschar * tls_cert_der_b64(void * cert);
47extern uschar * tls_cert_fprt_md5(void *);
48extern uschar * tls_cert_fprt_sha1(void *);
49extern uschar * tls_cert_fprt_sha256(void *);
50
51extern void tls_clean_env(void);
52extern BOOL tls_client_start(client_conn_ctx *, smtp_connect_args *,
53 void *, tls_support *, uschar **);
54
55extern void tls_close(void *, int);
56extern BOOL tls_could_read(void);
57extern void tls_daemon_init(void);
58extern BOOL tls_dropprivs_validate_require_cipher(BOOL);
59extern BOOL tls_export_cert(uschar *, size_t, void *);
60extern int tls_feof(void);
61extern int tls_ferror(void);
62extern void tls_free_cert(void **);
63extern int tls_getc(unsigned);
64extern uschar *tls_getbuf(unsigned *);
65extern void tls_get_cache(void);
66extern BOOL tls_import_cert(const uschar *, void **);
67extern int tls_read(void *, uschar *, size_t);
68extern int tls_server_start(const uschar *, uschar **);
69extern BOOL tls_smtp_buffered(void);
70extern int tls_ungetc(int);
71extern int tls_write(void *, const uschar *, size_t, BOOL);
72extern uschar *tls_validate_require_cipher(void);
73extern void tls_version_report(FILE *);
74# ifdef USE_OPENSSL
75extern BOOL tls_openssl_options_parse(uschar *, long *);
76# endif
77extern uschar * tls_field_from_dn(uschar *, const uschar *);
78extern BOOL tls_is_name_for_cert(const uschar *, void *);
79
80# ifdef SUPPORT_DANE
81extern int tlsa_lookup(const host_item *, dns_answer *, BOOL);
82# endif
83
84#endif /*DISABLE_TLS*/
85
86
87/* Everything else... */
88
89extern acl_block *acl_read(uschar *(*)(void), uschar **);
90extern int acl_check(int, uschar *, uschar *, uschar **, uschar **);
91extern int acl_eval(int, uschar *, uschar **, uschar **);
92
93extern tree_node *acl_var_create(uschar *);
94extern void acl_var_write(uschar *, uschar *, void *);
95
96#ifdef EXPERIMENTAL_ARC
97extern void *arc_ams_setup_sign_bodyhash(void);
98extern const uschar *arc_header_feed(gstring *, BOOL);
99extern gstring *arc_sign(const uschar *, gstring *, uschar **);
100extern void arc_sign_init(void);
101extern const uschar *acl_verify_arc(void);
102extern uschar * fn_arc_domains(void);
103#endif
104
105extern void assert_no_variables(void *, int, const char *, int);
106extern int auth_call_pam(const uschar *, uschar **);
107extern int auth_call_pwcheck(uschar *, uschar **);
108extern int auth_call_radius(const uschar *, uschar **);
109extern int auth_call_saslauthd(const uschar *, const uschar *,
110 const uschar *, const uschar *, uschar **);
111extern int auth_check_serv_cond(auth_instance *);
112extern int auth_check_some_cond(auth_instance *, uschar *, uschar *, int);
113extern int auth_client_item(void *, auth_instance *, const uschar **,
114 unsigned, int, uschar *, int);
115
116
117extern int auth_get_data(uschar **, const uschar *, int);
118extern int auth_get_no64_data(uschar **, uschar *);
119extern int auth_prompt(const uschar *);
120extern int auth_read_input(const uschar *);
121extern void auth_show_supported(FILE *);
122extern uschar *auth_xtextencode(uschar *, int);
123extern int auth_xtextdecode(uschar *, uschar **);
124
125#ifdef EXPERIMENTAL_ARC
126extern gstring *authres_arc(gstring *);
127#endif
128#ifndef DISABLE_DKIM
129extern gstring *authres_dkim(gstring *);
130#endif
131#ifdef SUPPORT_DMARC
132extern gstring *authres_dmarc(gstring *);
133#endif
134extern gstring *authres_smtpauth(gstring *);
135#ifdef SUPPORT_SPF
136extern gstring *authres_spf(gstring *);
137#endif
138
139extern uschar *b64encode(const uschar *, int);
140extern uschar *b64encode_taint(const uschar *, int, BOOL);
141extern int b64decode(const uschar *, uschar **);
142extern int bdat_getc(unsigned);
143extern uschar *bdat_getbuf(unsigned *);
144extern int bdat_ungetc(int);
145extern void bdat_flush_data(void);
146
147extern void bits_clear(unsigned int *, size_t, int *);
148extern void bits_set(unsigned int *, size_t, int *);
149
150extern void cancel_cutthrough_connection(BOOL, const uschar *);
151extern int check_host(void *, const uschar *, const uschar **, uschar **);
152extern uschar **child_exec_exim(int, BOOL, int *, BOOL, int, ...);
153extern pid_t child_open_uid(const uschar **, const uschar **, int,
154 uid_t *, gid_t *, int *, int *, uschar *, BOOL);
155extern BOOL cleanup_environment(void);
156extern void cutthrough_data_puts(uschar *, int);
157extern void cutthrough_data_put_nl(void);
158extern uschar *cutthrough_finaldot(void);
159extern BOOL cutthrough_flush_send(void);
160extern BOOL cutthrough_headers_send(void);
161extern BOOL cutthrough_predata(void);
162extern void release_cutthrough_connection(const uschar *);
163
164extern void daemon_go(void);
165
166#ifdef EXPERIMENTAL_DCC
167extern int dcc_process(uschar **);
168#endif
169
170extern void debug_logging_activate(uschar *, uschar *);
171extern void debug_logging_stop(void);
172extern void debug_print_argv(const uschar **);
173extern void debug_print_ids(uschar *);
174extern void debug_printf_indent(const char *, ...) PRINTF_FUNCTION(1,2);
175extern void debug_print_string(uschar *);
176extern void debug_print_tree(tree_node *);
177extern void debug_vprintf(int, const char *, va_list);
178extern void decode_bits(unsigned int *, size_t, int *,
179 uschar *, bit_table *, int, uschar *, int);
180extern void delete_pid_file(void);
181extern address_item *deliver_make_addr(uschar *, BOOL);
182extern void delivery_log(int, address_item *, int, uschar *);
183extern int deliver_message(uschar *, BOOL, BOOL);
184extern void deliver_msglog(const char *, ...) PRINTF_FUNCTION(1,2);
185extern void deliver_set_expansions(address_item *);
186extern int deliver_split_address(address_item *);
187extern void deliver_succeeded(address_item *);
188
189extern uschar *deliver_get_sender_address (uschar *id);
190extern void delivery_re_exec(int);
191
192extern void die_tainted(const uschar *, const uschar *, int);
193extern BOOL directory_make(const uschar *, const uschar *, int, BOOL);
194#ifndef DISABLE_DKIM
195extern uschar *dkim_exim_query_dns_txt(const uschar *);
196extern void dkim_exim_sign_init(void);
197
198extern BOOL dkim_transport_write_message(transport_ctx *,
199 struct ob_dkim *, const uschar ** errstr);
200#endif
201extern dns_address *dns_address_from_rr(dns_answer *, dns_record *);
202extern int dns_basic_lookup(dns_answer *, const uschar *, int);
203extern uschar *dns_build_reverse(const uschar *);
204extern time_t dns_expire_from_soa(dns_answer *, int);
205extern void dns_init(BOOL, BOOL, BOOL);
206extern BOOL dns_is_aa(const dns_answer *);
207extern BOOL dns_is_secure(const dns_answer *);
208extern int dns_lookup(dns_answer *, const uschar *, int, const uschar **);
209extern void dns_pattern_init(void);
210extern int dns_special_lookup(dns_answer *, const uschar *, int, const uschar **);
211extern dns_record *dns_next_rr(const dns_answer *, dns_scan *, int);
212extern uschar *dns_text_type(int);
213extern void dscp_list_to_stream(FILE *);
214extern BOOL dscp_lookup(const uschar *, int, int *, int *, int *);
215
216extern void enq_end(uschar *);
217extern BOOL enq_start(uschar *, unsigned);
218#ifndef DISABLE_EVENT
219extern uschar *event_raise(uschar *, const uschar *, uschar *);
220extern void msg_event_raise(const uschar *, const address_item *);
221#endif
222
223extern int exim_chown_failure(int, const uschar*, uid_t, gid_t);
224extern const uschar * exim_errstr(int);
225extern void exim_exit(int, const uschar *) NORETURN;
226extern void exim_nullstd(void);
227extern void exim_setugid(uid_t, gid_t, BOOL, uschar *);
228extern void exim_underbar_exit(int);
229extern void exim_wait_tick(struct timeval *, int);
230extern int exp_bool(address_item *addr,
231 uschar *mtype, uschar *mname, unsigned dgb_opt, uschar *oname, BOOL bvalue,
232 uschar *svalue, BOOL *rvalue);
233extern BOOL expand_check_condition(uschar *, uschar *, uschar *);
234extern uschar *expand_file_big_buffer(const uschar *);
235extern uschar *expand_string(uschar *); /* public, cannot make const */
236extern const uschar *expand_cstring(const uschar *); /* ... so use this one */
237extern uschar *expand_hide_passwords(uschar * );
238extern uschar *expand_string_copy(const uschar *);
239extern int_eximarith_t expand_string_integer(uschar *, BOOL);
240extern void modify_variable(uschar *, void *);
241
242extern BOOL fd_ready(int, time_t);
243
244extern int filter_interpret(uschar *, int, address_item **, uschar **);
245extern BOOL filter_personal(string_item *, BOOL);
246extern BOOL filter_runtest(int, uschar *, BOOL, BOOL);
247extern BOOL filter_system_interpret(address_item **, uschar **);
248
249extern uschar * fn_hdrs_added(void);
250
251extern void header_add(int, const char *, ...);
252extern header_line *header_add_at_position_internal(BOOL, uschar *, BOOL, int, const char *, ...);
253extern int header_checkname(header_line *, BOOL);
254extern BOOL header_match(uschar *, BOOL, BOOL, string_item *, int, ...);
255extern int host_address_extract_port(uschar *);
256extern uschar *host_and_ident(BOOL);
257extern int host_aton(const uschar *, int *);
258extern void host_build_hostlist(host_item **, const uschar *, BOOL);
259extern ip_address_item *host_build_ifacelist(const uschar *, uschar *);
260extern void host_build_log_info(void);
261extern void host_build_sender_fullhost(void);
262extern int host_find_byname(host_item *, const uschar *, int,
263 const uschar **, BOOL);
264extern int host_find_bydns(host_item *, const uschar *, int, uschar *, uschar *,
265 uschar *, const dnssec_domains *, const uschar **, BOOL *);
266extern ip_address_item *host_find_interfaces(void);
267extern BOOL host_is_in_net(const uschar *, const uschar *, int);
268extern BOOL host_is_tls_on_connect_port(int);
269extern int host_item_get_port(host_item *);
270extern void host_mask(int, int *, int);
271extern int host_name_lookup(void);
272extern int host_nmtoa(int, int *, int, uschar *, int);
273extern uschar *host_ntoa(int, const void *, uschar *, int *);
274extern int host_scan_for_local_hosts(host_item *, host_item **, BOOL *);
275
276extern uschar *imap_utf7_encode(uschar *, const uschar *,
277 uschar, uschar *, uschar **);
278
279extern void invert_address(uschar *, uschar *);
280extern int ip_addr(void *, int, const uschar *, int);
281extern int ip_bind(int, int, uschar *, int);
282extern int ip_connect(int, int, const uschar *, int, int, const blob *);
283extern int ip_connectedsocket(int, const uschar *, int, int,
284 int, host_item *, uschar **, const blob *);
285extern int ip_get_address_family(int);
286extern void ip_keepalive(int, const uschar *, BOOL);
287extern int ip_recv(client_conn_ctx *, uschar *, int, time_t);
288extern int ip_socket(int, int);
289
290extern int ip_tcpsocket(const uschar *, uschar **, int);
291extern int ip_unixsocket(const uschar *, uschar **);
292extern int ip_streamsocket(const uschar *, uschar **, int);
293
294extern int ipv6_nmtoa(int *, uschar *);
295
296extern uschar *local_part_quote(uschar *);
297extern int log_create(uschar *);
298extern int log_create_as_exim(uschar *);
299extern void log_close_all(void);
300
301extern macro_item * macro_create(const uschar *, const uschar *, BOOL);
302extern BOOL macro_read_assignment(uschar *);
303extern uschar *macros_expand(int, int *, BOOL *);
304extern void mainlog_close(void);
305#ifdef WITH_CONTENT_SCAN
306extern int malware(const uschar *, int);
307extern int malware_in_file(uschar *);
308extern void malware_init(void);
309extern void malware_show_supported(FILE *);
310#endif
311extern int match_address_list(const uschar *, BOOL, BOOL, const uschar **,
312 unsigned int *, int, int, const uschar **);
313extern int match_address_list_basic(const uschar *, const uschar **, int);
314extern int match_check_list(const uschar **, int, tree_node **, unsigned int **,
315 int(*)(void *, const uschar *, const uschar **, uschar **), void *, int,
316 const uschar *, const uschar **);
317extern int match_isinlist(const uschar *, const uschar **, int, tree_node **,
318 unsigned int *, int, BOOL, const uschar **);
319extern int match_check_string(const uschar *, const uschar *, int, BOOL, BOOL, BOOL,
320 const uschar **);
321extern void md5_end(md5 *, const uschar *, int, uschar *);
322extern void md5_mid(md5 *, const uschar *);
323extern void md5_start(md5 *);
324extern void millisleep(int);
325#ifdef WITH_CONTENT_SCAN
326struct mime_boundary_context;
327extern int mime_acl_check(uschar *acl, FILE *f,
328 struct mime_boundary_context *, uschar **, uschar **);
329extern int mime_decode(const uschar **);
330extern ssize_t mime_decode_base64(FILE *, FILE *, uschar *);
331extern int mime_regex(const uschar **);
332extern void mime_set_anomaly(int);
333#endif
334extern uschar *moan_check_errorcopy(uschar *);
335extern BOOL moan_skipped_syntax_errors(uschar *, error_block *, uschar *,
336 BOOL, uschar *);
337extern void moan_smtp_batch(uschar *, const char *, ...) PRINTF_FUNCTION(2,3);
338extern BOOL moan_send_message(uschar *, int, error_block *eblock,
339 header_line *, FILE *, uschar *);
340extern void moan_tell_someone(uschar *, address_item *,
341 const uschar *, const char *, ...) PRINTF_FUNCTION(4,5);
342extern BOOL moan_to_sender(int, error_block *, header_line *, FILE *, BOOL);
343extern void moan_write_from(FILE *);
344extern void moan_write_references(FILE *, uschar *);
345extern FILE *modefopen(const uschar *, const char *, mode_t);
346
347extern int open_cutthrough_connection( address_item * addr );
348
349extern uschar *parse_extract_address(uschar *, uschar **, int *, int *, int *,
350 BOOL);
351extern int parse_forward_list(uschar *, int, address_item **, uschar **,
352 const uschar *, uschar *, error_block **);
353extern uschar *parse_find_address_end(uschar *, BOOL);
354extern uschar *parse_find_at(uschar *);
355extern const uschar *parse_fix_phrase(const uschar *, int, uschar *, int);
356extern uschar *parse_message_id(uschar *, uschar **, uschar **);
357extern const uschar *parse_quote_2047(const uschar *, int, uschar *, uschar *, int, BOOL);
358extern uschar *parse_date_time(uschar *str, time_t *t);
359extern int vaguely_random_number(int);
360#ifndef DISABLE_TLS
361extern int vaguely_random_number_fallback(int);
362#endif
363
364extern BOOL queue_action(uschar *, int, uschar **, int, int);
365extern void queue_check_only(void);
366extern void queue_list(int, uschar **, int);
367extern void queue_count(void);
368extern void queue_run(uschar *, uschar *, BOOL);
369
370extern int random_number(int);
371extern const uschar *rc_to_string(int);
372extern int rda_interpret(redirect_block *, int, uschar *, uschar *,
373 uschar *, uschar *, uschar *, ugid_block *, address_item **,
374 uschar **, error_block **, int *, uschar *);
375extern int rda_is_filter(const uschar *);
376extern BOOL readconf_depends(driver_instance *, uschar *);
377extern void readconf_driver_init(uschar *, driver_instance **,
378 driver_info *, int, void *, int, optionlist *, int);
379extern uschar *readconf_find_option(void *);
380extern void readconf_main(BOOL);
381extern void readconf_options_from_list(optionlist *, unsigned, const uschar *, uschar *);
382extern BOOL readconf_print(uschar *, uschar *, BOOL);
383extern uschar *readconf_printtime(int);
384extern uschar *readconf_readname(uschar *, int, uschar *);
385extern int readconf_readtime(const uschar *, int, BOOL);
386extern void readconf_rest(void);
387extern uschar *readconf_retry_error(const uschar *, const uschar *, int *, int *);
388extern void readconf_save_config(const uschar *);
389extern void read_message_body(BOOL);
390extern void receive_bomb_out(uschar *, uschar *) NORETURN;
391extern BOOL receive_check_fs(int);
392extern BOOL receive_check_set_sender(uschar *);
393extern BOOL receive_msg(BOOL);
394extern int_eximarith_t receive_statvfs(BOOL, int *);
395extern void receive_swallow_smtp(void);
396#ifdef WITH_CONTENT_SCAN
397extern int regex(const uschar **);
398#endif
399extern BOOL regex_match_and_setup(const pcre *, const uschar *, int, int);
400extern const pcre *regex_must_compile(const uschar *, BOOL, BOOL);
401extern void retry_add_item(address_item *, uschar *, int);
402extern BOOL retry_check_address(const uschar *, host_item *, uschar *, BOOL,
403 uschar **, uschar **);
404extern retry_config *retry_find_config(const uschar *, const uschar *, int, int);
405extern BOOL retry_ultimate_address_timeout(uschar *, const uschar *,
406 dbdata_retry *, time_t);
407extern void retry_update(address_item **, address_item **, address_item **);
408extern uschar *rewrite_address(uschar *, BOOL, BOOL, rewrite_rule *, int);
409extern uschar *rewrite_address_qualify(uschar *, BOOL);
410extern header_line *rewrite_header(header_line *,
411 const uschar *, const uschar *,
412 rewrite_rule *, int, BOOL);
413extern uschar *rewrite_one(uschar *, int, BOOL *, BOOL, uschar *,
414 rewrite_rule *);
415extern void rewrite_test(uschar *);
416extern uschar *rfc2047_decode2(uschar *, BOOL, uschar *, int, int *, int *,
417 uschar **);
418extern int route_address(address_item *, address_item **, address_item **,
419 address_item **, address_item **, int);
420extern int route_check_prefix(const uschar *, const uschar *);
421extern int route_check_suffix(const uschar *, const uschar *);
422extern BOOL route_findgroup(uschar *, gid_t *);
423extern BOOL route_finduser(const uschar *, struct passwd **, uid_t *);
424extern BOOL route_find_expanded_group(uschar *, uschar *, uschar *, gid_t *,
425 uschar **);
426extern BOOL route_find_expanded_user(uschar *, uschar *, uschar *,
427 struct passwd **, uid_t *, uschar **);
428extern void route_init(void);
429extern void route_show_supported(FILE *);
430extern void route_tidyup(void);
431
432extern uschar *search_find(void *, uschar *, uschar *, int, const uschar *, int,
433 int, int *);
434extern int search_findtype(const uschar *, int);
435extern int search_findtype_partial(const uschar *, int *, const uschar **, int *,
436 int *);
437extern void *search_open(uschar *, int, int, uid_t *, gid_t *);
438extern void search_tidyup(void);
439extern void set_process_info(const char *, ...) PRINTF_FUNCTION(1,2);
440extern void sha1_end(hctx *, const uschar *, int, uschar *);
441extern void sha1_mid(hctx *, const uschar *);
442extern void sha1_start(hctx *);
443extern int sieve_interpret(uschar *, int, uschar *, uschar *, uschar *,
444 uschar *, address_item **, uschar **);
445extern void sigalrm_handler(int);
446extern BOOL smtp_buffered(void);
447extern void smtp_closedown(uschar *);
448extern void smtp_command_timeout_exit(void) NORETURN;
449extern void smtp_command_sigterm_exit(void) NORETURN;
450extern void smtp_data_timeout_exit(void) NORETURN;
451extern void smtp_data_sigint_exit(void) NORETURN;
452extern void smtp_deliver_init(void);
453extern uschar *smtp_cmd_hist(void);
454extern int smtp_connect(smtp_connect_args *, const blob *);
455extern int smtp_sock_connect(host_item *, int, int, uschar *,
456 transport_instance * tb, int, const blob *);
457extern int smtp_feof(void);
458extern int smtp_ferror(void);
459extern uschar *smtp_get_connection_info(void);
460extern BOOL smtp_get_interface(uschar *, int, address_item *,
461 uschar **, uschar *);
462extern BOOL smtp_get_port(uschar *, address_item *, int *, uschar *);
463extern int smtp_getc(unsigned);
464extern uschar *smtp_getbuf(unsigned *);
465extern void smtp_get_cache(void);
466extern int smtp_handle_acl_fail(int, int, uschar *, uschar *);
467extern void smtp_log_no_mail(void);
468extern void smtp_message_code(uschar **, int *, uschar **, uschar **, BOOL);
469extern void smtp_proxy_tls(void *, uschar *, size_t, int *, int) NORETURN;
470extern BOOL smtp_read_response(void *, uschar *, int, int, int);
471extern void *smtp_reset(void *);
472extern void smtp_respond(uschar *, int, BOOL, uschar *);
473extern void smtp_notquit_exit(uschar *, uschar *, uschar *, ...);
474extern void smtp_port_for_connect(host_item *, int);
475extern void smtp_send_prohibition_message(int, uschar *);
476extern int smtp_setup_msg(void);
477extern BOOL smtp_start_session(void);
478extern int smtp_ungetc(int);
479extern BOOL smtp_verify_helo(void);
480extern int smtp_write_command(void *, int, const char *, ...) PRINTF_FUNCTION(3,4);
481#ifdef WITH_CONTENT_SCAN
482extern int spam(const uschar **);
483extern FILE *spool_mbox(unsigned long *, const uschar *, uschar **);
484#endif
485extern void spool_clear_header_globals(void);
486extern BOOL spool_move_message(uschar *, uschar *, uschar *, uschar *);
487extern int spool_open_datafile(uschar *);
488extern int spool_open_temp(uschar *);
489extern int spool_read_header(uschar *, BOOL, BOOL);
490extern int spool_write_header(uschar *, int, uschar **);
491extern int stdin_getc(unsigned);
492extern int stdin_feof(void);
493extern int stdin_ferror(void);
494extern int stdin_ungetc(int);
495
496extern void store_exit(void);
497extern gstring *string_append(gstring *, int, ...) WARN_UNUSED_RESULT;
498extern gstring *string_append_listele(gstring *, uschar, const uschar *) WARN_UNUSED_RESULT;
499extern gstring *string_append_listele_n(gstring *, uschar, const uschar *, unsigned) WARN_UNUSED_RESULT;
500extern gstring *string_append2_listele_n(gstring *, const uschar *, const uschar *, unsigned) WARN_UNUSED_RESULT;
501extern uschar *string_base62(unsigned long int);
502extern gstring *string_cat (gstring *, const uschar * ) WARN_UNUSED_RESULT;
503extern gstring *string_catn(gstring *, const uschar *, int) WARN_UNUSED_RESULT;
504extern int string_compare_by_pointer(const void *, const void *);
505extern uschar *string_copy_dnsdomain(uschar *);
506extern uschar *string_copy_malloc(const uschar *);
507extern uschar *string_dequote(const uschar **);
508extern uschar *string_format_size(int, uschar *);
509extern int string_interpret_escape(const uschar **);
510extern int string_is_ip_address(const uschar *, int *);
511#ifdef SUPPORT_I18N
512extern BOOL string_is_utf8(const uschar *);
513#endif
514extern uschar *string_nextinlist(const uschar **, int *, uschar *, int);
515extern const uschar *string_printing2(const uschar *, BOOL);
516extern uschar *string_split_message(uschar *);
517extern uschar *string_unprinting(uschar *);
518#ifdef SUPPORT_I18N
519extern uschar *string_address_utf8_to_alabel(const uschar *, uschar **);
520extern uschar *string_domain_alabel_to_utf8(const uschar *, uschar **);
521extern uschar *string_domain_utf8_to_alabel(const uschar *, uschar **);
522extern uschar *string_localpart_alabel_to_utf8(const uschar *, uschar **);
523extern uschar *string_localpart_utf8_to_alabel(const uschar *, uschar **);
524#endif
525
526#define string_format(buf, siz, fmt, ...) \
527 string_format_trc(buf, siz, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
528extern BOOL string_format_trc(uschar *, int, const uschar *, unsigned,
529 const char *, ...) ALMOST_PRINTF(5,6);
530
531#define string_vformat(g, flgs, fmt, ap) \
532 string_vformat_trc(g, US __FUNCTION__, __LINE__, \
533 STRING_SPRINTF_BUFFER_SIZE, flgs, fmt, ap)
534extern gstring *string_vformat_trc(gstring *, const uschar *, unsigned,
535 unsigned, unsigned, const char *, va_list);
536
537#define string_open_failed(eno, fmt, ...) \
538 string_open_failed_trc(eno, US __FUNCTION__, __LINE__, fmt, __VA_ARGS__)
539extern uschar *string_open_failed_trc(int, const uschar *, unsigned,
540 const char *, ...) PRINTF_FUNCTION(4,5);
541
542extern int strcmpic(const uschar *, const uschar *);
543extern int strncmpic(const uschar *, const uschar *, int);
544extern uschar *strstric(uschar *, uschar *, BOOL);
545
546extern int test_harness_fudged_queue_time(int);
547extern void tcp_init(void);
548#ifdef EXIM_TFO_PROBE
549extern void tfo_probe(void);
550#endif
551extern void tls_modify_variables(tls_support *);
552extern uschar *tod_stamp(int);
553
554extern BOOL transport_check_waiting(const uschar *, const uschar *, int, uschar *,
555 BOOL *, oicf, void*);
556extern void transport_init(void);
557extern void transport_do_pass_socket(const uschar *, const uschar *,
558 const uschar *, uschar *, int);
559extern BOOL transport_pass_socket(const uschar *, const uschar *, const uschar *, uschar *,
560 int);
561extern uschar *transport_rcpt_address(address_item *, BOOL);
562extern BOOL transport_set_up_command(const uschar ***, uschar *,
563 BOOL, int, address_item *, uschar *, uschar **);
564extern void transport_update_waiting(host_item *, uschar *);
565extern BOOL transport_write_block(transport_ctx *, uschar *, int, BOOL);
566extern void transport_write_reset(int);
567extern BOOL transport_write_string(int, const char *, ...);
568extern BOOL transport_headers_send(transport_ctx *,
569 BOOL (*)(transport_ctx *, uschar *, int));
570extern void transport_show_supported(FILE *);
571extern BOOL transport_write_message(transport_ctx *, int);
572extern void tree_add_duplicate(uschar *, address_item *);
573extern void tree_add_nonrecipient(uschar *);
574extern void tree_add_unusable(host_item *);
575extern void tree_dup(tree_node **, tree_node *);
576extern int tree_insertnode(tree_node **, tree_node *);
577extern tree_node *tree_search(tree_node *, const uschar *);
578extern void tree_write(tree_node *, FILE *);
579extern void tree_walk(tree_node *, void (*)(uschar*, uschar*, void*), void *);
580
581#ifdef WITH_CONTENT_SCAN
582extern void unspool_mbox(void);
583#endif
584#ifdef SUPPORT_I18N
585extern void utf8_version_report(FILE *);
586#endif
587
588extern int verify_address(address_item *, FILE *, int, int, int, int,
589 uschar *, uschar *, BOOL *);
590extern int verify_check_dnsbl(int, const uschar **, uschar **);
591extern int verify_check_header_address(uschar **, uschar **, int, int, int,
592 uschar *, uschar *, int, int *);
593extern int verify_check_headers(uschar **);
594extern int verify_check_header_names_ascii(uschar **);
595extern int verify_check_host(uschar **);
596extern int verify_check_notblind(BOOL);
597extern int verify_check_given_host(const uschar **, const host_item *);
598extern int verify_check_this_host(const uschar **, unsigned int *,
599 const uschar*, const uschar *, const uschar **);
600extern address_item *verify_checked_sender(uschar *);
601extern void verify_get_ident(int);
602extern BOOL verify_sender(int *, uschar **);
603extern BOOL verify_sender_preliminary(int *, uschar **);
604extern void version_init(void);
605
606extern BOOL write_chunk(transport_ctx *, uschar *, int);
607extern ssize_t write_to_fd_buf(int, const uschar *, size_t);
608
609
610/******************************************************************************/
611/* Predicate: if an address is in a tainted pool.
612By extension, a variable pointing to this address is tainted.
613*/
614
615static inline BOOL
616is_tainted(const void * p)
617{
618#if defined(COMPILE_UTILITY) || defined(MACRO_PREDEF) || defined(EM_VERSION_C)
619return FALSE;
620
621#else
622extern BOOL is_tainted_fn(const void *);
623extern void * tainted_base, * tainted_top;
624
625return f.taint_check_slow
626 ? is_tainted_fn(p) : p >= tainted_base && p < tainted_top;
627#endif
628}
629
630/******************************************************************************/
631/* String functions */
632static inline uschar * __Ustrcat(uschar * dst, const uschar * src, const char * func, int line)
633{
634#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF)
635if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrcat", CUS func, line);
636#endif
637return US strcat(CS dst, CCS src);
638}
639static inline uschar * __Ustrcpy(uschar * dst, const uschar * src, const char * func, int line)
640{
641#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF)
642if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrcpy", CUS func, line);
643#endif
644return US strcpy(CS dst, CCS src);
645}
646static inline uschar * __Ustrncat(uschar * dst, const uschar * src, size_t n, const char * func, int line)
647{
648#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF)
649if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrncat", CUS func, line);
650#endif
651return US strncat(CS dst, CCS src, n);
652}
653static inline uschar * __Ustrncpy(uschar * dst, const uschar * src, size_t n, const char * func, int line)
654{
655#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF)
656if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrncpy", CUS func, line);
657#endif
658return US strncpy(CS dst, CCS src, n);
659}
660/*XXX will likely need unchecked copy also */
661
662
663/******************************************************************************/
664
665#if !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
666/* exim_chown - in some NFSv4 setups *seemes* to be an issue with
667chown(<exim-uid>, <exim-gid>).
668
669Probably because the idmapping is broken, misconfigured or set up in
670an unusal way. (see Bug 2931). As I'm not sure, if this was a single
671case of misconfiguration, or if there are more such broken systems
672out, I try to impose as least impact as possible and for now just write
673a panic log entry pointing to the bug report. You're encouraged to
674contact the developers, if you experience this issue.
675
676fd the file descriptor (or -1 if not valid)
677name the file name for error messages or for file operations,
678 if fd is < 0
679owner the owner
680group the group
681
682returns 0 on success, -1 on failure */
683
684static inline int
685exim_fchown(int fd, uid_t owner, gid_t group, const uschar *name)
686{
687return fchown(fd, owner, group)
688 ? exim_chown_failure(fd, name, owner, group) : 0;
689}
690
691static inline int
692exim_chown(const uschar *name, uid_t owner, gid_t group)
693{
694return chown(CCS name, owner, group)
695 ? exim_chown_failure(-1, name, owner, group) : 0;
696}
697#endif /* !MACRO_PREDEF && !COMPILE_UTILITY */
698
699/******************************************************************************/
700/* String functions */
701
702#if !defined(MACRO_PREDEF)
703/*************************************************
704* Copy and save string *
705*************************************************/
706
707/* This function assumes that memcpy() is faster than strcpy().
708*/
709
710static inline uschar *
711string_copy_taint_trc(const uschar *s, BOOL tainted, const char * func, int line)
712{
713int len = Ustrlen(s) + 1;
714uschar *ss = store_get_3(len, tainted, func, line);
715memcpy(ss, s, len);
716return ss;
717}
718
719#define string_copy_taint(s, tainted) \
720 string_copy_taint_trc((s), tainted, __FUNCTION__, __LINE__)
721
722static inline uschar *
723string_copy_trc(const uschar * s, const char * func, int line)
724{
725return string_copy_taint_trc((s), is_tainted(s), func, line);
726}
727
728#define string_copy(s) \
729 string_copy_trc((s), __FUNCTION__, __LINE__)
730
731
732/*************************************************
733* Copy, lowercase and save string *
734*************************************************/
735
736/*
737Argument: string to copy
738Returns: copy of string in new store, with letters lowercased
739*/
740
741static inline uschar *
742string_copylc(const uschar *s)
743{
744uschar *ss = store_get(Ustrlen(s) + 1, is_tainted(s));
745uschar *p = ss;
746while (*s != 0) *p++ = tolower(*s++);
747*p = 0;
748return ss;
749}
750
751
752
753/*************************************************
754* Copy and save string, given length *
755*************************************************/
756
757/* It is assumed the data contains no zeros. A zero is added
758onto the end.
759
760Arguments:
761 s string to copy
762 n number of characters
763
764Returns: copy of string in new store
765
766This is an API for local_scan hence not static.
767*/
768
769static inline uschar *
770string_copyn(const uschar *s, int n)
771{
772uschar *ss = store_get(n + 1, is_tainted(s));
773Ustrncpy(ss, s, n);
774ss[n] = 0;
775return ss;
776}
777
778/*************************************************
779* Copy, lowercase, and save string, given length *
780*************************************************/
781
782/* It is assumed the data contains no zeros. A zero is added
783onto the end.
784
785Arguments:
786 s string to copy
787 n number of characters
788
789Returns: copy of string in new store, with letters lowercased
790*/
791
792static inline uschar *
793string_copynlc(uschar *s, int n)
794{
795uschar *ss = store_get(n + 1, is_tainted(s));
796uschar *p = ss;
797while (n-- > 0) *p++ = tolower(*s++);
798*p = 0;
799return ss;
800}
801
802
803# ifndef COMPILE_UTILITY
804/*************************************************
805* Copy and save string in longterm store *
806*************************************************/
807
808/* This function assumes that memcpy() is faster than strcpy().
809
810Argument: string to copy
811Returns: copy of string in new store
812*/
813
814static inline uschar *
815string_copy_perm(const uschar *s, BOOL force_taint)
816{
817int old_pool = store_pool;
818int len = Ustrlen(s) + 1;
819uschar *ss;
820
821store_pool = POOL_PERM;
822ss = store_get(len, force_taint || is_tainted(s));
823memcpy(ss, s, len);
824store_pool = old_pool;
825return ss;
826}
827# endif
828
829
830
831/* sprintf into a buffer, taint-unchecked */
832
833static inline void
834string_format_nt(uschar * buf, int siz, const char * fmt, ...)
835{
836gstring gs = { .size = siz, .ptr = 0, .s = buf };
837va_list ap;
838va_start(ap, fmt);
839(void) string_vformat(&gs, SVFMT_TAINT_NOCHK, fmt, ap);
840va_end(ap);
841}
842
843
844
845/******************************************************************************/
846/* Growable-string functions */
847
848/* Create a growable-string with some preassigned space */
849
850#define string_get_tainted(size, tainted) \
851 string_get_tainted_trc((size), (tainted), __FUNCTION__, __LINE__)
852
853static inline gstring *
854string_get_tainted_trc(unsigned size, BOOL tainted, const char * func, unsigned line)
855{
856gstring * g = store_get_3(sizeof(gstring) + size, tainted, func, line);
857g->size = size;
858g->ptr = 0;
859g->s = US(g + 1);
860return g;
861}
862
863#define string_get(size) \
864 string_get_trc((size), __FUNCTION__, __LINE__)
865
866static inline gstring *
867string_get_trc(unsigned size, const char * func, unsigned line)
868{
869return string_get_tainted_trc(size, FALSE, func, line);
870}
871
872/* NUL-terminate the C string in the growable-string, and return it. */
873
874static inline uschar *
875string_from_gstring(gstring * g)
876{
877if (!g) return NULL;
878g->s[g->ptr] = '\0';
879return g->s;
880}
881
882static inline unsigned
883gstring_length(const gstring * g)
884{
885return g ? (unsigned)g->ptr : 0;
886}
887
888
889#define gstring_release_unused(g) \
890 gstring_release_unused_trc(g, __FUNCTION__, __LINE__)
891
892static inline void
893gstring_release_unused_trc(gstring * g, const char * file, unsigned line)
894{
895if (g) store_release_above_3(g->s + (g->size = g->ptr + 1), file, line);
896}
897
898
899/* sprintf-append to a growable-string */
900
901#define string_fmt_append(g, fmt, ...) \
902 string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \
903 SVFMT_EXTEND|SVFMT_REBUFFER, fmt, __VA_ARGS__)
904
905#define string_fmt_append_f(g, flgs, fmt, ...) \
906 string_fmt_append_f_trc(g, US __FUNCTION__, __LINE__, \
907 flgs, fmt, __VA_ARGS__)
908
909static inline gstring *
910string_fmt_append_f_trc(gstring * g, const uschar * func, unsigned line,
911 unsigned flags, const char *format, ...)
912{
913va_list ap;
914va_start(ap, format);
915g = string_vformat_trc(g, func, line, STRING_SPRINTF_BUFFER_SIZE,
916 flags, format, ap);
917va_end(ap);
918return g;
919}
920
921/******************************************************************************/
922
923#define store_get_dns_answer() store_get_dns_answer_trc(CUS __FUNCTION__, __LINE__)
924
925static inline dns_answer *
926store_get_dns_answer_trc(const uschar * func, unsigned line)
927{
928return store_get_3(sizeof(dns_answer), TRUE, CCS func, line); /* use tainted mem */
929}
930
931/******************************************************************************/
932/* Routines with knowledge of spool layout */
933
934# ifndef COMPILE_UTILITY
935static inline void
936spool_pname_buf(uschar * buf, int len)
937{
938snprintf(CS buf, len, "%s/%s/input", spool_directory, queue_name);
939}
940
941static inline uschar *
942spool_dname(const uschar * purpose, uschar * subdir)
943{
944return string_sprintf("%s/%s/%s/%s",
945 spool_directory, queue_name, purpose, subdir);
946}
947# endif
948
949static inline uschar *
950spool_q_sname(const uschar * purpose, const uschar * q, uschar * subdir)
951{
952return string_sprintf("%s%s%s%s%s",
953 q, *q ? "/" : "",
954 purpose,
955 *subdir ? "/" : "", subdir);
956}
957
958static inline uschar *
959spool_sname(const uschar * purpose, uschar * subdir)
960{
961return spool_q_sname(purpose, queue_name, subdir);
962}
963
964static inline uschar *
965spool_q_fname(const uschar * purpose, const uschar * q,
966 const uschar * subdir, const uschar * fname, const uschar * suffix)
967{
968return string_sprintf("%s/%s/%s/%s/%s%s",
969 spool_directory, q, purpose, subdir, fname, suffix);
970}
971
972static inline uschar *
973spool_fname(const uschar * purpose, const uschar * subdir, const uschar * fname,
974 const uschar * suffix)
975{
976#ifdef COMPILE_UTILITY /* version avoiding string-extension */
977int len = Ustrlen(spool_directory) + 1 + Ustrlen(queue_name) + 1 + Ustrlen(purpose) + 1
978 + Ustrlen(subdir) + 1 + Ustrlen(fname) + Ustrlen(suffix) + 1;
979uschar * buf = store_get(len, FALSE);
980string_format(buf, len, "%s/%s/%s/%s/%s%s",
981 spool_directory, queue_name, purpose, subdir, fname, suffix);
982return buf;
983#else
984return spool_q_fname(purpose, queue_name, subdir, fname, suffix);
985#endif
986}
987
988static inline void
989set_subdir_str(uschar * subdir_str, const uschar * name,
990 int search_sequence)
991{
992subdir_str[0] = split_spool_directory == (search_sequence == 0)
993 ? name[5] : '\0';
994subdir_str[1] = '\0';
995}
996
997/******************************************************************************/
998/* Time calculations */
999
1000static inline void
1001timesince(struct timeval * diff, const struct timeval * then)
1002{
1003gettimeofday(diff, NULL);
1004diff->tv_sec -= then->tv_sec;
1005if ((diff->tv_usec -= then->tv_usec) < 0)
1006 {
1007 diff->tv_sec--;
1008 diff->tv_usec += 1000*1000;
1009 }
1010}
1011
1012static inline uschar *
1013string_timediff(const struct timeval * diff)
1014{
1015static uschar buf[sizeof("0.000s")];
1016
1017if (diff->tv_sec >= 5 || !LOGGING(millisec))
1018 return readconf_printtime((int)diff->tv_sec);
1019
1020snprintf(CS buf, sizeof(buf), "%u.%03us", (uint)diff->tv_sec, (uint)diff->tv_usec/1000);
1021return buf;
1022}
1023
1024
1025static inline uschar *
1026string_timesince(const struct timeval * then)
1027{
1028struct timeval diff;
1029timesince(&diff, then);
1030return string_timediff(&diff);
1031}
1032
1033static inline void
1034report_time_since(const struct timeval * t0, const uschar * where)
1035{
1036# ifdef MEASURE_TIMING
1037struct timeval diff;
1038timesince(&diff, t0);
1039fprintf(stderr, "%d %s:\t%ld.%06ld\n",
1040 (uint)getpid(), where, (long)diff.tv_sec, (long)diff.tv_usec);
1041# endif
1042}
1043
1044
1045static inline void
1046testharness_pause_ms(int millisec)
1047{
1048#ifndef MEASURE_TIMING
1049if (f.running_in_test_harness) millisleep(millisec);
1050#endif
1051}
1052
1053/******************************************************************************/
1054/* Taint-checked file opens */
1055
1056static inline int
1057exim_open2(const char *pathname, int flags)
1058{
1059if (!is_tainted(pathname)) return open(pathname, flags);
1060log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
1061errno = EACCES;
1062return -1;
1063}
1064static inline int
1065exim_open(const char *pathname, int flags, mode_t mode)
1066{
1067if (!is_tainted(pathname)) return open(pathname, flags, mode);
1068log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
1069errno = EACCES;
1070return -1;
1071}
1072static inline int
1073exim_openat(int dirfd, const char *pathname, int flags)
1074{
1075if (!is_tainted(pathname)) return openat(dirfd, pathname, flags);
1076log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
1077errno = EACCES;
1078return -1;
1079}
1080static inline int
1081exim_openat4(int dirfd, const char *pathname, int flags, mode_t mode)
1082{
1083if (!is_tainted(pathname)) return openat(dirfd, pathname, flags, mode);
1084log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
1085errno = EACCES;
1086return -1;
1087}
1088
1089static inline FILE *
1090exim_fopen(const char *pathname, const char *mode)
1091{
1092if (!is_tainted(pathname)) return fopen(pathname, mode);
1093log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'\n", pathname);
1094errno = EACCES;
1095return NULL;
1096}
1097
1098#endif /* !MACRO_PREDEF */
1099
1100#endif /* _FUNCTIONS_H_ */
1101
1102/* vi: aw
1103*/
1104/* End of functions.h */