X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/35c3c48545d5bb1d98a0c4986dded979d2abe08a..ec06d64532e4952fc36429f73e0222d26997ef7c:/src/src/functions.h?ds=sidebyside diff --git a/src/src/functions.h b/src/src/functions.h index 2e5b1e47d..1e8083673 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -3,6 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 1995 - 2018 */ +/* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -13,6 +14,7 @@ are in in fact in separate headers. */ #ifndef _FUNCTIONS_H_ #define _FUNCTIONS_H_ +#include #include @@ -118,7 +120,7 @@ extern int auth_get_data(uschar **, const uschar *, int); extern int auth_get_no64_data(uschar **, uschar *); extern int auth_prompt(const uschar *); extern int auth_read_input(const uschar *); -extern void auth_show_supported(FILE *); +extern gstring * auth_show_supported(gstring *); extern uschar *auth_xtextencode(uschar *, int); extern int auth_xtextdecode(uschar *, uschar **); @@ -148,6 +150,8 @@ extern void bits_clear(unsigned int *, size_t, int *); extern void bits_set(unsigned int *, size_t, int *); extern void cancel_cutthrough_connection(BOOL, const uschar *); +extern gstring *cat_file(FILE *, gstring *, uschar *); +extern gstring *cat_file_tls(void *, gstring *, uschar *); extern int check_host(void *, const uschar *, const uschar **, uschar **); extern uschar **child_exec_exim(int, BOOL, int *, BOOL, int, ...); extern pid_t child_open_exim_function(int *, const uschar *); @@ -180,6 +184,8 @@ extern void debug_printf_indent(const char *, ...) PRINTF_FUNCTION(1,2); extern void debug_print_string(uschar *); extern void debug_print_tree(tree_node *); extern void debug_vprintf(int, const char *, va_list); +extern void debug_print_socket(int); + extern void decode_bits(unsigned int *, size_t, int *, uschar *, bit_table *, int, uschar *, int); extern void delete_pid_file(void); @@ -228,6 +234,7 @@ extern void msg_event_raise(const uschar *, const address_item *); extern int exim_chown_failure(int, const uschar*, uid_t, gid_t); extern const uschar * exim_errstr(int); extern void exim_exit(int) NORETURN; +extern void exim_gettime(struct timeval *); extern void exim_nullstd(void); extern void exim_setugid(uid_t, gid_t, BOOL, uschar *); extern void exim_underbar_exit(int) NORETURN; @@ -239,6 +246,8 @@ extern BOOL expand_check_condition(uschar *, uschar *, uschar *); extern uschar *expand_file_big_buffer(const uschar *); extern uschar *expand_string(uschar *); /* public, cannot make const */ extern const uschar *expand_cstring(const uschar *); /* ... so use this one */ +extern uschar *expand_getkeyed(const uschar *, const uschar *); + extern uschar *expand_hide_passwords(uschar * ); extern uschar *expand_string_copy(const uschar *); extern int_eximarith_t expand_string_integer(uschar *, BOOL); @@ -311,7 +320,7 @@ extern void mainlog_close(void); extern int malware(const uschar *, int); extern int malware_in_file(uschar *); extern void malware_init(void); -extern void malware_show_supported(FILE *); +extern gstring * malware_show_supported(gstring *); #endif extern int match_address_list(const uschar *, BOOL, BOOL, const uschar **, unsigned int *, int, int, const uschar **); @@ -357,9 +366,9 @@ extern int parse_forward_list(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 const uschar *parse_fix_phrase(const uschar *, int, uschar *, int); +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 *, uschar *, int, BOOL); +extern const uschar *parse_quote_2047(const uschar *, int, uschar *, BOOL); extern uschar *parse_date_time(uschar *str, time_t *t); extern int vaguely_random_number(int); #ifndef DISABLE_TLS @@ -435,15 +444,15 @@ extern BOOL route_find_expanded_group(uschar *, uschar *, uschar *, gid_t *, extern BOOL route_find_expanded_user(uschar *, uschar *, uschar *, struct passwd **, uid_t *, uschar **); extern void route_init(void); -extern void route_show_supported(FILE *); +extern gstring * route_show_supported(gstring *); extern void route_tidyup(void); -extern uschar *search_find(void *, uschar *, uschar *, int, const uschar *, int, - int, int *); +extern uschar *search_find(void *, const uschar *, uschar *, int, + const uschar *, int, int, int *, const uschar *); extern int search_findtype(const uschar *, int); extern int search_findtype_partial(const uschar *, int *, const uschar **, int *, - int *); -extern void *search_open(uschar *, int, int, uid_t *, gid_t *); + int *, const uschar **); +extern void *search_open(const uschar *, int, int, uid_t *, gid_t *); extern void search_tidyup(void); extern void set_process_info(const char *, ...) PRINTF_FUNCTION(1,2); extern void sha1_end(hctx *, const uschar *, int, uschar *); @@ -520,8 +529,7 @@ extern int string_is_ip_address(const uschar *, int *); #ifdef SUPPORT_I18N extern BOOL string_is_utf8(const uschar *); #endif -extern uschar *string_nextinlist(const uschar **, int *, uschar *, int); -extern const uschar *string_printing2(const uschar *, BOOL); +extern const uschar *string_printing2(const uschar *, int); extern uschar *string_split_message(uschar *); extern uschar *string_unprinting(uschar *); #ifdef SUPPORT_I18N @@ -548,6 +556,11 @@ extern gstring *string_vformat_trc(gstring *, const uschar *, unsigned, extern uschar *string_open_failed_trc(int, const uschar *, unsigned, const char *, ...) PRINTF_FUNCTION(4,5); +#define string_nextinlist(lp, sp, b, l) \ + string_nextinlist_trc((lp), (sp), (b), (l), US __FUNCTION__, __LINE__) +extern uschar *string_nextinlist_trc(const uschar **listptr, int *separator, uschar *buffer, int buflen, + const uschar * func, int line); + extern int strcmpic(const uschar *, const uschar *); extern int strncmpic(const uschar *, const uschar *, int); extern uschar *strstric(uschar *, uschar *, BOOL); @@ -576,7 +589,7 @@ extern void transport_write_reset(int); extern BOOL transport_write_string(int, const char *, ...); extern BOOL transport_headers_send(transport_ctx *, BOOL (*)(transport_ctx *, uschar *, int)); -extern void transport_show_supported(FILE *); +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 *); @@ -666,6 +679,15 @@ return US strncpy(CS dst, CCS src, n); /*XXX will likely need unchecked copy also */ +/* Advance the string pointer given over any whitespace. +Return the next char as there's enought places using it to be useful. */ + +#define Uskip_whitespace(sp) skip_whitespace(CUSS sp) + +static inline uschar skip_whitespace(const uschar ** sp) +{ while (isspace(**sp)) (*sp)++; return **sp; } + + /******************************************************************************/ #if !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY) @@ -746,9 +768,9 @@ string_copy_trc(const uschar * s, const char * func, int line) /* Simple string-copy functions maintaining the taint */ #define string_copyn(s, len) \ - string_copyn_taint_trc((s), (len), is_tainted(s), __FUNCTION__, __LINE__) + string_copyn_trc((s), (len), __FUNCTION__, __LINE__) #define string_copy(s) \ - string_copy_taint_trc((s), is_tainted(s), __FUNCTION__, __LINE__) + string_copy_trc((s), __FUNCTION__, __LINE__) /************************************************* @@ -1061,36 +1083,66 @@ 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 uschar* 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'\n", 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'\n", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return open(pathname, flags, mode); errno = EACCES; 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'\n", 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'\n", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return openat(dirfd, pathname, flags, mode); errno = EACCES; return -1; } @@ -1098,8 +1150,17 @@ 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'\n", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return fopen(pathname, mode); +errno = EACCES; +return NULL; +} + +static inline DIR * +exim_opendir(const uschar * name) +{ +if (!is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name)) + return opendir(CCS name); errno = EACCES; return NULL; }