summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTodd Lyons <tlyons@exim.org>2014-05-12 08:12:17 -0700
committerTodd Lyons <tlyons@exim.org>2014-05-12 08:12:17 -0700
commit9aa512a1898155484e00ee089057d28f2432b30e (patch)
tree231b6a3479c59e09a15f63f1350d31fb60f360b6 /src
parenta37a8eec3f4c73e604c23d73c9264c8ae95a0037 (diff)
parent783b385fe846f97aa5d7a7675cc0600e917b8795 (diff)
Merge branch 'master' of ssh://git.exim.org/home/git/exim
Diffstat (limited to 'src')
-rw-r--r--src/Makefile1
-rw-r--r--src/OS/os.c-Linux2
-rw-r--r--src/src/deliver.c56
-rw-r--r--src/src/expand.c31
-rw-r--r--src/src/functions.h1
-rw-r--r--src/src/globals.c1
-rw-r--r--src/src/globals.h3
-rw-r--r--src/src/host.c48
-rw-r--r--src/src/malware.c14
-rw-r--r--src/src/route.c1
-rw-r--r--src/src/string.c2
-rw-r--r--src/src/structs.h4
-rw-r--r--src/src/tls-gnu.c7
-rw-r--r--src/src/tls-openssl.c37
-rw-r--r--src/src/tlscert-gnu.c6
-rw-r--r--src/src/tlscert-openssl.c16
-rw-r--r--src/src/transport.c1
-rw-r--r--src/src/transports/smtp.c12
18 files changed, 176 insertions, 67 deletions
diff --git a/src/Makefile b/src/Makefile
index b913aec8a..99f4ab308 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -94,6 +94,7 @@ cscope.files: FRC
-o -name "os.h*" -print \
-o -name "*akefile*" -print \
-o -name EDITME -print >> $@
+ ls OS/* >> $@
FRC:
diff --git a/src/OS/os.c-Linux b/src/OS/os.c-Linux
index 1e8a6f47d..df0dff9db 100644
--- a/src/OS/os.c-Linux
+++ b/src/OS/os.c-Linux
@@ -94,7 +94,7 @@ ip_address_item *last = NULL;
ip_address_item *next;
char addr6p[8][5];
unsigned int plen, scope, dad_status, if_idx;
-char devname[20];
+char devname[20+1];
FILE *f;
#endif
diff --git a/src/src/deliver.c b/src/src/deliver.c
index fff0e2fd0..777ff8dc7 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -730,6 +730,7 @@ pointer to a single host item in their host list, for use by the transport. */
tpda_delivery_local_part = NULL;
tpda_delivery_domain = NULL;
tpda_delivery_confirmation = NULL;
+ lookup_dnssec_authenticated = NULL;
#endif
s = reset_point = store_get(size);
@@ -793,7 +794,7 @@ if (addr->transport->info->local)
else
{
- if (addr->host_used != NULL)
+ if (addr->host_used)
{
s = d_hostlog(s, &size, &ptr, addr);
if (continue_sequence > 1)
@@ -806,6 +807,11 @@ else
tpda_delivery_local_part = addr->local_part;
tpda_delivery_domain = addr->domain;
tpda_delivery_confirmation = addr->message;
+
+ /* DNS lookup status */
+ lookup_dnssec_authenticated = addr->host_used->dnssec==DS_YES ? US"yes"
+ : addr->host_used->dnssec==DS_NO ? US"no"
+ : NULL;
#endif
}
@@ -1088,6 +1094,10 @@ if (result == OK)
addr->ourcert = NULL;
tls_out.peercert = addr->peercert;
addr->peercert = NULL;
+
+ tls_out.cipher = addr->cipher;
+ tls_out.peerdn = addr->peerdn;
+ tls_out.ocsp = addr->ocsp;
#endif
delivery_log(LOG_MAIN, addr, logchar, NULL);
@@ -1103,6 +1113,9 @@ if (result == OK)
tls_free_cert(tls_out.peercert);
tls_out.peercert = NULL;
}
+ tls_out.cipher = NULL;
+ tls_out.peerdn = NULL;
+ tls_out.ocsp = OCSP_NOT_REQ;
#endif
}
@@ -2987,9 +3000,7 @@ while (!done)
addr->cipher = string_copy(ptr);
while (*ptr++);
if (*ptr)
- {
addr->peerdn = string_copy(ptr);
- }
break;
case '2':
@@ -3003,10 +3014,18 @@ while (!done)
if (*ptr)
(void) tls_import_cert(ptr, &addr->ourcert);
break;
+
+ #ifdef EXPERIMENTAL_OCSP
+ case '4':
+ addr->ocsp = OCSP_NOT_REQ;
+ if (*ptr)
+ addr->ocsp = *ptr - '0';
+ break;
+ #endif
}
while (*ptr++);
break;
- #endif
+ #endif /*SUPPORT_TLS*/
case 'C': /* client authenticator information */
switch (*ptr++)
@@ -3026,7 +3045,7 @@ while (!done)
#ifdef EXPERIMENTAL_PRDR
case 'P':
- addr->flags |= af_prdr_used; break;
+ addr->flags |= af_prdr_used; break;
#endif
case 'A':
@@ -3053,7 +3072,7 @@ while (!done)
addr->user_message = (*ptr)? string_copy(ptr) : NULL;
while(*ptr++);
- /* Always two strings for host information, followed by the port number */
+ /* Always two strings for host information, followed by the port number and DNSSEC mark */
if (*ptr != 0)
{
@@ -3064,6 +3083,10 @@ while (!done)
while(*ptr++);
memcpy(&(h->port), ptr, sizeof(h->port));
ptr += sizeof(h->port);
+ h->dnssec = *ptr == '2' ? DS_YES
+ : *ptr == '1' ? DS_NO
+ : DS_UNK;
+ ptr++;
addr->host_used = h;
}
else ptr++;
@@ -4091,11 +4114,9 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
retry_item *r;
/* The certificate verification status goes into the flags */
-
if (tls_out.certificate_verified) setflag(addr, af_cert_verified);
/* Use an X item only if there's something to send */
-
#ifdef SUPPORT_TLS
if (addr->cipher)
{
@@ -4132,7 +4153,16 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
*ptr++ = 0;
rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer);
}
- #endif
+ # ifdef EXPERIMENTAL_OCSP
+ if (addr->ocsp > OCSP_NOT_REQ)
+ {
+ ptr = big_buffer;
+ sprintf(CS ptr, "X4%c", addr->ocsp + '0');
+ while(*ptr++);
+ rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer);
+ }
+ # endif
+ #endif /*SUPPORT_TLS*/
if (client_authenticator)
{
@@ -4157,7 +4187,8 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
}
#ifdef EXPERIMENTAL_PRDR
- if (addr->flags & af_prdr_used) rmt_dlv_checked_write(fd, "P", 1);
+ if (addr->flags & af_prdr_used)
+ rmt_dlv_checked_write(fd, "P", 1);
#endif
/* Retry information: for most success cases this will be null. */
@@ -4211,6 +4242,11 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++)
while(*ptr++);
memcpy(ptr, &(addr->host_used->port), sizeof(addr->host_used->port));
ptr += sizeof(addr->host_used->port);
+
+ /* DNS lookup status */
+ *ptr++ = addr->host_used->dnssec==DS_YES ? '2'
+ : addr->host_used->dnssec==DS_NO ? '1' : '0';
+
}
rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer);
}
diff --git a/src/src/expand.c b/src/src/expand.c
index 01c6e05f4..9afc036fa 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -205,6 +205,7 @@ static uschar *op_table_main[] = {
US"rxquote",
US"s",
US"sha1",
+ US"sha256",
US"stat",
US"str2b64",
US"strlen",
@@ -242,6 +243,7 @@ enum {
EOP_RXQUOTE,
EOP_S,
EOP_SHA1,
+ EOP_SHA256,
EOP_STAT,
EOP_STR2B64,
EOP_STRLEN,
@@ -5365,8 +5367,6 @@ while (*s != 0)
#ifdef SUPPORT_TLS
case EITEM_CERTEXTRACT:
{
- int i;
- int field_number = 1;
uschar *save_lookup_value = lookup_value;
uschar *sub[2];
int save_expand_nmax =
@@ -5382,7 +5382,6 @@ while (*s != 0)
/* strip spaces fore & aft */
{
int len;
- int x = 0;
uschar *p = sub[0];
while (isspace(*p)) p++;
@@ -5725,7 +5724,7 @@ while (*s != 0)
int c;
uschar *arg = NULL;
uschar *sub;
- var_entry *vp;
+ var_entry *vp = NULL;
/* Owing to an historical mis-design, an underscore may be part of the
operator name, or it may introduce arguments. We therefore first scan the
@@ -5748,8 +5747,9 @@ while (*s != 0)
switch(c)
{
#ifdef SUPPORT_TLS
- case EOP_SHA1:
case EOP_MD5:
+ case EOP_SHA1:
+ case EOP_SHA256:
if (s[1] == '$')
{
uschar * s1 = s;
@@ -5763,7 +5763,6 @@ while (*s != 0)
break;
}
}
- vp = NULL;
/*FALLTHROUGH*/
#endif
default:
@@ -5861,7 +5860,7 @@ while (*s != 0)
if (vp && *(void **)vp->value)
{
uschar * cp = tls_cert_fprt_md5(*(void **)vp->value);
- yield = string_cat(yield, &size, &ptr, cp, (int)strlen(cp));
+ yield = string_cat(yield, &size, &ptr, cp, Ustrlen(cp));
}
else
#endif
@@ -5882,7 +5881,7 @@ while (*s != 0)
if (vp && *(void **)vp->value)
{
uschar * cp = tls_cert_fprt_sha1(*(void **)vp->value);
- yield = string_cat(yield, &size, &ptr, cp, (int)strlen(cp));
+ yield = string_cat(yield, &size, &ptr, cp, Ustrlen(cp));
}
else
#endif
@@ -5898,6 +5897,18 @@ while (*s != 0)
}
continue;
+ case EOP_SHA256:
+#ifdef SUPPORT_TLS
+ if (vp && *(void **)vp->value)
+ {
+ uschar * cp = tls_cert_fprt_sha256(*(void **)vp->value);
+ yield = string_cat(yield, &size, &ptr, cp, (int)strlen(cp));
+ }
+ else
+#endif
+ expand_string_message = US"sha256 only supported for certificates";
+ continue;
+
/* Convert hex encoding to base64 encoding */
case EOP_HEX2B64:
@@ -6349,7 +6360,7 @@ while (*s != 0)
case EOP_UTF8CLEAN:
{
int seq_len, index = 0;
- int bytes_left = 0;
+ int bytes_left = 0;
uschar seq_buff[4]; /* accumulate utf-8 here */
while (*sub != 0)
@@ -6360,7 +6371,7 @@ while (*s != 0)
complete = 0;
c = *sub++;
- if(bytes_left)
+ if (bytes_left)
{
if ((c & 0xc0) != 0x80)
{
diff --git a/src/src/functions.h b/src/src/functions.h
index 38ba7f39d..792f3df4d 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -41,6 +41,7 @@ extern uschar * tls_cert_version(void *, uschar * mod);
extern uschar * tls_cert_fprt_md5(void *);
extern uschar * tls_cert_fprt_sha1(void *);
+extern uschar * tls_cert_fprt_sha256(void *);
extern int tls_client_start(int, host_item *, address_item *,
void *);
diff --git a/src/src/globals.c b/src/src/globals.c
index af2903525..a2cc50313 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -341,6 +341,7 @@ address_item address_defaults = {
NULL, /* ourcert */
NULL, /* peercert */
NULL, /* peerdn */
+ OCSP_NOT_REQ, /* ocsp */
#endif
NULL, /* authenticator */
NULL, /* auth_id */
diff --git a/src/src/globals.h b/src/src/globals.h
index 9a42fe27e..8b55321f9 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -92,7 +92,8 @@ typedef struct {
enum {
OCSP_NOT_REQ=0, /* not requested */
OCSP_NOT_RESP, /* no response to request */
- OCSP_NOT_VFY, /* response not verified */
+ OCSP_VFY_NOT_TRIED, /* response not verified */
+ OCSP_FAILED, /* verify failed */
OCSP_VFIED /* verified */
} ocsp; /* Stapled OCSP status */
} tls_support;
diff --git a/src/src/host.c b/src/src/host.c
index a1db7717e..a59c4381b 100644
--- a/src/src/host.c
+++ b/src/src/host.c
@@ -2065,6 +2065,7 @@ for (i = 1; i <= times;
host->port = PORT_NONE;
host->status = hstatus_unknown;
host->why = hwhy_unknown;
+ host->dnssec = DS_UNK;
last = host;
}
@@ -2080,6 +2081,7 @@ for (i = 1; i <= times;
next->port = PORT_NONE;
next->status = hstatus_unknown;
next->why = hwhy_unknown;
+ next->dnssec = DS_UNK;
next->last_try = 0;
next->next = last->next;
last->next = next;
@@ -2475,10 +2477,12 @@ int ind_type = 0;
int yield;
dns_answer dnsa;
dns_scan dnss;
-BOOL dnssec_request = match_isinlist(host->name, &dnssec_request_domains,
- 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
BOOL dnssec_require = match_isinlist(host->name, &dnssec_require_domains,
0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
+BOOL dnssec_request = dnssec_require
+ || match_isinlist(host->name, &dnssec_request_domains,
+ 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
+dnssec_status_t dnssec;
/* Set the default fully qualified name to the incoming name, initialize the
resolver if necessary, set up the relevant options, and initialize the flag
@@ -2487,7 +2491,7 @@ that gets set for DNS syntax check errors. */
if (fully_qualified_name != NULL) *fully_qualified_name = host->name;
dns_init((whichrrs & HOST_FIND_QUALIFY_SINGLE) != 0,
(whichrrs & HOST_FIND_SEARCH_PARENTS) != 0,
- dnssec_request || dnssec_require
+ dnssec_request
);
host_find_failed_syntax = FALSE;
@@ -2509,9 +2513,17 @@ if ((whichrrs & HOST_FIND_BY_SRV) != 0)
the input name, pass back the new original domain, without the prepended
magic. */
+ dnssec = DS_UNK;
+ lookup_dnssec_authenticated = NULL;
rc = dns_lookup(&dnsa, buffer, ind_type, &temp_fully_qualified_name);
- lookup_dnssec_authenticated = !dnssec_request ? NULL
- : dns_is_secure(&dnsa) ? US"yes" : US"no";
+
+ if (dnssec_request)
+ {
+ if (dns_is_secure(&dnsa))
+ { dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; }
+ else
+ { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; }
+ }
if (temp_fully_qualified_name != buffer && fully_qualified_name != NULL)
*fully_qualified_name = temp_fully_qualified_name + prefix_length;
@@ -2547,9 +2559,17 @@ listed as one for which we continue. */
if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0)
{
ind_type = T_MX;
+ dnssec = DS_UNK;
+ lookup_dnssec_authenticated = NULL;
rc = dns_lookup(&dnsa, host->name, ind_type, fully_qualified_name);
- lookup_dnssec_authenticated = !dnssec_request ? NULL
- : dns_is_secure(&dnsa) ? US"yes" : US"no";
+
+ if (dnssec_request)
+ {
+ if (dns_is_secure(&dnsa))
+ { dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; }
+ else
+ { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; }
+ }
switch (rc)
{
@@ -2593,9 +2613,19 @@ if (rc != DNS_SUCCEED)
last = host; /* End of local chainlet */
host->mx = MX_NONE;
host->port = PORT_NONE;
+ dnssec = DS_UNK;
+ lookup_dnssec_authenticated = NULL;
rc = set_address_from_dns(host, &last, ignore_target_hosts, FALSE,
fully_qualified_name, dnssec_request, dnssec_require);
+ if (dnssec_request)
+ {
+ if (dns_is_secure(&dnsa))
+ { dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; }
+ else
+ { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; }
+ }
+
/* If one or more address records have been found, check that none of them
are local. Since we know the host items all have their IP addresses
inserted, host_scan_for_local_hosts() can only return HOST_FOUND or
@@ -2665,9 +2695,7 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
the same precedence to sort randomly. */
if (ind_type == T_MX)
- {
weight = random_number(500);
- }
/* SRV records are specified with a port and a weight. The weight is used
in a special algorithm. However, to start with, we just use it to order the
@@ -2731,6 +2759,7 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
host->sort_key = precedence * 1000 + weight;
host->status = hstatus_unknown;
host->why = hwhy_unknown;
+ host->dnssec = dnssec;
last = host;
}
@@ -2747,6 +2776,7 @@ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
next->sort_key = sort_key;
next->status = hstatus_unknown;
next->why = hwhy_unknown;
+ next->dnssec = dnssec;
next->last_try = 0;
/* Handle the case when we have to insert before the first item. */
diff --git a/src/src/malware.c b/src/src/malware.c
index aaf3fcb7e..2d2a8c892 100644
--- a/src/src/malware.c
+++ b/src/src/malware.c
@@ -42,7 +42,7 @@ static struct scan
#define MAX_CLAMD_ADDRESS_LENGTH_S "64"
typedef struct clamd_address_container {
- uschar tcp_addr[MAX_CLAMD_ADDRESS_LENGTH];
+ uschar tcp_addr[MAX_CLAMD_ADDRESS_LENGTH+1];
unsigned int tcp_port;
} clamd_address_container;
@@ -401,6 +401,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
case MC_TCP: sock = m_tcpsocket_fromdef(scanner_options, &errstr); break;
case MC_UNIX: sock = m_unixsocket(scanner_options, &errstr); break;
case MC_STRM: sock = m_streamsocket(scanner_options, &errstr); break;
+ default: /* compiler quietening */ break;
}
if (sock < 0)
return m_errlog_defer(scanent, errstr);
@@ -944,12 +945,10 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
sep = pclose(scanner_out);
signal(SIGCHLD,eximsigchld); signal(SIGPIPE,eximsigpipe);
if (sep != 0)
- if (sep == -1)
return m_errlog_defer(scanent,
- string_sprintf("running scanner failed: %s", strerror(sep)));
- else
- return m_errlog_defer(scanent,
- string_sprintf("scanner returned error code: %d", sep));
+ sep == -1
+ ? string_sprintf("running scanner failed: %s", strerror(sep))
+ : string_sprintf("scanner returned error code: %d", sep));
if (trigger) {
uschar * s;
@@ -1270,8 +1269,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
{
free(clamav_fbuf);
return m_errlog_defer_3(scanent,
- string_sprintf("unable to send file body to socket (%s:%u)",
- hostname, port),
+ string_sprintf("unable to send file body to socket (%s)", hostname),
sock);
}
#endif
diff --git a/src/src/route.c b/src/src/route.c
index 271175e4b..0116e12af 100644
--- a/src/src/route.c
+++ b/src/src/route.c
@@ -1941,6 +1941,7 @@ DEBUG(D_route)
if (h->mx >= 0) debug_printf(" MX=%d", h->mx);
else if (h->mx != MX_NONE) debug_printf(" rgroup=%d", h->mx);
if (h->port != PORT_NONE) debug_printf(" port=%d", h->port);
+ /* if (h->dnssec != DS_UNK) debug_printf(" dnssec=%s", h->dnssec==DS_YES ? "yes" : "no"); */
debug_printf("\n");
}
}
diff --git a/src/src/string.c b/src/src/string.c
index f216e5a86..914390255 100644
--- a/src/src/string.c
+++ b/src/src/string.c
@@ -998,7 +998,7 @@ if (list)
new = string_cat(new, &sz, &off, &sep, 1);
}
-while (sp = Ustrchr(ele, sep))
+while((sp = Ustrchr(ele, sep)))
{
new = string_cat(new, &sz, &off, ele, sp-ele+1);
new = string_cat(new, &sz, &off, &sep, 1);
diff --git a/src/src/structs.h b/src/src/structs.h
index a6c78f4fc..989653e30 100644
--- a/src/src/structs.h
+++ b/src/src/structs.h
@@ -55,6 +55,8 @@ typedef struct ugid_block {
but also used when checking lists of hosts and when transporting. Looking up
host addresses is done using this structure. */
+typedef enum {DS_UNK=-1, DS_NO, DS_YES} dnssec_status_t;
+
typedef struct host_item {
struct host_item *next;
uschar *name; /* Host name */
@@ -65,6 +67,7 @@ typedef struct host_item {
int status; /* Usable, unusable, or unknown */
int why; /* Why host is unusable */
int last_try; /* Time of last try if known */
+ dnssec_status_t dnssec;
} host_item;
/* Chain of rewrite rules, read from the rewrite config, or parsed from the
@@ -543,6 +546,7 @@ typedef struct address_item {
void *ourcert; /* Certificate offered to peer, binary */
void *peercert; /* Certificate from peer, binary */
uschar *peerdn; /* DN of server's certificate */
+ int ocsp; /* OCSP status of peer cert */
#endif
uschar *authenticator; /* auth driver name used by transport */
diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c
index b0b67d820..3c926c0d4 100644
--- a/src/src/tls-gnu.c
+++ b/src/src/tls-gnu.c
@@ -1446,15 +1446,15 @@ server_ocsp_stapling_cb(gnutls_session_t session, void * ptr,
{
int ret;
-tls_in.ocsp = OCSP_NOT_RESP;
if ((ret = gnutls_load_file(ptr, ocsp_response)) < 0)
{
DEBUG(D_tls) debug_printf("Failed to load ocsp stapling file %s\n",
(char *)ptr);
+ tls_in.ocsp = OCSP_NOT_RESP;
return GNUTLS_E_NO_CERTIFICATE_STATUS;
}
-tls_in.ocsp = OCSP_NOT_VFY;
+tls_in.ocsp = OCSP_VFY_NOT_TRIED;
return 0;
}
@@ -1778,7 +1778,10 @@ if (require_ocsp)
}
if (gnutls_ocsp_status_request_is_checked(state->session, 0) == 0)
+ {
+ tls_out.ocsp = OCSP_FAILED;
return tls_error(US"certificate status check failed", NULL, state->host);
+ }
DEBUG(D_tls) debug_printf("Passed OCSP checking\n");
tls_out.ocsp = OCSP_VFIED;
}
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index fd257f3c6..db2544c03 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -572,21 +572,21 @@ if (!OCSP_check_validity(thisupd, nextupd, EXIM_OCSP_SKEW_SECONDS, EXIM_OCSP_MAX
}
supply_response:
-cbinfo->u_ocsp.server.response = resp;
+ cbinfo->u_ocsp.server.response = resp;
return;
bad:
-if (running_in_test_harness)
- {
- extern char ** environ;
- uschar ** p;
- for (p = USS environ; *p != NULL; p++)
- if (Ustrncmp(*p, "EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK", 42) == 0)
- {
- DEBUG(D_tls) debug_printf("Supplying known bad OCSP response\n");
- goto supply_response;
- }
- }
+ if (running_in_test_harness)
+ {
+ extern char ** environ;
+ uschar ** p;
+ for (p = USS environ; *p != NULL; p++)
+ if (Ustrncmp(*p, "EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK", 42) == 0)
+ {
+ DEBUG(D_tls) debug_printf("Supplying known bad OCSP response\n");
+ goto supply_response;
+ }
+ }
return;
}
#endif /*EXPERIMENTAL_OCSP*/
@@ -844,9 +844,10 @@ if(!p)
DEBUG(D_tls) debug_printf(" null\n");
return cbinfo->u_ocsp.client.verify_required ? 0 : 1;
}
-tls_out.ocsp = OCSP_NOT_VFY;
+
if(!(rsp = d2i_OCSP_RESPONSE(NULL, &p, len)))
{
+ tls_out.ocsp = OCSP_FAILED;
if (log_extra_selector & LX_tls_cipher)
log_write(0, LOG_MAIN, "Received TLS status response, parse error");
else
@@ -856,6 +857,7 @@ if(!(rsp = d2i_OCSP_RESPONSE(NULL, &p, len)))
if(!(bs = OCSP_response_get1_basic(rsp)))
{
+ tls_out.ocsp = OCSP_FAILED;
if (log_extra_selector & LX_tls_cipher)
log_write(0, LOG_MAIN, "Received TLS status response, error parsing response");
else
@@ -867,14 +869,12 @@ if(!(bs = OCSP_response_get1_basic(rsp)))
/* We'd check the nonce here if we'd put one in the request. */
/* However that would defeat cacheability on the server so we don't. */
-
/* This section of code reworked from OpenSSL apps source;
The OpenSSL Project retains copyright:
Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*/
{
BIO * bp = NULL;
- OCSP_CERTID *id;
int status, reason;
ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
@@ -888,6 +888,7 @@ if(!(bs = OCSP_response_get1_basic(rsp)))
if ((i = OCSP_basic_verify(bs, NULL,
cbinfo->u_ocsp.client.verify_store, 0)) <= 0)
{
+ tls_out.ocsp = OCSP_FAILED;
BIO_printf(bp, "OCSP response verify failure\n");
ERR_print_errors(bp);
i = cbinfo->u_ocsp.client.verify_required ? 0 : 1;
@@ -902,6 +903,7 @@ if(!(bs = OCSP_response_get1_basic(rsp)))
if (sk_OCSP_SINGLERESP_num(sresp) != 1)
{
+ tls_out.ocsp = OCSP_FAILED;
log_write(0, LOG_MAIN, "OCSP stapling "
"with multiple responses not handled");
i = cbinfo->u_ocsp.client.verify_required ? 0 : 1;
@@ -917,6 +919,7 @@ if(!(bs = OCSP_response_get1_basic(rsp)))
if (!OCSP_check_validity(thisupd, nextupd,
EXIM_OCSP_SKEW_SECONDS, EXIM_OCSP_MAX_AGE))
{
+ tls_out.ocsp = OCSP_FAILED;
DEBUG(D_tls) ERR_print_errors(bp);
log_write(0, LOG_MAIN, "Server OSCP dates invalid");
i = cbinfo->u_ocsp.client.verify_required ? 0 : 1;
@@ -928,10 +931,11 @@ if(!(bs = OCSP_response_get1_basic(rsp)))
switch(status)
{
case V_OCSP_CERTSTATUS_GOOD:
- i = 1;
tls_out.ocsp = OCSP_VFIED;
+ i = 1;
break;
case V_OCSP_CERTSTATUS_REVOKED:
+ tls_out.ocsp = OCSP_FAILED;
log_write(0, LOG_MAIN, "Server certificate revoked%s%s",
reason != -1 ? "; reason: " : "",
reason != -1 ? OCSP_crl_reason_str(reason) : "");
@@ -939,6 +943,7 @@ if(!(bs = OCSP_response_get1_basic(rsp)))
i = cbinfo->u_ocsp.client.verify_required ? 0 : 1;
break;
default:
+ tls_out.ocsp = OCSP_FAILED;
log_write(0, LOG_MAIN,
"Server certificate status unknown, in OCSP stapling");
i = cbinfo->u_ocsp.client.verify_required ? 0 : 1;
diff --git a/src/src/tlscert-gnu.c b/src/src/tlscert-gnu.c
index 32b1986b8..5a4c231bb 100644
--- a/src/src/tlscert-gnu.c
+++ b/src/src/tlscert-gnu.c
@@ -421,6 +421,12 @@ tls_cert_fprt_sha1(void * cert)
return fingerprint((gnutls_x509_crt_t)cert, GNUTLS_DIG_SHA1);
}
+uschar *
+tls_cert_fprt_sha256(void * cert)
+{
+return fingerprint((gnutls_x509_crt_t)cert, GNUTLS_DIG_SHA256);
+}
+
/* vi: aw ai sw=2
*/
diff --git a/src/src/tlscert-openssl.c b/src/src/tlscert-openssl.c
index cddde4cdc..9903f08f3 100644
--- a/src/src/tlscert-openssl.c
+++ b/src/src/tlscert-openssl.c
@@ -81,7 +81,7 @@ X509_free((X509 *)cert);
static uschar *
bio_string_copy(BIO * bp, int len)
{
-uschar * cp = "";
+uschar * cp = US"";
len = len > 0 ? (int) BIO_get_mem_data(bp, &cp) : 0;
cp = string_copyn(cp, len);
BIO_free(bp);
@@ -164,7 +164,7 @@ return cp;
uschar *
tls_cert_signature_algorithm(void * cert, uschar * mod)
{
-return string_copy(OBJ_nid2ln(X509_get_signature_type((X509 *)cert)));
+return string_copy(US OBJ_nid2ln(X509_get_signature_type((X509 *)cert)));
}
uschar *
@@ -182,7 +182,7 @@ return string_sprintf("%d", X509_get_version((X509 *)cert));
uschar *
tls_cert_ext_by_oid(void * cert, uschar * oid, int idx)
{
-int nid = OBJ_create(oid, "", "");
+int nid = OBJ_create(CS oid, "", "");
int nidx = X509_get_ext_by_NID((X509 *)cert, nid, idx);
X509_EXTENSION * ex = X509_get_ext((X509 *)cert, nidx);
ASN1_OCTET_STRING * adata = X509_EXTENSION_get_data(ex);
@@ -201,7 +201,7 @@ cp3 = cp2 = store_get(len*3+1);
while(len)
{
- sprintf(cp2, "%.2x ", *cp1++);
+ sprintf(CS cp2, "%.2x ", *cp1++);
cp2 += 3;
len--;
}
@@ -341,7 +341,7 @@ if (!X509_digest(cert,fdig,md,&n))
return NULL;
}
cp = store_get(n*2+1);
-for (j = 0; j < (int)n; j++) sprintf(cp+2*j, "%02X", md[j]);
+for (j = 0; j < (int)n; j++) sprintf(CS cp+2*j, "%02X", md[j]);
return(cp);
}
@@ -357,6 +357,12 @@ tls_cert_fprt_sha1(void * cert)
return fingerprint((X509 *)cert, EVP_sha1());
}
+uschar *
+tls_cert_fprt_sha256(void * cert)
+{
+return fingerprint((X509 *)cert, EVP_sha256());
+}
+
/* vi: aw ai sw=2
*/
diff --git a/src/src/transport.c b/src/src/transport.c
index 92de4b92b..00b8fa9d8 100644
--- a/src/src/transport.c
+++ b/src/src/transport.c
@@ -837,7 +837,6 @@ internal_transport_write_message(address_item *addr, int fd, int options,
{
int written = 0;
int len;
-header_line *h;
BOOL use_crlf = (options & topt_use_crlf) != 0;
/* Initialize pointer in output buffer. */
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 9089d90c1..020f76cac 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -636,7 +636,7 @@ tpda_defer_errstr = addr->message
? string_sprintf("%s: %s", addr->message, strerror(addr->basic_errno))
: string_copy(addr->message)
: addr->basic_errno > 0
- ? string_copy(strerror(addr->basic_errno))
+ ? string_copy(US strerror(addr->basic_errno))
: NULL;
DEBUG(D_transport)
@@ -1232,6 +1232,7 @@ tls_out.peerdn = NULL;
#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
tls_out.sni = NULL;
#endif
+tls_out.ocsp = OCSP_NOT_REQ;
/* Flip the legacy TLS-related variables over to the outbound set in case
they're used in the context of the transport. Don't bother resetting
@@ -1242,8 +1243,8 @@ tls_modify_variables(&tls_out);
#ifndef SUPPORT_TLS
if (smtps)
{
- set_errno(addrlist, 0, US"TLS support not available", DEFER, FALSE);
- return ERROR;
+ set_errno(addrlist, 0, US"TLS support not available", DEFER, FALSE);
+ return ERROR;
}
#endif
@@ -1475,6 +1476,7 @@ if (tls_offered && !suppress_tls &&
addr->ourcert = tls_out.ourcert;
addr->peercert = tls_out.peercert;
addr->peerdn = tls_out.peerdn;
+ addr->ocsp = tls_out.ocsp;
}
}
}
@@ -2514,6 +2516,7 @@ for (addr = addrlist; addr != NULL; addr = addr->next)
addr->ourcert = NULL;
addr->peercert = NULL;
addr->peerdn = NULL;
+ addr->ocsp = OCSP_NOT_REQ;
#endif
}
return first_addr;
@@ -2916,6 +2919,9 @@ for (cutoff_retry = 0; expired &&
deliver_host = host->name;
deliver_host_address = host->address;
+ lookup_dnssec_authenticated = host->dnssec == DS_YES ? US"yes"
+ : host->dnssec == DS_NO ? US"no"
+ : US"";
/* Set up a string for adding to the retry key if the port number is not
the standard SMTP port. A host may have its own port setting that overrides