Commit e20dfceb authored by Timo Teräs's avatar Timo Teräs Committed by Timo Teräs

main/libspf2: fix local policy handling

parent 85955453
From abfd38dbff2be2e63ee222a87b4f24de5573e7eb Mon Sep 17 00:00:00 2001
From: Natanael Copa <natanael.copa@gmail.com>
Date: Mon, 19 Apr 2010 14:53:35 +0000
Subject: [PATCH] provide dn_skipname
---
configure.ac | 3 +-
src/libreplace/__dn_skipname.c | 87 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 1 deletions(-)
create mode 100644 src/libreplace/__dn_skipname.c
diff --git a/configure.ac b/configure.ac
index 310d73c..8a0dd2b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -272,7 +273,7 @@ AC_CHECK_FUNCS([strcasecmp strncasecmp strspn strtoul])
AC_CHECK_FUNCS([gethostbyname inet_ntoa select strrchr strstr strtol])
AC_REPLACE_FUNCS([getopt_long_only strncasecmp])
-AC_REPLACE_FUNCS([__ns_initparse __ns_name_uncompress __ns_get16 __ns_msg_getflag])
+AC_REPLACE_FUNCS([__ns_initparse __ns_name_uncompress __ns_get16 __ns_msg_getflag __dn_skipname])
AC_CONFIG_FILES([Makefile
Doxyfile
diff --git a/src/libreplace/__dn_skipname.c b/src/libreplace/__dn_skipname.c
new file mode 100644
index 0000000..88d48b5
--- /dev/null
+++ b/src/libreplace/__dn_skipname.c
@@ -0,0 +1,87 @@
+/* taken from OpenBSD source */
+/*
+ * ++Copyright++ 1985, 1993
+ * -
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/*
+ * Skip over a compressed domain name. Return the size or -1.
+ */
+#include <sys/types.h>
+#include <resolv.h>
+
+int
+__dn_skipname(const u_char *comp_dn, const u_char *eom)
+{
+ const u_char *cp;
+ int n;
+
+ cp = comp_dn;
+ while (cp < eom && (n = *cp++)) {
+ /*
+ * check for indirection
+ */
+ switch (n & INDIR_MASK) {
+ case 0: /* normal case, n == len */
+ cp += n;
+ continue;
+ case INDIR_MASK: /* indirection */
+ cp++;
+ break;
+ default: /* illegal type */
+ return (-1);
+ }
+ break;
+ }
+ if (cp > eom)
+ return (-1);
+ return (cp - comp_dn);
+}
+
+
--
1.7.0.4
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=libspf2
pkgver=1.2.9
pkgrel=0
pkgrel=7
pkgdesc="Sender Policy Framework library, a part of the SPF/SRS protocol pair."
url="http://www.libspf2.org"
arch="all"
license="LGPL-2.1 BSD-2"
subpackages="$pkgname-dev"
makedepends=
makedepends="autoconf automake libtool bind-dev"
depends=
source="http://www.libspf2.org/spf/libspf2-$pkgver.tar.gz
libspf2-localpolicy-fix.patch"
libspf2-localpolicy-fix.patch
0001-provide-dn_skipname.patch
libspf2-libreplace-fix.patch
libspf2-res_ninit-uclibc.patch
"
build() {
cd "$srcdir"/$pkgname-$pkgver
_builddir="$srcdir"/$pkgname-$pkgver
prepare() {
cd "$_builddir"
for i in ../*.patch; do
msg "Apply $i"
patch -p1 < $i || return 1
done
libtoolize --force && aclocal && automake && autoconf && autoheader
}
build() {
cd "$_builddir"
./configure --prefix=/usr \
|| return 1
# uclibc claims to have res_ninit() but it doesnt.
sed -i -e 's:HAVE_DECL_RES_NINIT 1:HAVE_DECL_RES_NINIT 0:' config.h
make || return 1
}
package() {
cd "$_builddir"
make DESTDIR="$pkgdir" install || return 1
rm "$pkgdir"/usr/lib/*.la
}
md5sums="3305df4d1b13ca964d80b23bb5e4e2b6 libspf2-1.2.9.tar.gz
48d82a6af8c513d75a7402f2933b8b0a libspf2-localpolicy-fix.patch"
dab7cc92ed1ff332e4fcfab95b8d35ea libspf2-localpolicy-fix.patch
201889cbd209aa7cae9ce11ed5ebaaa6 0001-provide-dn_skipname.patch
6dd2d5f33c5f1a5b7c14eec4c71767cd libspf2-libreplace-fix.patch
06c981fcca0434d447f8a2749b51696f libspf2-res_ninit-uclibc.patch"
diff --git a/src/libreplace/__ns_initparse.c b/src/libreplace/__ns_initparse.c
index 10a7c9c..f22fa09 100644
--- a/src/libreplace/__ns_initparse.c
+++ b/src/libreplace/__ns_initparse.c
@@ -52,26 +52,6 @@ static void setsection(ns_msg *msg, ns_sect sect);
/* Public. */
-/* These need to be in the same order as the nres.h:ns_flag enum. */
-struct _ns_flagdata _ns_flagdata[16] = {
- { 0x8000, 15 }, /* qr. */
- { 0x7800, 11 }, /* opcode. */
- { 0x0400, 10 }, /* aa. */
- { 0x0200, 9 }, /* tc. */
- { 0x0100, 8 }, /* rd. */
- { 0x0080, 7 }, /* ra. */
- { 0x0040, 6 }, /* z. */
- { 0x0020, 5 }, /* ad. */
- { 0x0010, 4 }, /* cd. */
- { 0x000f, 0 }, /* rcode. */
- { 0x0000, 0 }, /* expansion (1/6). */
- { 0x0000, 0 }, /* expansion (2/6). */
- { 0x0000, 0 }, /* expansion (3/6). */
- { 0x0000, 0 }, /* expansion (4/6). */
- { 0x0000, 0 }, /* expansion (5/6). */
- { 0x0000, 0 }, /* expansion (6/6). */
-};
-
int
ns_skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
const u_char *optr = ptr;
diff --git a/src/libreplace/__ns_msg_getflag.c b/src/libreplace/__ns_msg_getflag.c
index 19bfb88..a46c017 100644
--- a/src/libreplace/__ns_msg_getflag.c
+++ b/src/libreplace/__ns_msg_getflag.c
@@ -11,6 +11,25 @@
#include "arpa_nameser.h"
+/* These need to be in the same order as the nres.h:ns_flag enum. */
+struct _ns_flagdata _ns_flagdata[16] = {
+ { 0x8000, 15 }, /* qr. */
+ { 0x7800, 11 }, /* opcode. */
+ { 0x0400, 10 }, /* aa. */
+ { 0x0200, 9 }, /* tc. */
+ { 0x0100, 8 }, /* rd. */
+ { 0x0080, 7 }, /* ra. */
+ { 0x0040, 6 }, /* z. */
+ { 0x0020, 5 }, /* ad. */
+ { 0x0010, 4 }, /* cd. */
+ { 0x000f, 0 }, /* rcode. */
+ { 0x0000, 0 }, /* expansion (1/6). */
+ { 0x0000, 0 }, /* expansion (2/6). */
+ { 0x0000, 0 }, /* expansion (3/6). */
+ { 0x0000, 0 }, /* expansion (4/6). */
+ { 0x0000, 0 }, /* expansion (5/6). */
+ { 0x0000, 0 }, /* expansion (6/6). */
+};
int __ns_msg_getflag(ns_msg handle, int flag) {
return(((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift);
--- libspf2-1.2.9/src/libspf2/spf_interpret.c Wed Oct 22 15:47:43 2008
+++ libspf2-1.2.9.patched/src/libspf2/spf_interpret.c Mon Sep 21 12:22:51 2009
@@ -1261,6 +1261,7 @@
*/
if ( mech == local_policy ) {
+ spf_request->use_local_policy = 0;
err = SPF_record_interpret(spf_server->local_policy,
spf_request, spf_response, depth + 1);
--- libspf2-1.2.9/src/spfquery/spfquery.c Mon Sep 15 00:17:49 2008
+++ libspf2-1.2.9.patched/src/spfquery/spfquery.c Mon Sep 21 12:14:38 2009
@@ -602,6 +602,7 @@
FREE_RESPONSE(spf_response);
spf_request = SPF_request_new(spf_server);
diff --git a/src/libspf2/spf_interpret.c b/src/libspf2/spf_interpret.c
index 78fa81a..6dbdd8d 100644
--- a/src/libspf2/spf_interpret.c
+++ b/src/libspf2/spf_interpret.c
@@ -594,10 +594,6 @@ SPF_record_interpret(SPF_record_t *spf_record,
SPF_data_t *data;
SPF_data_t *data_end; /* XXX Replace with size_t data_len */
- /* Where to insert the local policy (whitelist) */
- SPF_mech_t *local_policy; /* Not the local policy */
- int found_all; /* A crappy temporary. */
-
char *buf = NULL;
size_t buf_len = 0;
ns_type fetch_ns_type;
@@ -662,58 +658,6 @@ SPF_record_interpret(SPF_record_t *spf_record,
#endif
/*
- * Do some start up stuff if we haven't recursed yet
- */
-
- local_policy = NULL;
-
- if ( spf_request->use_local_policy ) {
- /*
- * find the location for the whitelist execution
- *
- * Philip Gladstone says:
- *
- * I think that the localpolicy should only be inserted if the
- * final mechanism is '-all', and it should be inserted after
- * the last mechanism which is not '-'.
- *
- * Thus for the case of 'v=spf1 +a +mx -all', this would be
- * interpreted as 'v=spf1 +a +mx +localpolicy -all'. Whereas
- * 'v=spf1 -all' would remain the same (no non-'-'
- * mechanism). 'v=spf1 +a +mx -exists:%stuff -all' would
- * become 'v=spf1 +a +mx +localpolicy -exists:%stuff -all'.
- */
-
- if ( spf_server->local_policy ) {
- mech = spf_record->mech_first;
-
- found_all = FALSE;
- for(m = 0; m < spf_record->num_mech; m++)
- {
- if ( mech->mech_type == MECH_ALL
- && (mech->prefix_type == PREFIX_FAIL
- || mech->prefix_type == PREFIX_UNKNOWN
- || mech->prefix_type == PREFIX_SOFTFAIL
- )
- )
- found_all = TRUE;
-
- if ( mech->prefix_type != PREFIX_FAIL
- && mech->prefix_type != PREFIX_SOFTFAIL
- )
- local_policy = mech;
-
- mech = SPF_mech_next( mech );
- }
-
- if ( !found_all )
- local_policy = NULL;
- }
-
- }
-
-
- /*
* evaluate the mechanisms
*/
@@ -751,6 +695,35 @@ SPF_record_interpret(SPF_record_t *spf_record,
resolver = spf_server->resolver;
+ /*
+ * execute the local policy
+ */
+ if ( spf_request->use_local_policy && spf_server->local_policy ) {
+ spf_request->use_local_policy = 0;
+ err = SPF_record_interpret(spf_server->local_policy,
+ spf_request, spf_response, depth + 1);
+ spf_request->use_local_policy = 1;
+
+ if ( spf_server->debug > 0 )
+ SPF_debugf( "local_policy: executed SPF record: %s result: %s reason: %s",
+ SPF_strerror( err ),
+ SPF_strresult( spf_response->result ),
+ SPF_strreason( spf_response->reason ) );
+
+ if (spf_response->result != SPF_RESULT_INVALID &&
+ spf_response->result != SPF_RESULT_NONE &&
+ spf_response->result != SPF_RESULT_NEUTRAL) {
+ SPF_FREE_LOOKUP_DATA();
+ return err;
+ }
+
+ if ( spf_server->debug > 0 )
+ SPF_debugf( "local_policy: not definite",
+ SPF_strerror( err ),
+ SPF_strresult( spf_response->result ),
+ SPF_strreason( spf_response->reason ) );
+ }
+
mech = spf_record->mech_first;
for (m = 0; m < spf_record->num_mech; m++) {
@@ -1256,26 +1229,6 @@ SPF_record_interpret(SPF_record_t *spf_record,
break;
}
- /*
- * execute the local policy
- */
-
- if ( mech == local_policy ) {
- err = SPF_record_interpret(spf_server->local_policy,
- spf_request, spf_response, depth + 1);
-
- if ( spf_server->debug > 0 )
- SPF_debugf( "local_policy: executed SPF record: %s result: %s reason: %s",
- SPF_strerror( err ),
- SPF_strresult( spf_response->result ),
- SPF_strreason( spf_response->reason ) );
-
- if (spf_response->result != SPF_RESULT_INVALID) {
- SPF_FREE_LOOKUP_DATA();
- return err;
- }
- }
-
mech = SPF_mech_next( mech );
}
diff --git a/src/libspf2/spf_request.c b/src/libspf2/spf_request.c
index 7614141..9eb1774 100644
--- a/src/libspf2/spf_request.c
+++ b/src/libspf2/spf_request.c
@@ -47,6 +47,7 @@ SPF_request_new(SPF_server_t *spf_server)
return sr;
memset(sr, 0, sizeof(SPF_request_t));
if (SPF_request_set_ipv4_str(spf_request, req->ip)
&& SPF_request_set_ipv6_str(spf_request, req->ip)) {
+ sr->use_local_policy = 1;
sr->spf_server = spf_server;
sr->client_ver = AF_UNSPEC;
sr->ipv4.s_addr = htonl(INADDR_ANY);
diff --git a/src/libspf2/spf_dns_resolv.c b/src/libspf2/spf_dns_resolv.c
index 10ccee6..7acdd1f 100644
--- a/src/libspf2/spf_dns_resolv.c
+++ b/src/libspf2/spf_dns_resolv.c
@@ -79,13 +79,13 @@ static const struct res_sym ns_sects[] = {
static const int num_ns_sect = sizeof(ns_sects) / sizeof(*ns_sects);
-#if HAVE_DECL_RES_NINIT
+#if HAVE_DECL_RES_NINIT && !defined(__UCLIBC__)
# define SPF_h_errno res_state->res_h_errno
#else
# define SPF_h_errno h_errno
#endif
-#if HAVE_DECL_RES_NINIT
+#if HAVE_DECL_RES_NINIT && !defined(__UCLIBC__)
static pthread_once_t res_state_control = PTHREAD_ONCE_INIT;
static pthread_key_t res_state_key;
@@ -239,14 +239,14 @@ SPF_dns_resolv_lookup(SPF_dns_server_t *spf_dns_server,
size_t rdlen;
const u_char *rdata;
-#if HAVE_DECL_RES_NINIT
+#if HAVE_DECL_RES_NINIT && !defined(__UCLIBC__)
void *res_spec;
struct __res_state *res_state;
#endif
SPF_ASSERT_NOTNULL(spf_dns_server);
-#if HAVE_DECL_RES_NINIT
+#if HAVE_DECL_RES_NINIT && !defined(__UCLIBC__)
/** Get the thread-local resolver state. */
res_spec = pthread_getspecific(res_state_key);
if (res_spec == NULL) {
@@ -292,7 +292,7 @@ SPF_dns_resolv_lookup(SPF_dns_server_t *spf_dns_server,
for (;;) {
int dns_len;
-#if HAVE_DECL_RES_NINIT
+#if HAVE_DECL_RES_NINIT && !defined(__UCLIBC__)
/* Resolve the name. */
dns_len = res_nquery(res_state, domain, ns_c_in, rr_type,
responsebuf, responselen);
@@ -606,7 +606,7 @@ SPF_dns_resolv_free(SPF_dns_server_t *spf_dns_server)
{
SPF_ASSERT_NOTNULL(spf_dns_server);
-#if ! HAVE_DECL_RES_NINIT
+#if ! HAVE_DECL_RES_NINIT || defined(__UCLIBC__)
res_close();
#endif
@@ -619,7 +619,7 @@ SPF_dns_resolv_new(SPF_dns_server_t *layer_below,
{
SPF_dns_server_t *spf_dns_server;
-#if HAVE_DECL_RES_NINIT
+#if HAVE_DECL_RES_NINIT && !defined(__UCLIBC__)
pthread_once(&res_state_control, SPF_dns_resolv_init_key);
#else
if (res_init() != 0) {
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment