X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Facl.c;h=dac2ba570cdeba68efac738be2acb632837ae936;hb=1a44d9d799eb1f94d87ae2cef4ca5b31720ccf88;hp=8fbd2250f7499f08dbd003b2e653c6e4022f94db;hpb=897024f1b30dfde19f8ed9477c49b7cd5a1f5512;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/acl.c b/src/src/acl.c index 8fbd2250f..dac2ba570 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -367,9 +367,6 @@ enum { CONTROL_NO_PIPELINING, CONTROL_QUEUE_ONLY, -#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_REQUIRETLS) - CONTROL_REQUIRETLS, -#endif CONTROL_SUBMISSION, CONTROL_SUPPRESS_LOCAL_FIXUPS, #ifdef SUPPORT_I18N @@ -515,16 +512,6 @@ static control_def controls_list[] = { }, -#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_REQUIRETLS) -[CONTROL_REQUIRETLS] = - { US"requiretls", FALSE, - (unsigned) - ~(ACL_BIT_MAIL | ACL_BIT_RCPT | ACL_BIT_PREDATA | - ACL_BIT_DATA | ACL_BIT_MIME | - ACL_BIT_NOTSMTP) - }, -#endif - [CONTROL_SUBMISSION] = { US"submission", TRUE, (unsigned) @@ -790,7 +777,7 @@ while ((s = (*func)()) != NULL) *error = string_sprintf("malformed ACL line \"%s\"", saveline); return NULL; } - this = store_get(sizeof(acl_block)); + this = store_get(sizeof(acl_block), FALSE); *lastp = this; lastp = &(this->next); this->next = NULL; @@ -837,7 +824,7 @@ while ((s = (*func)()) != NULL) return NULL; } - cond = store_get(sizeof(acl_condition_block)); + cond = store_get(sizeof(acl_condition_block), FALSE); cond->next = NULL; cond->type = c; cond->u.negated = negated; @@ -1035,7 +1022,9 @@ for (p = q; *p; p = q) if (!*hptr) { - header_line *h = store_get(sizeof(header_line)); + /* The header_line struct itself is not tainted, though it points to + tainted data. */ + header_line *h = store_get(sizeof(header_line), FALSE); h->text = hdr; h->next = NULL; h->type = newtype; @@ -1368,7 +1357,7 @@ we return from this function. */ t = tree_search(csa_cache, domain); if (t != NULL) return t->data.val; -t = store_get_perm(sizeof(tree_node) + Ustrlen(domain)); +t = store_get_perm(sizeof(tree_node) + Ustrlen(domain), is_tainted(domain)); Ustrcpy(t->name, domain); (void)tree_insertnode(&csa_cache, t); @@ -1525,7 +1514,7 @@ static verify_type_t verify_type_list[] = { { US"helo", VERIFY_HELO, ~0, TRUE, 0 }, { US"csa", VERIFY_CSA, ~0, FALSE, 0 }, { US"header_syntax", VERIFY_HDR_SYNTAX, ACL_BIT_DATA | ACL_BIT_NOTSMTP, TRUE, 0 }, - { US"not_blind", VERIFY_NOT_BLIND, ACL_BIT_DATA | ACL_BIT_NOTSMTP, TRUE, 0 }, + { US"not_blind", VERIFY_NOT_BLIND, ACL_BIT_DATA | ACL_BIT_NOTSMTP, FALSE, 0 }, { US"header_sender", VERIFY_HDR_SNDR, ACL_BIT_DATA | ACL_BIT_NOTSMTP, FALSE, 0 }, { US"sender", VERIFY_SNDR, ACL_BIT_MAIL | ACL_BIT_RCPT |ACL_BIT_PREDATA | ACL_BIT_DATA | ACL_BIT_NOTSMTP, @@ -1724,14 +1713,27 @@ switch(vp->value) case VERIFY_NOT_BLIND: /* Check that no recipient of this message is "blind", that is, every envelope recipient must be mentioned in either To: or Cc:. */ + { + BOOL case_sensitive = TRUE; + + while ((ss = string_nextinlist(&list, &sep, NULL, 0))) + if (strcmpic(ss, US"case_insensitive") == 0) + case_sensitive = FALSE; + else + { + *log_msgptr = string_sprintf("unknown option \"%s\" in ACL " + "condition \"verify %s\"", ss, arg); + return ERROR; + } - if ((rc = verify_check_notblind()) != OK) + if ((rc = verify_check_notblind(case_sensitive)) != OK) { - *log_msgptr = string_sprintf("bcc recipient detected"); + *log_msgptr = US"bcc recipient detected"; if (smtp_return_error_details) *user_msgptr = string_sprintf("Rejected after DATA: %s", *log_msgptr); } return rc; + } /* The remaining verification tests check recipient and sender addresses, either from the envelope or from the header. There are a number of @@ -2168,10 +2170,10 @@ gstring * g = string_cat(NULL, US"error in arguments to \"ratelimit\" condition: "); va_start(ap, format); -g = string_vformat(g, TRUE, format, ap); +g = string_vformat(g, SVFMT_EXTEND|SVFMT_REBUFFER, format, ap); va_end(ap); -gstring_reset_unused(g); +gstring_release_unused(g); *log_msgptr = string_from_gstring(g); return ERROR; } @@ -2406,7 +2408,7 @@ if ((t = tree_search(*anchor, key))) /* We aren't using a pre-computed rate, so get a previously recorded rate from the database, which will be updated and written back if required. */ -if (!(dbm = dbfn_open(US"ratelimit", O_RDWR, &dbblock, TRUE))) +if (!(dbm = dbfn_open(US"ratelimit", O_RDWR, &dbblock, TRUE, TRUE))) { store_pool = old_pool; sender_rate = NULL; @@ -2455,7 +2457,7 @@ if (!dbdb) /* No Bloom filter. This basic ratelimit block is initialized below. */ HDEBUG(D_acl) debug_printf_indent("ratelimit creating new rate data block\n"); dbdb_size = sizeof(*dbd); - dbdb = store_get(dbdb_size); + dbdb = store_get(dbdb_size, FALSE); /* not tainted */ } else { @@ -2469,7 +2471,7 @@ if (!dbdb) extra = (int)limit * 2 - sizeof(dbdb->bloom); if (extra < 0) extra = 0; dbdb_size = sizeof(*dbdb) + extra; - dbdb = store_get(dbdb_size); + dbdb = store_get(dbdb_size, FALSE); /* not tainted */ dbdb->bloom_epoch = tv.tv_sec; dbdb->bloom_size = sizeof(dbdb->bloom) + extra; memset(dbdb->bloom, 0, dbdb->bloom_size); @@ -2686,9 +2688,10 @@ else dbfn_close(dbm); -/* Store the result in the tree for future reference. */ +/* Store the result in the tree for future reference. Take the taint status +from the key for consistency even though it's unlikely we'll ever expand this. */ -t = store_get(sizeof(tree_node) + Ustrlen(key)); +t = store_get(sizeof(tree_node) + Ustrlen(key), is_tainted(key)); t->data.ptr = dbd; Ustrcpy(t->name, key); (void)tree_insertnode(anchor, t); @@ -2761,7 +2764,7 @@ if (*portend != '\0') } /* Make a single-item host list. */ -h = store_get(sizeof(host_item)); +h = store_get(sizeof(host_item), FALSE); memset(h, 0, sizeof(host_item)); h->name = hostname; h->port = portnum; @@ -3168,11 +3171,6 @@ for (; cb; cb = cb->next) cancel_cutthrough_connection(TRUE, US"queueing forced"); break; -#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_REQUIRETLS) - case CONTROL_REQUIRETLS: - tls_requiretls |= REQUIRETLS_MSG; - break; -#endif case CONTROL_SUBMISSION: originator_name = US""; f.submission_mode = TRUE; @@ -3498,7 +3496,7 @@ for (; cb; cb = cb->next) (sender_host_address == NULL)? US"" : sender_host_address, CUSS &host_data); if (rc == DEFER) *log_msgptr = search_error_message; - if (host_data) host_data = string_copy_malloc(host_data); + if (host_data) host_data = string_copy_perm(host_data, TRUE); break; case ACLC_LOCAL_PARTS: @@ -3600,7 +3598,7 @@ for (; cb; cb = cb->next) "Directory separator not permitted in queue name: '%s'", arg); return ERROR; } - queue_name = string_copy_malloc(arg); + queue_name = string_copy_perm(arg, FALSE); break; case ACLC_RATELIMIT: @@ -4000,13 +3998,20 @@ if (Ustrchr(ss, ' ') == NULL) else if (*ss == '/') { struct stat statbuf; + if (is_tainted(ss)) + { + log_write(0, LOG_MAIN|LOG_PANIC, + "attempt to open tainted ACL file name \"%s\"", ss); + /* Avoid leaking info to an attacker */ + *log_msgptr = US"internal configuration error"; + return ERROR; + } if ((fd = Uopen(ss, O_RDONLY, 0)) < 0) { *log_msgptr = string_sprintf("failed to open ACL file \"%s\": %s", ss, strerror(errno)); return ERROR; } - if (fstat(fd, &statbuf) != 0) { *log_msgptr = string_sprintf("failed to fstat ACL file \"%s\": %s", ss, @@ -4014,7 +4019,8 @@ if (Ustrchr(ss, ' ') == NULL) return ERROR; } - acl_text = store_get(statbuf.st_size + 1); + /* If the string being used as a filename is tainted, so is the file content */ + acl_text = store_get(statbuf.st_size + 1, is_tainted(ss)); acl_text_end = acl_text + statbuf.st_size + 1; if (read(fd, acl_text, statbuf.st_size) != statbuf.st_size) @@ -4044,7 +4050,7 @@ if (!acl) if (!acl && *log_msgptr) return ERROR; if (fd >= 0) { - tree_node *t = store_get_perm(sizeof(tree_node) + Ustrlen(ss)); + tree_node *t = store_get_perm(sizeof(tree_node) + Ustrlen(ss), is_tainted(ss)); Ustrcpy(t->name, ss); t->data.ptr = acl; (void)tree_insertnode(&acl_anchor, t); @@ -4525,7 +4531,7 @@ acl_var_create(uschar * name) tree_node * node, ** root = name[0] == 'c' ? &acl_var_c : &acl_var_m; if (!(node = tree_search(*root, name))) { - node = store_get(sizeof(tree_node) + Ustrlen(name)); + node = store_get(sizeof(tree_node) + Ustrlen(name), is_tainted(name)); Ustrcpy(node->name, name); (void)tree_insertnode(root, node); } @@ -4559,6 +4565,7 @@ void acl_var_write(uschar *name, uschar *value, void *ctx) { FILE *f = (FILE *)ctx; +if (is_tainted(value)) putc('-', f); fprintf(f, "-acl%c %s %d\n%s\n", name[0], name+1, Ustrlen(value), value); }