#include "tools.h"
#include "domain.h"
+#ifdef HAVE_RESOLV_H
+#include <arpa/nameser.h>
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#include <arpa/nameser_compat.h>
+#endif
+#include <resolv.h>
+#endif
+
+
void locate_host(char *tbuf, size_t n,
char *abuf, size_t na,
const struct in_addr *addr)
int a1, a2, a3, a4;
char address_string[SIZ];
- lprintf(CTDL_DEBUG, "locate_host() called\n");
#ifdef HAVE_NONREENTRANT_NETDB
begin_critical_section(S_NETDB);
#endif
tbuf[63] = 0;
- lprintf(CTDL_DEBUG, "locate_host() exiting\n");
+}
+
+
+#define RESULT_SIZE 4096 /* What is the longest result text we support? */
+
+int rblcheck_backend(char *domain, char *txtbuf, int txtbufsize) {
+ int a, b, c;
+ char *result = NULL;
+ u_char fixedans[ PACKETSZ ];
+ u_char *answer;
+ int need_to_free_answer = 0;
+ const u_char *cp;
+ u_char *rp;
+ const u_char *cend;
+ const u_char *rend;
+ int len;
+
+ /* Make our DNS query. */
+ //res_init();
+ answer = fixedans;
+ len = res_query( domain, C_IN, T_A, answer, PACKETSZ );
+
+ /* Was there a problem? If so, the domain doesn't exist. */
+ if( len == -1 ) {
+ if (txtbuf != NULL) {
+ strcpy(txtbuf, "");
+ }
+ return(0);
+ }
+
+ if( len > PACKETSZ )
+ {
+ answer = malloc( len );
+ need_to_free_answer = 1;
+ len = res_query( domain, C_IN, T_A, answer, len );
+ if( len == -1 ) {
+ if (txtbuf != NULL) {
+ snprintf(txtbuf, txtbufsize,
+ "Message rejected due to known spammer source IP address");
+ }
+ if (need_to_free_answer) free(answer);
+ return(1);
+ }
+ }
+
+ result = ( char * )malloc( RESULT_SIZE );
+ result[ 0 ] = '\0';
+
+
+ /* Make another DNS query for textual data; this shouldn't
+ be a performance hit, since it'll now be cached at the
+ nameserver we're using. */
+ res_init();
+ len = res_query( domain, C_IN, T_TXT, answer, PACKETSZ );
+
+ /* Just in case there's no TXT record... */
+ if( len == -1 )
+ {
+ if (txtbuf != NULL) {
+ snprintf(txtbuf, txtbufsize,
+ "Message rejected due to known spammer source IP address");
+ }
+ if (need_to_free_answer) free(answer);
+ free(result);
+ return(1);
+ }
+
+ /* Skip the header and the address we queried. */
+ cp = answer + sizeof( HEADER );
+ while( *cp != '\0' )
+ {
+ a = *cp++;
+ while( a-- )
+ cp++;
+ }
+
+ /* This seems to be a bit of magic data that we need to
+ skip. I wish there were good online documentation
+ for programming for libresolv, so I'd know what I'm
+ skipping here. Anyone reading this, feel free to
+ enlighten me. */
+ cp += 1 + NS_INT16SZ + NS_INT32SZ;
+
+ /* Skip the type, class and ttl. */
+ cp += ( NS_INT16SZ * 2 ) + NS_INT32SZ;
+
+ /* Get the length and end of the buffer. */
+ NS_GET16( c, cp );
+ cend = cp + c;
+
+ /* Iterate over any multiple answers we might have. In
+ this context, it's unlikely, but anyway. */
+ rp = result;
+ rend = result + RESULT_SIZE - 1;
+ while( cp < cend && rp < rend )
+ {
+ a = *cp++;
+ if( a != 0 )
+ for( b = a; b > 0 && cp < cend && rp < rend;
+ b-- )
+ {
+ if( *cp == '\n' || *cp == '"' ||
+ *cp == '\\' )
+ {
+ *rp++ = '\\';
+ }
+ *rp++ = *cp++;
+ }
+ }
+ *rp = '\0';
+ if (txtbuf != NULL) {
+ snprintf(txtbuf, txtbufsize, "%s", result);
+ }
+ if (need_to_free_answer) free(answer);
+ free(result);
+ return(1);
}
int rbl;
int num_rbl;
char rbl_domains[SIZ];
+ char txt_answer[1024];
strcpy(message_to_spammer, "ok");
a4, a3, a2, a1);
extract_token(&tbuf[strlen(tbuf)], rbl_domains, rbl, '|', (sizeof tbuf - strlen(tbuf)));
- if (gethostbyname(tbuf) != NULL) {
- strcpy(message_to_spammer,
- "5.7.1 Message rejected due to known spammer source IP address"
- );
+ if (rblcheck_backend(tbuf, txt_answer, sizeof txt_answer)) {
+ sprintf(message_to_spammer, "5.7.1 %s", txt_answer);
+ lprintf(CTDL_INFO, "RBL: %s\n", txt_answer);
return(1);
}
}