File: postfix-dnssec.patch

package info (click to toggle)
dnssec-tools 1.13-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 16,064 kB
  • sloc: perl: 44,399; ansic: 31,547; cpp: 21,306; sh: 15,813; xml: 2,113; makefile: 1,390; pascal: 836; python: 290; csh: 11
file content (289 lines) | stat: -rw-r--r-- 10,941 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
diff -ur postfix-2.7-20091115.clean/makedefs postfix-2.7-20091115/makedefs
--- postfix-2.7-20091115.clean/makedefs	2009-11-09 19:44:41.000000000 -0500
+++ postfix-2.7-20091115/makedefs	2009-11-18 14:19:01.000000000 -0500
@@ -282,9 +282,9 @@
 		#     GDBM_LIBS=gdbm
 		# fi
 		SYSLIBS="-ldb"
-		for name in nsl resolv $GDBM_LIBS
+		for name in nsl resolv val-threads sres crypto $GDBM_LIBS
 		do
-		    for lib in /usr/lib64 /lib64 /usr/lib /lib
+		    for lib in /usr/lib64 /lib64 /usr/lib /lib /usr/local/lib
 		    do
 			test -e $lib/lib$name.a -o -e $lib/lib$name.so && {
 			    SYSLIBS="$SYSLIBS -l$name"
diff -ur postfix-2.7-20091115.clean/src/dns/dns.h postfix-2.7-20091115/src/dns/dns.h
--- postfix-2.7-20091115.clean/src/dns/dns.h	2008-11-09 16:42:03.000000000 -0500
+++ postfix-2.7-20091115/src/dns/dns.h	2009-11-18 14:19:01.000000000 -0500
@@ -171,6 +171,8 @@
   * Status codes. Failures must have negative codes so they will not collide
   * with valid counts of answer records etc.
   */
+                                        /* DNS_INSECURE dnssec patch added */
+#define DNS_INSECURE	(-6)		/* query was not validated */
 #define DNS_INVAL	(-5)		/* query ok, malformed reply */
 #define DNS_FAIL	(-4)		/* query failed, don't retry */
 #define DNS_NOTFOUND	(-3)		/* query ok, data not found */
diff -ur postfix-2.7-20091115.clean/src/dns/dns_lookup.c postfix-2.7-20091115/src/dns/dns_lookup.c
--- postfix-2.7-20091115.clean/src/dns/dns_lookup.c	2009-08-06 15:25:33.000000000 -0400
+++ postfix-2.7-20091115/src/dns/dns_lookup.c	2009-11-18 14:19:01.000000000 -0500
@@ -146,6 +146,7 @@
 #include <msg.h>
 #include <valid_hostname.h>
 #include <stringops.h>
+#include <validator/validator.h>
 
 /* DNS library. */
 
@@ -215,7 +216,15 @@
     for (;;) {
 	_res.options &= ~saved_options;
 	_res.options |= flags;
-	len = res_search((char *) name, C_IN, type, reply->buf, reply->buf_len);
+
+        /* dns query using dnssec validator library */
+        val_status_t val_status;
+        len = val_res_query((val_context_t *) NULL,
+                            (char *) name, 
+                            C_IN, type, 
+                            reply->buf, reply->buf_len,
+                            &val_status);
+
 	_res.options &= ~flags;
 	_res.options |= saved_options;
 	if (len < 0) {
@@ -236,8 +245,22 @@
 		return (DNS_RETRY);
 	    }
 	}
-	if (msg_verbose)
-	    msg_info("dns_query: %s (%s): OK", name, dns_strtype(type));
+
+        /* check that the dnssec query is trusted */
+        if (!val_istrusted(val_status)) {
+            if (why || msg_verbose)
+                vstring_sprintf(why, "Validation error during Name Service lookup."
+                                " Error %d : %s  for name=%s type=%s",
+                                val_status, p_val_error(val_status),
+                                name, dns_strtype(type));
+            
+            return(DNS_FAIL);
+        }
+ 
+        if (msg_verbose)
+            msg_info("dns_query: %s (%s): OK   validation: %s (%d)", 
+                     name, dns_strtype(type), 
+                     p_val_error(val_status), val_status);
 
 	reply_header = (HEADER *) reply->buf;
 	if (reply_header->tc == 0 || reply->buf_len >= MAX_DNS_REPLY_SIZE)
diff -ur postfix-2.7-20091115.clean/src/util/myaddrinfo.c postfix-2.7-20091115/src/util/myaddrinfo.c
--- postfix-2.7-20091115.clean/src/util/myaddrinfo.c	2006-09-29 19:34:20.000000000 -0400
+++ postfix-2.7-20091115/src/util/myaddrinfo.c	2009-11-23 13:44:24.216393943 -0500
@@ -427,7 +427,26 @@
 	}
 #endif
     }
-    err = getaddrinfo(hostname, service, &hints, res);
+
+    /* 
+     * Call dnssec aware getaddrinfo.  If it returns a regular
+     * getaddrinfo error, return with that error.
+     * If the return query is not trusted, return a
+     * dnssec failure condition. 
+     */
+    val_status_t  vstatus;
+    err = val_getaddrinfo((val_context_t *)NULL, hostname, 
+                          service, &hints, res, &vstatus);
+    if (VAL_GETADDRINFO_HAS_STATUS(err) &&  (0 == val_istrusted(vstatus)))  {
+        err = DNSSECAI_FAIL;
+        msg_warn("DNSSEC, hostname information not trusted for host, %s (status: %d:%s, dnssec status %d:%s, val_getaddrinfo)", 
+                 hostname ? hostname : "NULL", err, MAI_STRERROR(err), 
+                 vstatus, p_val_status(vstatus));
+    }
+    else if(err) {
+      msg_warn("failed to get host information for host, %s (status %d:%s, val_getaddrinfo)", 
+               hostname ? hostname : "NULL", err, MAI_STRERROR(err));
+    }
 #if defined(BROKEN_AI_NULL_SERVICE)
     if (service == 0 && err == 0) {
 	struct addrinfo *r;
@@ -543,7 +562,27 @@
 	}
 #endif
     }
-    err = getaddrinfo(hostaddr, service, &hints, res);
+
+    /* 
+     * Call dnssec aware getaddrinfo.  If it returns a regular
+     * getaddrinfo error, return with that error.
+     * If the return query is not trusted, return a 
+     * dnssec failure condition. 
+     */
+    val_status_t  vstatus;
+    err = val_getaddrinfo((val_context_t *)NULL, hostaddr, service, &hints, 
+                          res, &vstatus);
+    if (VAL_GETADDRINFO_HAS_STATUS(err) && (0 == val_istrusted(vstatus)))  {
+        err = DNSSECAI_FAIL;
+        msg_warn("DNSSEC, host address information not trusted for host, %s (status %d:%s, dnssec status %d:%s, val_getaddrinfo)",
+                 hostaddr ? hostaddr : "NULL", err, MAI_STRERROR(err),
+                 vstatus, p_val_status(vstatus));
+    }
+    else {
+      msg_warn("failed to get host information for host, %s (status %d:%s, val_getaddrinfo)", 
+               hostaddr ? hostaddr : "NULL",
+               err, MAI_STRERROR(err));
+    }
 #if defined(BROKEN_AI_NULL_SERVICE)
     if (service == 0 && err == 0) {
 	struct addrinfo *r;
@@ -769,6 +808,29 @@
 
 #endif
 
+
+/* 
+ * dnssec_strerror - looks for dnssec errors (currently there is
+ *                   only one), passes back dnssec specific error
+ *                   string or calls the system gai_strerror. 
+ */
+
+static const char* dnssecai_fail_string = "DNSSEC Error";
+static const char* dnssecai_noerror_string = "DNSSEC Success";
+
+const char   *dnssec_strerror(int ecode)  
+{
+  switch (ecode) {
+  case 0:
+    return (dnssecai_noerror_string);
+  case DNSSECAI_FAIL:
+    return (dnssecai_fail_string);
+  }
+  /* default response*/
+  return (gai_strerror(ecode));
+} /* denssec_strerror */
+
+
 #ifdef TEST
 
  /*
@@ -797,46 +859,59 @@
     msg_info("=== hostname %s ===", argv[2]);
 
     if ((err = hostname_to_sockaddr(argv[2], (char *) 0, 0, &info)) != 0) {
-	msg_info("hostname_to_sockaddr(%s): %s",
-	  argv[2], err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+	msg_info("hostname_to_sockaddr(%s): Error: %s",
+                 argv[2], MAI_STRERROR(err));
     } else {
+	msg_info("hostname_to_sockaddr(%s): Success: %s",
+                 argv[2], MAI_STRERROR(err));
 	for (ip = info; ip != 0; ip = ip->ai_next) {
 	    if ((err = sockaddr_to_hostaddr(ip->ai_addr, ip->ai_addrlen, &addr,
 					 (MAI_SERVPORT_STR *) 0, 0)) != 0) {
-		msg_info("sockaddr_to_hostaddr: %s",
-		   err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+		msg_info("sockaddr_to_hostaddr: Error: %s",
+		   MAI_STRERROR(err));
 		continue;
 	    }
+            else {
+              msg_info("sockaddr_to_hostaddr: Success: %s",
+                       MAI_STRERROR(err));
+            }
 	    msg_info("%s -> family=%d sock=%d proto=%d %s", argv[2],
 		 ip->ai_family, ip->ai_socktype, ip->ai_protocol, addr.buf);
 	    if ((err = sockaddr_to_hostname(ip->ai_addr, ip->ai_addrlen, &host,
 					 (MAI_SERVNAME_STR *) 0, 0)) != 0) {
-		msg_info("sockaddr_to_hostname: %s",
-		   err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+		msg_info("sockaddr_to_hostname: Error: %s",
+		   MAI_STRERROR(err));
 		continue;
 	    }
+            else {
+              msg_info("sockaddr_to_hostname: Success: %s",
+                       MAI_STRERROR(err));
+            }
 	    msg_info("%s -> %s", addr.buf, host.buf);
 	}
 	freeaddrinfo(info);
     }
 
+    msg_info(" ");
     msg_info("=== host address %s ===", argv[3]);
 
     if ((err = hostaddr_to_sockaddr(argv[3], (char *) 0, 0, &ip)) != 0) {
-	msg_info("hostaddr_to_sockaddr(%s): %s",
-	  argv[3], err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+	msg_info("hostaddr_to_sockaddr(%s): Error: %s",
+	  argv[3], MAI_STRERROR(err));
     } else {
+	msg_info("hostaddr_to_sockaddr(%s): Success: %s",
+                 argv[3], MAI_STRERROR(err));
 	if ((err = sockaddr_to_hostaddr(ip->ai_addr, ip->ai_addrlen, &addr,
 					(MAI_SERVPORT_STR *) 0, 0)) != 0) {
-	    msg_info("sockaddr_to_hostaddr: %s",
-		   err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+	    msg_info("sockaddr_to_hostaddr: Error: %s",
+		   MAI_STRERROR(err));
 	} else {
 	    msg_info("%s -> family=%d sock=%d proto=%d %s", argv[3],
 		 ip->ai_family, ip->ai_socktype, ip->ai_protocol, addr.buf);
 	    if ((err = sockaddr_to_hostname(ip->ai_addr, ip->ai_addrlen, &host,
 					 (MAI_SERVNAME_STR *) 0, 0)) != 0) {
 		msg_info("sockaddr_to_hostname: %s",
-		   err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
+		   MAI_STRERROR(err));
 	    } else
 		msg_info("%s -> %s", addr.buf, host.buf);
 	    freeaddrinfo(ip);
Only in postfix-2.7-20091115/src/util: myaddrinfo.e
diff -ur postfix-2.7-20091115.clean/src/util/myaddrinfo.h postfix-2.7-20091115/src/util/myaddrinfo.h
--- postfix-2.7-20091115.clean/src/util/myaddrinfo.h	2008-11-27 14:10:17.000000000 -0500
+++ postfix-2.7-20091115/src/util/myaddrinfo.h	2009-11-18 14:19:01.000000000 -0500
@@ -21,6 +21,7 @@
 #include <string.h>
 #include <errno.h>			/* MAI_STRERROR() */
 #include <limits.h>			/* CHAR_BIT */
+#include <validator/validator.h>
 
  /*
   * Backwards compatibility support for IPV4 systems without addrinfo API.
@@ -32,8 +33,6 @@
   * provides its own addrinfo() implementation. This also allows us to test
   * the IPV4 emulation code on an IPV6 enabled system.
   */
-#undef  freeaddrinfo
-#define freeaddrinfo	mai_freeaddrinfo
 #undef  gai_strerror
 #define gai_strerror	mai_strerror
 #undef  addrinfo
@@ -103,6 +102,16 @@
 
 #endif
 
+
+/* start dnssec patch additions */
+
+#define DNSSECAI_FAIL   -600  /* sharing number space with netdb.h errors */
+
+const char   *dnssec_strerror(int ecode);
+
+/* end dnssec patch additions (except for MAI_STRERROR below)*/
+
+
  /*
   * Bounds grow in leaps. These macros attempt to keep non-library code free
   * from IPV6 #ifdef pollution. Avoid macro names that end in STRLEN because
@@ -166,7 +175,8 @@
 
 #define MAI_CTL_END	0		/* list terminator */
 
-#define MAI_STRERROR(e) ((e) == EAI_SYSTEM ? strerror(errno) : gai_strerror(e))
+/* redefined by dnssec patch */
+#define MAI_STRERROR(e) ((e) == EAI_SYSTEM ? strerror(errno) : dnssec_strerror(e))
 
  /*
   * Macros for the case where we really don't want to be bothered with things