X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=postlicyd%2Fmatch.c;h=3624be9a8f15d626937d6402186fdb5eaf14dc76;hb=380e4e0ee92811b2edd87f06ad7f0d13e92882d4;hp=1b02cc262125aa499438b22d20b03b166952980d;hpb=60e8a96ef5bd215a3ca40397c17ce06e2ebaf102;p=apps%2Fpfixtools.git diff --git a/postlicyd/match.c b/postlicyd/match.c index 1b02cc2..3624be9 100644 --- a/postlicyd/match.c +++ b/postlicyd/match.c @@ -16,17 +16,20 @@ /* products derived from this software without specific prior written */ /* permission. */ /* */ -/* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND */ -/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE */ -/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ -/* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS */ -/* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR */ -/* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF */ -/* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS */ -/* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN */ -/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) */ -/* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF */ -/* THE POSSIBILITY OF SUCH DAMAGE. */ +/* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS */ +/* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ +/* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY */ +/* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL */ +/* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS */ +/* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) */ +/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, */ +/* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ +/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ +/* POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/* Copyright (c) 2006-2008 the Authors */ +/* see AUTHORS and source files for details */ /******************************************************************************/ /* @@ -49,8 +52,7 @@ typedef struct match_condition_t { MATCH_EMPTY, } condition; - char *value; - ssize_t value_len; + static_str_t value; } match_condition_t; ARRAY(match_condition_t) @@ -63,7 +65,7 @@ static const char *condition_names[] = { "is empty" }; -#define CONDITION_INIT { PTK_UNKNOWN, false, MATCH_UNKNOWN, NULL, 0 } +#define CONDITION_INIT { PTK_UNKNOWN, false, MATCH_UNKNOWN, { NULL, 0 } } typedef struct match_config_t { A(match_condition_t) conditions; @@ -77,8 +79,10 @@ static match_config_t *match_config_new(void) static inline void match_condition_wipe(match_condition_t *condition) { - p_delete(&condition->value); - condition->value_len = 0; + char *str = (char*)condition->value.str; + p_delete(&str); + condition->value.str = NULL; + condition->value.len = 0; } static void match_config_delete(match_config_t **config) @@ -133,7 +137,7 @@ static bool match_filter_constructor(filter_t *filter) condition.field = policy_tokenize(p, n - p); PARSE_CHECK(condition.field >= PTK_HELO_NAME && condition.field < PTK_SMTPD_ACCESS_POLICY, - "invalid field name %.*s", n - p, p); + "invalid field name %.*s", (int)(n - p), p); p = skipspaces(n); n = p + 1; PARSE_CHECK(IS_OP_START(*p) && IS_OP_END(*n), @@ -157,8 +161,8 @@ static bool match_filter_constructor(filter_t *filter) if (condition.condition != MATCH_EMPTY) { p = skipspaces(n + 1); PARSE_CHECK(*p, "no value defined to check the condition"); - condition.value_len = param->value_len - (p - param->value); - condition.value = p_dupstr(p, condition.value_len); + condition.value.len = param->value_len - (p - param->value); + condition.value.str = p_dupstr(p, condition.value.len); } array_add(config->conditions, condition); } break; @@ -182,79 +186,50 @@ static void match_filter_destructor(filter_t *filter) static inline bool match_condition(const match_condition_t *cond, const query_t *query) { - const char *field = NULL; - switch (cond->field) { -#define CASE(Up, Low) \ - case PTK_ ## Up: field = query->Low; break; - CASE(HELO_NAME, helo_name) - CASE(QUEUE_ID, queue_id) - CASE(SENDER, sender) - CASE(SENDER_DOMAIN, sender_domain) - CASE(RECIPIENT, recipient) - CASE(RECIPIENT_DOMAIN, recipient_domain) - CASE(RECIPIENT_COUNT, recipient_count) - CASE(CLIENT_ADDRESS, client_address) - CASE(CLIENT_NAME, client_name) - CASE(REVERSE_CLIENT_NAME, reverse_client_name) - CASE(INSTANCE, instance) - CASE(SASL_METHOD, sasl_method) - CASE(SASL_USERNAME, sasl_username) - CASE(SASL_SENDER, sasl_sender) - CASE(SIZE, size) - CASE(CCERT_SUBJECT, ccert_subject) - CASE(CCERT_ISSUER, ccert_issuer) - CASE(CCERT_FINGERPRINT, ccert_fingerprint) - CASE(ENCRYPTION_PROTOCOL, encryption_protocol) - CASE(ENCRYPTION_CIPHER, encryption_cipher) - CASE(ENCRYPTION_KEYSIZE, encryption_keysize) - CASE(ETRN_DOMAIN, etrn_domain) - CASE(STRESS, stress) -#undef CASE - default: return false; - } + const static_str_t *field = query_field_for_id(query, cond->field); debug("running condition: \"%s\" %s %s\"%s\"", - field, condition_names[cond->condition], + field->str, condition_names[cond->condition], cond->case_sensitive ? "" : "(alternative) ", - cond->value ? cond->value : "(none)"); + cond->value.str ? cond->value.str : "(none)"); switch (cond->condition) { case MATCH_EQUAL: case MATCH_DIFFER: - if (field == NULL) { + if (field == NULL || field->str == NULL) { return cond->condition != MATCH_DIFFER; } if (cond->case_sensitive) { - return !!((strcmp(field, cond->value) == 0) + return !!((strcmp(field->str, cond->value.str) == 0) ^ (cond->condition == MATCH_DIFFER)); } else { - return !!((ascii_strcasecmp(field, cond->value) == 0) + return !!((ascii_strcasecmp(field->str, cond->value.str) == 0) ^ (cond->condition == MATCH_DIFFER)); } break; case MATCH_CONTAINS: - if (field == NULL) { + if (field == NULL || field->str == NULL) { return false; } if (cond->case_sensitive) { - return strstr(field, cond->value); + return strstr(field->str, cond->value.str); } else { - return m_stristrn(field, cond->value, cond->value_len); + return m_stristrn(field->str, cond->value.str, cond->value.len); } break; case MATCH_CONTAINED: - if (field == NULL) { + if (field == NULL || field->str == NULL) { return false; } if (cond->case_sensitive) { - return strstr(cond->value, field); + return strstr(cond->value.str, field->str); } else { - return m_stristr(cond->value, field); + return m_stristr(cond->value.str, field->str); } break; case MATCH_EMPTY: - return !!((field == NULL || *field == '\0') ^ (!cond->case_sensitive)); + return !!((field == NULL || field->len == 0) ^ (!cond->case_sensitive)); default: assert(false && "invalid condition type"); @@ -262,7 +237,8 @@ static inline bool match_condition(const match_condition_t *cond, const query_t return true; } -static filter_result_t match_filter(const filter_t *filter, const query_t *query) +static filter_result_t match_filter(const filter_t *filter, const query_t *query, + filter_context_t *context) { const match_config_t *config = filter->data; foreach (const match_condition_t *condition, config->conditions) { @@ -287,7 +263,8 @@ static filter_result_t match_filter(const filter_t *filter, const query_t *query static int match_init(void) { filter_type_t type = filter_register("match", match_filter_constructor, - match_filter_destructor, match_filter); + match_filter_destructor, match_filter, + NULL, NULL); /* Hooks. */ (void)filter_hook_register(type, "abort");