X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/f870028fd26f8ac1a2fcb6e43e0d7d1c76c110ec..dbab2d6f08acd5ccf71d5e8a6cdc1224ab857d7a:/src/src/functions.h diff --git a/src/src/functions.h b/src/src/functions.h index 0f962b313..9c222223b 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -3,7 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 1995 - 2018 */ -/* Copyright (c) The Exim Maintainers 2020 */ +/* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -56,9 +56,9 @@ extern BOOL tls_client_start(client_conn_ctx *, smtp_connect_args *, extern void tls_client_creds_reload(BOOL); extern void tls_close(void *, int); -extern BOOL tls_could_read(void); +extern BOOL tls_could_getc(void); extern void tls_daemon_init(void); -extern void tls_daemon_tick(void); +extern int tls_daemon_tick(void); extern BOOL tls_dropprivs_validate_require_cipher(BOOL); extern BOOL tls_export_cert(uschar *, size_t, void *); extern int tls_feof(void); @@ -67,7 +67,8 @@ extern uschar *tls_field_from_dn(uschar *, const uschar *); extern void tls_free_cert(void **); extern int tls_getc(unsigned); extern uschar *tls_getbuf(unsigned *); -extern void tls_get_cache(void); +extern void tls_get_cache(unsigned); +extern BOOL tls_hasc(void); extern BOOL tls_import_cert(const uschar *, void **); extern BOOL tls_is_name_for_cert(const uschar *, void *); # ifdef USE_OPENSSL @@ -84,7 +85,7 @@ extern void tls_watch_invalidate(void); #endif extern int tls_write(void *, const uschar *, size_t, BOOL); extern uschar *tls_validate_require_cipher(void); -extern void tls_version_report(FILE *); +extern gstring *tls_version_report(gstring *); # ifdef SUPPORT_DANE extern int tlsa_lookup(const host_item *, dns_answer *, BOOL); @@ -150,6 +151,7 @@ extern uschar *b64encode_taint(const uschar *, int, BOOL); extern int b64decode(const uschar *, uschar **); extern int bdat_getc(unsigned); extern uschar *bdat_getbuf(unsigned *); +extern BOOL bdat_hasc(void); extern int bdat_ungetc(int); extern void bdat_flush_data(void); @@ -184,14 +186,17 @@ extern int dcc_process(uschar **); #endif extern void debug_logging_activate(uschar *, uschar *); -extern void debug_logging_stop(void); +extern void debug_logging_stop(BOOL); extern void debug_print_argv(const uschar **); extern void debug_print_ids(uschar *); extern void debug_printf_indent(const char *, ...) PRINTF_FUNCTION(1,2); extern void debug_print_string(uschar *); extern void debug_print_tree(const char *, tree_node *); extern void debug_vprintf(int, const char *, va_list); +extern void debug_pretrigger_setup(const uschar *); +extern void debug_pretrigger_discard(void); extern void debug_print_socket(int); +extern void debug_trigger_fire(void); extern void decode_bits(unsigned int *, size_t, int *, uschar *, bit_table *, int, uschar *, int); @@ -234,7 +239,7 @@ extern BOOL dscp_lookup(const uschar *, int, int *, int *, int *); extern void enq_end(uschar *); extern BOOL enq_start(uschar *, unsigned); #ifndef DISABLE_EVENT -extern uschar *event_raise(uschar *, const uschar *, uschar *); +extern uschar *event_raise(uschar *, const uschar *, uschar *, int *); extern void msg_event_raise(const uschar *, const address_item *); #endif @@ -262,7 +267,7 @@ extern void modify_variable(uschar *, void *); extern BOOL fd_ready(int, time_t); -extern int filter_interpret(uschar *, int, address_item **, uschar **); +extern int filter_interpret(const uschar *, int, address_item **, uschar **); extern BOOL filter_personal(string_item *, BOOL); extern BOOL filter_runtest(int, uschar *, BOOL, BOOL); extern BOOL filter_system_interpret(address_item **, uschar **); @@ -316,8 +321,7 @@ extern int ip_streamsocket(const uschar *, uschar **, int, host_item *); extern int ipv6_nmtoa(int *, uschar *); extern uschar *local_part_quote(uschar *); -extern int log_create(uschar *); -extern int log_create_as_exim(uschar *); +extern int log_open_as_exim(uschar * const); extern void log_close_all(void); extern macro_item * macro_create(const uschar *, const uschar *, BOOL); @@ -371,16 +375,19 @@ extern FILE *modefopen(const uschar *, const char *, mode_t); extern int open_cutthrough_connection( address_item * addr ); -extern uschar *parse_extract_address(uschar *, uschar **, int *, int *, int *, +extern uschar *parse_extract_address(const uschar *, uschar **, int *, int *, int *, BOOL); -extern int parse_forward_list(uschar *, int, address_item **, uschar **, +extern int parse_forward_list(const uschar *, int, address_item **, uschar **, const uschar *, uschar *, error_block **); -extern uschar *parse_find_address_end(uschar *, BOOL); -extern uschar *parse_find_at(uschar *); +extern uschar *parse_find_address_end(const uschar *, BOOL); +extern const uschar *parse_find_at(const uschar *); extern const uschar *parse_fix_phrase(const uschar *, int); -extern uschar *parse_message_id(uschar *, uschar **, uschar **); -extern const uschar *parse_quote_2047(const uschar *, int, uschar *, BOOL); -extern uschar *parse_date_time(uschar *str, time_t *t); +extern const uschar *parse_message_id(const uschar *, uschar **, uschar **); +extern const uschar *parse_quote_2047(const uschar *, int, const uschar *, + BOOL); +extern const uschar *parse_date_time(const uschar *str, time_t *t); +extern void priv_drop_temp(const uid_t, const gid_t); +extern void priv_restore(void); extern int vaguely_random_number(int); #ifndef DISABLE_TLS extern int vaguely_random_number_fallback(int); @@ -408,7 +415,7 @@ extern void readconf_driver_init(uschar *, driver_instance **, extern uschar *readconf_find_option(void *); extern void readconf_main(BOOL); extern void readconf_options_from_list(optionlist *, unsigned, const uschar *, uschar *); -extern BOOL readconf_print(uschar *, uschar *, BOOL); +extern BOOL readconf_print(const uschar *, uschar *, BOOL); extern uschar *readconf_printtime(int); extern uschar *readconf_readname(uschar *, int, uschar *); extern int readconf_readtime(const uschar *, int, BOOL); @@ -425,8 +432,9 @@ extern void receive_swallow_smtp(void); #ifdef WITH_CONTENT_SCAN extern int regex(const uschar **); #endif -extern BOOL regex_match_and_setup(const pcre *, const uschar *, int, int); -extern const pcre *regex_must_compile(const uschar *, BOOL, BOOL); +extern BOOL regex_match(const pcre2_code *, const uschar *, int, uschar **); +extern BOOL regex_match_and_setup(const pcre2_code *, const uschar *, int, int); +extern const pcre2_code *regex_must_compile(const uschar *, BOOL, BOOL); extern void retry_add_item(address_item *, uschar *, int); extern BOOL retry_check_address(const uschar *, host_item *, uschar *, BOOL, uschar **, uschar **); @@ -434,16 +442,16 @@ extern retry_config *retry_find_config(const uschar *, const uschar *, int, int) extern BOOL retry_ultimate_address_timeout(uschar *, const uschar *, dbdata_retry *, time_t); extern void retry_update(address_item **, address_item **, address_item **); -extern uschar *rewrite_address(uschar *, BOOL, BOOL, rewrite_rule *, int); -extern uschar *rewrite_address_qualify(uschar *, BOOL); +extern const uschar *rewrite_address(const uschar *, BOOL, BOOL, rewrite_rule *, int); +extern const uschar *rewrite_address_qualify(const uschar *, BOOL); extern header_line *rewrite_header(header_line *, const uschar *, const uschar *, rewrite_rule *, int, BOOL); -extern uschar *rewrite_one(uschar *, int, BOOL *, BOOL, uschar *, +extern const uschar *rewrite_one(const uschar *, int, BOOL *, BOOL, uschar *, rewrite_rule *); -extern void rewrite_test(uschar *); -extern uschar *rfc2047_decode2(uschar *, BOOL, uschar *, int, int *, int *, - uschar **); +extern void rewrite_test(const uschar *); +extern uschar *rfc2047_decode2(uschar *, BOOL, const uschar *, int, int *, + int *, uschar **); extern int route_address(address_item *, address_item **, address_item **, address_item **, address_item **, int); extern int route_check_prefix(const uschar *, const uschar *, unsigned *); @@ -470,10 +478,9 @@ extern void set_process_info(const char *, ...) PRINTF_FUNCTION(1,2); extern void sha1_end(hctx *, const uschar *, int, uschar *); extern void sha1_mid(hctx *, const uschar *); extern void sha1_start(hctx *); -extern int sieve_interpret(uschar *, int, uschar *, uschar *, uschar *, +extern int sieve_interpret(const uschar *, int, uschar *, uschar *, uschar *, uschar *, address_item **, uschar **); extern void sigalrm_handler(int); -extern BOOL smtp_buffered(void); extern void smtp_closedown(uschar *); extern void smtp_command_timeout_exit(void) NORETURN; extern void smtp_command_sigterm_exit(void) NORETURN; @@ -492,7 +499,8 @@ extern BOOL smtp_get_interface(uschar *, int, address_item *, extern BOOL smtp_get_port(uschar *, address_item *, int *, uschar *); extern int smtp_getc(unsigned); extern uschar *smtp_getbuf(unsigned *); -extern void smtp_get_cache(void); +extern void smtp_get_cache(unsigned); +extern BOOL smtp_hasc(void); extern int smtp_handle_acl_fail(int, int, uschar *, uschar *); extern void smtp_log_no_mail(void); extern void smtp_message_code(uschar **, int *, uschar **, uschar **, BOOL); @@ -522,10 +530,12 @@ extern int spool_write_header(uschar *, int, uschar **); extern int stdin_getc(unsigned); extern int stdin_feof(void); extern int stdin_ferror(void); +extern BOOL stdin_hasc(void); extern int stdin_ungetc(int); extern void store_exit(void); extern void store_init(void); +extern void store_writeprotect(int); extern gstring *string_append(gstring *, int, ...) WARN_UNUSED_RESULT; extern gstring *string_append_listele(gstring *, uschar, const uschar *) WARN_UNUSED_RESULT; @@ -579,6 +589,7 @@ extern uschar *string_nextinlist_trc(const uschar **listptr, int *separator, usc extern int strcmpic(const uschar *, const uschar *); extern int strncmpic(const uschar *, const uschar *, int); extern uschar *strstric(uschar *, uschar *, BOOL); +extern const uschar *strstric_c(const uschar *, const uschar *, BOOL); extern int test_harness_fudged_queue_time(int); extern void tcp_init(void); @@ -593,8 +604,11 @@ extern BOOL transport_check_waiting(const uschar *, const uschar *, int, usch extern void transport_init(void); extern void transport_do_pass_socket(const uschar *, const uschar *, const uschar *, uschar *, int); -extern BOOL transport_pass_socket(const uschar *, const uschar *, const uschar *, uschar *, - int); +extern BOOL transport_pass_socket(const uschar *, const uschar *, const uschar *, uschar *, int +#ifdef EXPERIMENTAL_ESMTP_LIMITS + , unsigned, unsigned, unsigned +#endif + ); extern uschar *transport_rcpt_address(address_item *, BOOL); extern BOOL transport_set_up_command(const uschar ***, uschar *, BOOL, int, address_item *, uschar *, uschar **); @@ -606,9 +620,9 @@ extern BOOL transport_headers_send(transport_ctx *, BOOL (*)(transport_ctx *, uschar *, int)); extern gstring * transport_show_supported(gstring *); extern BOOL transport_write_message(transport_ctx *, int); -extern void tree_add_duplicate(uschar *, address_item *); -extern void tree_add_nonrecipient(uschar *); -extern void tree_add_unusable(host_item *); +extern void tree_add_duplicate(const uschar *, address_item *); +extern void tree_add_nonrecipient(const uschar *); +extern void tree_add_unusable(const host_item *); extern void tree_dup(tree_node **, tree_node *); extern int tree_insertnode(tree_node **, tree_node *); extern tree_node *tree_search(tree_node *, const uschar *); @@ -619,7 +633,7 @@ extern void tree_walk(tree_node *, void (*)(uschar*, uschar*, void*), void *) extern void unspool_mbox(void); #endif #ifdef SUPPORT_I18N -extern void utf8_version_report(FILE *); +extern gstring *utf8_version_report(gstring *); #endif extern int verify_address(address_item *, FILE *, int, int, int, int, @@ -800,11 +814,11 @@ Returns: copy of string in new store, with letters lowercased */ static inline uschar * -string_copylc(const uschar *s) +string_copylc(const uschar * s) { -uschar *ss = store_get(Ustrlen(s) + 1, is_tainted(s)); -uschar *p = ss; -while (*s != 0) *p++ = tolower(*s++); +uschar * ss = store_get(Ustrlen(s) + 1, is_tainted(s)); +uschar * p = ss; +while (*s) *p++ = tolower(*s++); *p = 0; return ss; } @@ -826,7 +840,7 @@ Returns: copy of string in new store, with letters lowercased */ static inline uschar * -string_copynlc(uschar *s, int n) +string_copynlc(uschar * s, int n) { uschar *ss = store_get(n + 1, is_tainted(s)); uschar *p = ss; @@ -890,7 +904,7 @@ static inline gstring * string_get_tainted_trc(unsigned size, BOOL tainted, const char * func, unsigned line) { gstring * g = store_get_3(sizeof(gstring) + size, tainted, func, line); -g->size = size; +g->size = size; /*XXX would be good if we could see the actual alloc size */ g->ptr = 0; g->s = US(g + 1); return g; @@ -979,7 +993,6 @@ could be used and would handle that implicitly. */ static inline dns_answer * store_get_dns_answer_trc(const uschar * func, unsigned line) { -/* return store_get_3(sizeof(dns_answer), TRUE, CCS func, line); use tainted mem */ return store_malloc_3(sizeof(dns_answer), CCS func, line); } @@ -1121,20 +1134,50 @@ if (f.running_in_test_harness && f.testsuite_delays) millisleep(millisec); /******************************************************************************/ /* Taint-checked file opens */ +static inline uschar * +is_tainted2(const void *p, int lflags, const char* fmt, ...) +{ +va_list ap; +uschar *msg; +rmark mark; + +if (!is_tainted(p)) + return NULL; + +mark = store_mark(); +va_start(ap, fmt); +msg = string_from_gstring(string_vformat(NULL, SVFMT_TAINT_NOCHK|SVFMT_EXTEND, fmt, ap)); +va_end(ap); + +#ifdef ALLOW_INSECURE_TAINTED_DATA +if (allow_insecure_tainted_data) + { + if LOGGING(tainted) log_write(0, LOG_MAIN, "Warning: %s", msg); + store_reset(mark); + return NULL; + } +#endif + +if (lflags) log_write(0, lflags, "%s", msg); +return msg; /* no store_reset(), as the message might be used afterwards and Exim + is expected to exit anyway, so we do not care about the leaked + storage */ +} static inline int exim_open2(const char *pathname, int flags) { -if (!is_tainted(pathname)) return open(pathname, flags); -log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return open(pathname, flags); errno = EACCES; return -1; } + static inline int exim_open(const char *pathname, int flags, mode_t mode) { -if (!is_tainted(pathname)) return open(pathname, flags, mode); -log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return open(pathname, flags, mode); errno = EACCES; return -1; } @@ -1142,16 +1185,16 @@ return -1; static inline int exim_openat(int dirfd, const char *pathname, int flags) { -if (!is_tainted(pathname)) return openat(dirfd, pathname, flags); -log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return openat(dirfd, pathname, flags); errno = EACCES; return -1; } static inline int exim_openat4(int dirfd, const char *pathname, int flags, mode_t mode) { -if (!is_tainted(pathname)) return openat(dirfd, pathname, flags, mode); -log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return openat(dirfd, pathname, flags, mode); errno = EACCES; return -1; } @@ -1160,8 +1203,8 @@ return -1; static inline FILE * exim_fopen(const char *pathname, const char *mode) { -if (!is_tainted(pathname)) return fopen(pathname, mode); -log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return fopen(pathname, mode); errno = EACCES; return NULL; } @@ -1169,8 +1212,8 @@ return NULL; static inline DIR * exim_opendir(const uschar * name) { -if (!is_tainted(name)) return opendir(CCS name); -log_write(0, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name); +if (!is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name)) + return opendir(CCS name); errno = EACCES; return NULL; } @@ -1214,6 +1257,14 @@ child_open(uschar **argv, uschar **envp, int newumask, int *infdptr, outfdptr, make_leader, purpose); } +/* Return 1 if fd is usable per pollbits, else 0 */ +static inline int +poll_one_fd(int fd, short pollbits, int tmo_millisec) +{ +struct pollfd p = {.fd = fd, .events = pollbits}; +return poll(&p, 1, tmo_millisec); +} + # endif /* !COMPILE_UTILITY */ /******************************************************************************/