Avoid calling gettimeofday(), select() per char for cmdline message submission. ...
[exim.git] / src / src / functions.h
index 4212c3328a113f342cc5f1090d03e8641f5a1c4c..401300d94453e92265afbd2a949ec7c639fe3e9c 100644 (file)
@@ -58,7 +58,7 @@ extern void    tls_client_creds_reload(BOOL);
 extern void    tls_close(void *, int);
 extern BOOL    tls_could_read(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
@@ -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);
 
@@ -372,13 +374,14 @@ extern int     open_cutthrough_connection( address_item * addr );
 
 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_address_end(const uschar *, BOOL);
 extern const uschar *parse_find_at(const uschar *);
 extern const uschar *parse_fix_phrase(const uschar *, int);
 extern const uschar *parse_message_id(const uschar *, uschar **, uschar **);
-extern const uschar *parse_quote_2047(const uschar *, int, uschar *, BOOL);
+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);
@@ -426,8 +429,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 **);
@@ -443,8 +447,8 @@ extern header_line *rewrite_header(header_line *,
 extern const uschar *rewrite_one(const uschar *, int, BOOL *, BOOL, uschar *,
                  rewrite_rule *);
 extern void    rewrite_test(const uschar *);
-extern uschar *rfc2047_decode2(uschar *, BOOL, uschar *, int, int *, int *,
-                 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 *);
@@ -493,7 +497,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);
@@ -523,10 +528,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;
@@ -1125,20 +1132,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;
 }
@@ -1146,16 +1183,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;
 }
@@ -1164,8 +1201,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;
 }
@@ -1173,8 +1210,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;
 }