* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2016 */
+/* Copyright (c) University of Cambridge 1995 - 2017 */
/* See the file NOTICE for conditions of use and distribution. */
/* Code for handling Access Control Lists (ACLs) */
#ifdef WITH_CONTENT_SCAN
ACLC_SPAM,
#endif
-#ifdef EXPERIMENTAL_SPF
+#ifdef SUPPORT_SPF
ACLC_SPF,
ACLC_SPF_GUESS,
#endif
(1<<ACL_WHERE_NOTSMTP)),
},
#endif
-#ifdef EXPERIMENTAL_SPF
+#ifdef SUPPORT_SPF
[ACLC_SPF] = { US"spf", TRUE, FALSE,
(1<<ACL_WHERE_AUTH)|(1<<ACL_WHERE_CONNECT)|
(1<<ACL_WHERE_HELO)|
compatibility. */
if (c == ACLC_SET)
+#ifndef DISABLE_DKIM
+ if ( Ustrncmp(s, "dkim_verify_status", 18) == 0
+ || Ustrncmp(s, "dkim_verify_reason", 18) == 0)
+ {
+ uschar * endptr = s+18;
+
+ if (isalnum(*endptr))
+ {
+ *error = string_sprintf("invalid variable name after \"set\" in ACL "
+ "modifier \"set %s\" "
+ "(only \"dkim_verify_status\" or \"dkim_verify_reason\" permitted)",
+ s);
+ return NULL;
+ }
+ cond->u.varname = string_copyn(s, 18);
+ s = endptr;
+ while (isspace(*s)) s++;
+ }
+ else
+#endif
{
uschar *endptr;
uschar *
fn_hdrs_added(void)
{
-uschar * ret = NULL;
-int size = 0;
-int ptr = 0;
+gstring * g = NULL;
header_line * h = acl_added_headers;
uschar * s;
uschar * cp;
if (cp[1] == '\0') break;
/* contains embedded newline; needs doubling */
- ret = string_catn(ret, &size, &ptr, s, cp-s+1);
- ret = string_catn(ret, &size, &ptr, US"\n", 1);
+ g = string_catn(g, s, cp-s+1);
+ g = string_catn(g, US"\n", 1);
s = cp+1;
}
/* last bit of header */
- ret = string_catn(ret, &size, &ptr, s, cp-s+1); /* newline-sep list */
+/*XXX could we use add_listele? */
+ g = string_catn(g, s, cp-s+1); /* newline-sep list */
}
while((h = h->next));
-ret[ptr-1] = '\0'; /* overwrite last newline */
-return ret;
+g->s[g->ptr - 1] = '\0'; /* overwrite last newline */
+return g->s;
}
int length = Ustrlen(text) + 1;
log_write(0, LOG_MAIN, "%s", text);
logged = store_malloc(sizeof(string_item) + length);
- logged->text = (uschar *)logged + sizeof(string_item);
+ logged->text = US logged + sizeof(string_item);
memcpy(logged->text, text, length);
logged->next = acl_warn_logged;
acl_warn_logged = logged;
/* Handle name/address consistency verification in a separate function. */
for (vp= verify_type_list;
- (char *)vp < (char *)verify_type_list + sizeof(verify_type_list);
+ CS vp < CS verify_type_list + sizeof(verify_type_list);
vp++
)
if (vp->alt_opt_sep ? strncmpic(ss, vp->name, vp->alt_opt_sep) == 0
: strcmpic (ss, vp->name) == 0)
break;
-if ((char *)vp >= (char *)verify_type_list + sizeof(verify_type_list))
+if (CS vp >= CS verify_type_list + sizeof(verify_type_list))
goto BAD_VERIFY;
if (vp->no_options && slash != NULL)
return csa_return_code[rc];
case VERIFY_HDR_SYNTAX:
- /* Check that all relevant header lines have the correct syntax. If there is
+ /* Check that all relevant header lines have the correct 5322-syntax. If there is
a syntax error, we return details of the error to the sender if configured to
send out full details. (But a "message" setting on the ACL can override, as
always). */
HDEBUG(D_acl)
debug_printf_indent("udpsend [%s]:%d %s\n", h->address, portnum, arg);
+/*XXX this could better use sendto */
r = s = ip_connectedsocket(SOCK_DGRAM, h->address, portnum, portnum,
- 1, NULL, &errstr);
+ 1, NULL, &errstr, NULL);
if (r < 0) goto defer;
len = Ustrlen(arg);
r = send(s, arg, len, 0);
if (cb->type == ACLC_SET)
{
- debug_printf("acl_%s ", cb->u.varname);
- lhswidth += 5 + Ustrlen(cb->u.varname);
+#ifndef DISABLE_DKIM
+ if ( Ustrcmp(cb->u.varname, "dkim_verify_status") == 0
+ || Ustrcmp(cb->u.varname, "dkim_verify_reason") == 0)
+ {
+ debug_printf("%s ", cb->u.varname);
+ lhswidth += 19;
+ }
+ else
+#endif
+ {
+ debug_printf("acl_%s ", cb->u.varname);
+ lhswidth += 5 + Ustrlen(cb->u.varname);
+ }
}
debug_printf("= %s\n", cb->arg);
#ifndef DISABLE_DKIM
case ACLC_DKIM_SIGNER:
- if (dkim_cur_signer != NULL)
+ if (dkim_cur_signer)
rc = match_isinlist(dkim_cur_signer,
&arg,0,NULL,NULL,MCL_STRING,TRUE,NULL);
else
break;
case ACLC_DKIM_STATUS:
- rc = match_isinlist(dkim_exim_expand_query(DKIM_VERIFY_STATUS),
+ rc = match_isinlist(dkim_verify_status,
&arg,0,NULL,NULL,MCL_STRING,TRUE,NULL);
break;
#endif
#endif
case ACLC_QUEUE:
+ if (Ustrchr(arg, '/'))
+ {
+ *log_msgptr = string_sprintf(
+ "Directory separator not permitted in queue name: '%s'", arg);
+ return ERROR;
+ }
queue_name = string_copy_malloc(arg);
break;
{
int old_pool = store_pool;
if ( cb->u.varname[0] == 'c'
+#ifndef DISABLE_DKIM
+ || cb->u.varname[0] == 'd'
+#endif
#ifndef DISABLE_EVENT
|| event_name /* An event is being delivered */
#endif
)
store_pool = POOL_PERM;
- acl_var_create(cb->u.varname)->data.ptr = string_copy(arg);
+#ifndef DISABLE_DKIM /* Overwriteable dkim result variables */
+ if (Ustrcmp(cb->u.varname, "dkim_verify_status") == 0)
+ dkim_verify_status = string_copy(arg);
+ else if (Ustrcmp(cb->u.varname, "dkim_verify_reason") == 0)
+ dkim_verify_reason = string_copy(arg);
+ else
+#endif
+ acl_var_create(cb->u.varname)->data.ptr = string_copy(arg);
store_pool = old_pool;
}
break;
- #ifdef WITH_CONTENT_SCAN
+#ifdef WITH_CONTENT_SCAN
case ACLC_SPAM:
{
/* Separate the regular expression and any optional parameters. */
const uschar * list = arg;
uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
- /* Run the spam backend. */
+
rc = spam(CUSS &ss);
/* Modify return code based upon the existence of options. */
- while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
- != NULL) {
+ while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER)
- {
- /* FAIL so that the message is passed to the next ACL */
- rc = FAIL;
- }
- }
+ rc = FAIL; /* FAIL so that the message is passed to the next ACL */
}
break;
- #endif
+#endif
- #ifdef EXPERIMENTAL_SPF
+#ifdef SUPPORT_SPF
case ACLC_SPF:
rc = spf_process(&arg, sender_address, SPF_PROCESS_NORMAL);
break;
case ACLC_SPF_GUESS:
rc = spf_process(&arg, sender_address, SPF_PROCESS_GUESS);
break;
- #endif
+#endif
case ACLC_UDPSEND:
rc = acl_udpsend(arg, log_msgptr);
}
else ss = s;
-while (isspace(*ss))ss++;
+while (isspace(*ss)) ss++;
/* If we can't find a named ACL, the default is to parse it as an inline one.
(Unless it begins with a slash; non-existent files give rise to an error.) */