Prereq: "3.4.8"
diff -ur --new-file /var/tmp/postfix-3.4.8/src/global/mail_version.h ./src/global/mail_version.h
--- /var/tmp/postfix-3.4.8/src/global/mail_version.h	2019-11-24 15:40:32.000000000 -0500
+++ ./src/global/mail_version.h	2020-02-02 15:13:52.000000000 -0500
@@ -20,8 +20,8 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE	"20191124"
-#define MAIL_VERSION_NUMBER	"3.4.8"
+#define MAIL_RELEASE_DATE	"20200203"
+#define MAIL_VERSION_NUMBER	"3.4.9"
 
 #ifdef SNAPSHOT
 #define MAIL_VERSION_DATE	"-" MAIL_RELEASE_DATE
diff -ur --new-file /var/tmp/postfix-3.4.8/HISTORY ./HISTORY
--- /var/tmp/postfix-3.4.8/HISTORY	2019-11-11 18:01:20.000000000 -0500
+++ ./HISTORY	2020-02-02 12:51:46.000000000 -0500
@@ -24319,3 +24319,23 @@
 	now, the parser skips object types that it does not know
 	about for usability, and logs a warning because ignoring
 	inputs is not kosher. Viktor and Wietse. File: tls/tls_certkey.c.
+
+20191214
+
+	Bugfix (introduced: Postfix 3.1): support for
+	smtp_dns_resolver_options was broken while adding support
+	for negative DNS response caching in postscreen. Postfix
+	was inadvertently changed to call res_query() instead of
+	res_search(). Reported by Jaroslav Skarvada. File:
+	dns/dns_lookup.c.
+
+	Bugfix (introduced: Postfix 3.0): sanitize server responses
+	before storing them in the verify database, to avoid Postfix
+	warnings about malformed UTF8. File: verify/verify.c.
+
+20200115
+
+	Bugfix (introduced: Postfix 2.5): the Milter connect event
+	macros were evaluated before the Milter connection itself
+	had been negotiated. Problem reported by David B��rgin.
+	Files: milter/milter.h, milter/milter.c, milter/milter8.c
diff -ur --new-file /var/tmp/postfix-3.4.8/src/dns/dns_lookup.c ./src/dns/dns_lookup.c
--- /var/tmp/postfix-3.4.8/src/dns/dns_lookup.c	2017-12-20 20:48:39.000000000 -0500
+++ ./src/dns/dns_lookup.c	2019-12-15 11:13:04.000000000 -0500
@@ -396,7 +396,7 @@
     if (keep_notfound)
 	/* Prepare for returning a null-padded server reply. */
 	memset(answer, 0, anslen);
-    len = res_query(name, class, type, answer, anslen);
+    len = res_search(name, class, type, answer, anslen);
     /* Begin API creep workaround. */
     if (len < 0 && h_errno == 0) {
 	SET_H_ERRNO(TRY_AGAIN);
diff -ur --new-file /var/tmp/postfix-3.4.8/src/milter/milter.c ./src/milter/milter.c
--- /var/tmp/postfix-3.4.8/src/milter/milter.c	2017-02-21 17:32:57.000000000 -0500
+++ ./src/milter/milter.c	2020-02-02 12:37:46.000000000 -0500
@@ -417,6 +417,8 @@
     if (msg_verbose)
 	msg_info("report connect to all milters");
     for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
+	if (m->connect_on_demand != 0)
+	    m->connect_on_demand(m);
 	any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, conn_macros);
 	resp = m->conn_event(m, client_name, client_addr, client_port,
 			     addr_family, any_macros);
diff -ur --new-file /var/tmp/postfix-3.4.8/src/milter/milter.h ./src/milter/milter.h
--- /var/tmp/postfix-3.4.8/src/milter/milter.h	2016-06-11 18:17:03.000000000 -0400
+++ ./src/milter/milter.h	2020-02-02 12:37:46.000000000 -0500
@@ -35,6 +35,7 @@
     struct MILTER *next;		/* linkage */
     struct MILTERS *parent;		/* parent information */
     struct MILTER_MACROS *macros;	/* private macros */
+    void    (*connect_on_demand) (struct MILTER *);
     const char *(*conn_event) (struct MILTER *, const char *, const char *, const char *, unsigned, ARGV *);
     const char *(*helo_event) (struct MILTER *, const char *, int, ARGV *);
     const char *(*mail_event) (struct MILTER *, const char **, ARGV *);
diff -ur --new-file /var/tmp/postfix-3.4.8/src/milter/milter8.c ./src/milter/milter8.c
--- /var/tmp/postfix-3.4.8/src/milter/milter8.c	2018-11-27 19:30:23.000000000 -0500
+++ ./src/milter/milter8.c	2020-02-02 12:37:46.000000000 -0500
@@ -1918,15 +1918,6 @@
 #define STR_NE(x,y)	(strcmp((x), (y)) != 0)
 
     /*
-     * XXX Sendmail 8 libmilter closes the MTA-to-filter socket when it finds
-     * out that the SMTP client has disconnected. Because of this, Postfix
-     * has to open a new MTA-to-filter socket for each SMTP client.
-     */
-#ifdef LIBMILTER_AUTO_DISCONNECT
-    milter8_connect(milter);
-#endif
-
-    /*
      * Report the event.
      */
     switch (milter->state) {
@@ -2835,6 +2826,10 @@
 
     /*
      * Fill in the structure. Note: all strings must be copied.
+     * 
+     * XXX Sendmail 8 libmilter closes the MTA-to-filter socket when it finds
+     * out that the SMTP client has disconnected. Because of this, Postfix
+     * has to open a new MTA-to-filter socket for each SMTP client.
      */
     milter = (MILTER8 *) mymalloc(sizeof(*milter));
     milter->m.name = mystrdup(name);
@@ -2842,6 +2837,11 @@
     milter->m.next = 0;
     milter->m.parent = parent;
     milter->m.macros = 0;
+#ifdef LIBMILTER_AUTO_DISCONNECT
+    milter->m.connect_on_demand = (void (*) (struct MILTER *)) milter8_connect;
+#else
+    milter->m.connect_on_demand = 0;
+#endif
     milter->m.conn_event = milter8_conn_event;
     milter->m.helo_event = milter8_helo_event;
     milter->m.mail_event = milter8_mail_event;
diff -ur --new-file /var/tmp/postfix-3.4.8/src/verify/verify.c ./src/verify/verify.c
--- /var/tmp/postfix-3.4.8/src/verify/verify.c	2019-02-03 14:17:14.000000000 -0500
+++ ./src/verify/verify.c	2019-12-14 20:16:04.000000000 -0500
@@ -401,6 +401,7 @@
 		|| STATUS_FROM_RAW_ENTRY(raw_data) != DEL_RCPT_STAT_OK) {
 		probed = 0;
 		updated = (long) time((time_t *) 0);
+		printable(STR(text), '?');
 		verify_make_entry(buf, addr_status, probed, updated, STR(text));
 		if (msg_verbose)
 		    msg_info("PUT %s status=%d probed=%ld updated=%ld text=%s",