-/* $Cambridge: exim/src/src/verify.c,v 1.48 2007/02/06 12:19:27 ph10 Exp $ */
-
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2007 */
+/* Copyright (c) University of Cambridge 1995 - 2009 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions concerned with verifying things. The original code for callout
vaddr->basic_errno = addr->basic_errno;
vaddr->more_errno = addr->more_errno;
vaddr->p.address_data = addr->p.address_data;
+ copyflag(vaddr, addr, af_pass_message);
}
return yield;
}
+/**************************************************
+* printf that automatically handles TLS if needed *
+***************************************************/
+
+/* This function is used by verify_address() as a substitute for all fprintf()
+calls; a direct fprintf() will not produce output in a TLS SMTP session, such
+as a response to an EXPN command. smtp_in.c makes smtp_printf available but
+that assumes that we always use the smtp_out FILE* when not using TLS or the
+ssl buffer when we are. Instead we take a FILE* parameter and check to see if
+that is smtp_out; if so, smtp_printf() with TLS support, otherwise regular
+fprintf().
+
+Arguments:
+ f the candidate FILE* to write to
+ format format string
+ ... optional arguments
+
+Returns:
+ nothing
+*/
+
+static void PRINTF_FUNCTION(2,3)
+respond_printf(FILE *f, const char *format, ...)
+{
+va_list ap;
+
+va_start(ap, format);
+if (smtp_out && (f == smtp_out))
+ smtp_vprintf(format, ap);
+else
+ vfprintf(f, format, ap);
+va_end(ap);
+}
+
+
+
/*************************************************
* Verify an email address *
*************************************************/
if ((options & vopt_qualify) == 0)
{
if (f != NULL)
- fprintf(f, "%sA domain is required for \"%s\"%s\n", ko_prefix, address,
- cr);
+ respond_printf(f, "%sA domain is required for \"%s\"%s\n",
+ ko_prefix, address, cr);
*failure_ptr = US"qualify";
return FAIL;
}
{
address_item *p = addr->parent;
- fprintf(f, "%s%s %s", ko_prefix, full_info? addr->address : address,
+ respond_printf(f, "%s%s %s", ko_prefix,
+ full_info? addr->address : address,
address_test_mode? "is undeliverable" : "failed to verify");
if (!expn && admin_user)
{
if (addr->basic_errno > 0)
- fprintf(f, ": %s", strerror(addr->basic_errno));
+ respond_printf(f, ": %s", strerror(addr->basic_errno));
if (addr->message != NULL)
- fprintf(f, ": %s", addr->message);
+ respond_printf(f, ": %s", addr->message);
}
/* Show parents iff doing full info */
if (full_info) while (p != NULL)
{
- fprintf(f, "%s\n <-- %s", cr, p->address);
+ respond_printf(f, "%s\n <-- %s", cr, p->address);
p = p->parent;
}
- fprintf(f, "%s\n", cr);
+ respond_printf(f, "%s\n", cr);
}
if (!full_info) return copy_error(vaddr, addr, FAIL);
if (f != NULL)
{
address_item *p = addr->parent;
- fprintf(f, "%s%s cannot be resolved at this time", ko_prefix,
+ respond_printf(f, "%s%s cannot be resolved at this time", ko_prefix,
full_info? addr->address : address);
if (!expn && admin_user)
{
if (addr->basic_errno > 0)
- fprintf(f, ": %s", strerror(addr->basic_errno));
+ respond_printf(f, ": %s", strerror(addr->basic_errno));
if (addr->message != NULL)
- fprintf(f, ": %s", addr->message);
+ respond_printf(f, ": %s", addr->message);
else if (addr->basic_errno <= 0)
- fprintf(f, ": unknown error");
+ respond_printf(f, ": unknown error");
}
/* Show parents iff doing full info */
if (full_info) while (p != NULL)
{
- fprintf(f, "%s\n <-- %s", cr, p->address);
+ respond_printf(f, "%s\n <-- %s", cr, p->address);
p = p->parent;
}
- fprintf(f, "%s\n", cr);
+ respond_printf(f, "%s\n", cr);
}
-
if (!full_info) return copy_error(vaddr, addr, DEFER);
else if (yield == OK) yield = DEFER;
}
if (addr_new == NULL)
{
if (addr_local == NULL && addr_remote == NULL)
- fprintf(f, "250 mail to <%s> is discarded\r\n", address);
+ respond_printf(f, "250 mail to <%s> is discarded\r\n", address);
else
- fprintf(f, "250 <%s>\r\n", address);
+ respond_printf(f, "250 <%s>\r\n", address);
}
else while (addr_new != NULL)
{
address_item *addr2 = addr_new;
addr_new = addr2->next;
if (addr_new == NULL) ok_prefix = US"250 ";
- fprintf(f, "%s<%s>\r\n", ok_prefix, addr2->address);
+ respond_printf(f, "%s<%s>\r\n", ok_prefix, addr2->address);
}
return OK;
}
name, we have to fish the file off the start of the query. For a single-key
lookup, the key is the current IP address, masked appropriately, and
reconverted to text form, with the mask appended. For IPv6 addresses, specify
- dot separators instead of colons. */
+ dot separators instead of colons, except when the lookup type is "iplsearch".
+ */
if (mac_islookup(search_type, lookup_absfilequery))
{
filename = NULL;
key = semicolon + 1;
}
- else
+ else /* Single-key style */
{
+ int sep = (Ustrcmp(lookup_list[search_type]->name, "iplsearch") == 0)?
+ ':' : '.';
insize = host_aton(cb->host_address, incoming);
host_mask(insize, incoming, mlen);
- (void)host_nmtoa(insize, incoming, mlen, buffer, '.');
+ (void)host_nmtoa(insize, incoming, mlen, buffer, sep);
key = buffer;
filename = semicolon + 1;
}
/*************************************************
-* Invert an IP address for a DNS black list *
+* Invert an IP address *
*************************************************/
-/*
+/* Originally just used for DNS xBL lists, now also used for the
+reverse_ip expansion operator.
+
Arguments:
buffer where to put the answer
address the address to invert
*/
-static void
+void
invert_address(uschar *buffer, uschar *address)
{
int bin[4];
for (s = domain; *s != 0; s++)
{
- if (!isalnum(*s) && *s != '-' && *s != '.')
+ if (!isalnum(*s) && *s != '-' && *s != '.' && *s != '_')
{
log_write(0, LOG_MAIN, "dnslists domain \"%s\" contains "
"strange characters - is this right?", domain);
if (domain_txt != domain) for (s = domain_txt; *s != 0; s++)
{
- if (!isalnum(*s) && *s != '-' && *s != '.')
+ if (!isalnum(*s) && *s != '-' && *s != '.' && *s != '_')
{
log_write(0, LOG_MAIN, "dnslists domain \"%s\" contains "
"strange characters - is this right?", domain_txt);
if (rc == OK)
{
dnslist_domain = string_copy(domain_txt);
+ dnslist_matched = string_copy(sender_host_address);
HDEBUG(D_dnsbl) debug_printf("=> that means %s is listed at %s\n",
sender_host_address, dnslist_domain);
}
if (rc == OK)
{
dnslist_domain = string_copy(domain_txt);
+ dnslist_matched = string_copy(keydomain);
HDEBUG(D_dnsbl) debug_printf("=> that means %s is listed at %s\n",
keydomain, dnslist_domain);
return OK;