extern void tls_close(void *, int);
extern BOOL tls_could_read(void);
extern void tls_daemon_init(void);
+extern BOOL tls_dropprivs_validate_require_cipher(BOOL);
extern BOOL tls_export_cert(uschar *, size_t, void *);
extern int tls_feof(void);
extern int tls_ferror(void);
#endif
extern uschar *b64encode(const uschar *, int);
+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 void debug_vprintf(int, const char *, va_list);
extern void decode_bits(unsigned int *, size_t, int *,
uschar *, bit_table *, int, uschar *, int);
+extern void delete_pid_file(void);
extern address_item *deliver_make_addr(uschar *, BOOL);
-extern void deliver_init(void);
extern void delivery_log(int, address_item *, int, uschar *);
extern int deliver_message(uschar *, BOOL, BOOL);
extern void deliver_msglog(const char *, ...) PRINTF_FUNCTION(1,2);
#endif
extern dns_address *dns_address_from_rr(dns_answer *, dns_record *);
extern int dns_basic_lookup(dns_answer *, const uschar *, int);
-extern void dns_build_reverse(const uschar *, uschar *);
-extern time_t dns_expire_from_soa(dns_answer *);
+extern uschar *dns_build_reverse(const uschar *);
+extern time_t dns_expire_from_soa(dns_answer *, int);
extern void dns_init(BOOL, BOOL, BOOL);
extern BOOL dns_is_aa(const dns_answer *);
extern BOOL dns_is_secure(const dns_answer *);
extern void smtp_command_sigterm_exit(void) NORETURN;
extern void smtp_data_timeout_exit(void) NORETURN;
extern void smtp_data_sigint_exit(void) NORETURN;
+extern void smtp_deliver_init(void);
extern uschar *smtp_cmd_hist(void);
extern int smtp_connect(smtp_connect_args *, const blob *);
extern int smtp_sock_connect(host_item *, int, int, uschar *,
extern int strncmpic(const uschar *, const uschar *, int);
extern uschar *strstric(uschar *, uschar *, BOOL);
+extern int test_harness_fudged_queue_time(int);
+extern void tcp_init(void);
#ifdef EXIM_TFO_PROBE
extern void tfo_probe(void);
#endif
# endif
static inline uschar *
-spool_sname(const uschar * purpose, uschar * subdir)
+spool_q_sname(const uschar * purpose, const uschar * q, uschar * subdir)
{
return string_sprintf("%s%s%s%s%s",
- queue_name, *queue_name ? "/" : "",
+ q, *q ? "/" : "",
purpose,
*subdir ? "/" : "", subdir);
}
static inline uschar *
-spool_fname(const uschar * purpose, const uschar * subdir, const uschar * fname,
- const uschar * suffix)
+spool_sname(const uschar * purpose, uschar * subdir)
+{
+return spool_q_sname(purpose, queue_name, subdir);
+}
+
+static inline uschar *
+spool_q_fname(const uschar * purpose, const uschar * q,
+ const uschar * subdir, const uschar * fname, const uschar * suffix)
{
return string_sprintf("%s/%s/%s/%s/%s%s",
+ spool_directory, q, purpose, subdir, fname, suffix);
+}
+
+static inline uschar *
+spool_fname(const uschar * purpose, const uschar * subdir, const uschar * fname,
+ const uschar * suffix)
+{
+#ifdef COMPILE_UTILITY /* version avoiding string-extension */
+int len = Ustrlen(spool_directory) + 1 + Ustrlen(queue_name) + 1 + Ustrlen(purpose) + 1
+ + Ustrlen(subdir) + 1 + Ustrlen(fname) + Ustrlen(suffix) + 1;
+uschar * buf = store_get(len, FALSE);
+string_format(buf, len, "%s/%s/%s/%s/%s%s",
spool_directory, queue_name, purpose, subdir, fname, suffix);
+return buf;
+#else
+return spool_q_fname(purpose, queue_name, subdir, fname, suffix);
+#endif
}
static inline void
}
/******************************************************************************/
+/* Time calculations */
+
static inline void
-timesince(struct timeval * diff, struct timeval * then)
+timesince(struct timeval * diff, const struct timeval * then)
{
gettimeofday(diff, NULL);
diff->tv_sec -= then->tv_sec;
}
static inline uschar *
-string_timediff(struct timeval * diff)
+string_timediff(const struct timeval * diff)
{
static uschar buf[sizeof("0.000s")];
if (diff->tv_sec >= 5 || !LOGGING(millisec))
return readconf_printtime((int)diff->tv_sec);
-sprintf(CS buf, "%u.%03us", (uint)diff->tv_sec, (uint)diff->tv_usec/1000);
+snprintf(CS buf, sizeof(buf), "%u.%03us", (uint)diff->tv_sec, (uint)diff->tv_usec/1000);
return buf;
}
static inline uschar *
-string_timesince(struct timeval * then)
+string_timesince(const struct timeval * then)
{
struct timeval diff;
timesince(&diff, then);
}
static inline void
-report_time_since(struct timeval * t0, uschar * where)
+report_time_since(const struct timeval * t0, const uschar * where)
{
# ifdef MEASURE_TIMING
struct timeval diff;
#endif
}
+/******************************************************************************/
+/* Taint-checked file opens */
+
+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);
+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);
+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);
+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);
+errno = EACCES;
+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);
+errno = EACCES;
+return NULL;
+}
+
#endif /* !MACRO_PREDEF */
#endif /* _FUNCTIONS_H_ */