diff --git a/sieve/tests/address-part.sieve b/sieve/tests/address-part.sieve index cd25bf9851686ccb4480dfab383ef313fb082b79..fbe58b6b5bae85af03065f7778835d16ce60ba2b 100644 --- a/sieve/tests/address-part.sieve +++ b/sieve/tests/address-part.sieve @@ -1,4 +1,4 @@ -if address :comparator "i;ascii-casemap" :localpart "from" "STEPHAN" { +if address :comparator "i;octet" :domain "from" "STEPHAN" { discard; if address :domain :comparator "i;octet" "from" "drunksnipers.com" { diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c index 547d5f35cc37f43bf85183256dacf1c5a00c6c3f..f0f7dabb628cde61a0cbc982011f278323ad658a 100644 --- a/src/lib-sieve/sieve-address-parts.c +++ b/src/lib-sieve/sieve-address-parts.c @@ -2,8 +2,10 @@ #include "lib.h" #include "compat.h" +#include "mempool.h" #include "hash.h" #include "array.h" +#include "message-address.h" #include "sieve-extensions.h" #include "sieve-code.h" @@ -256,6 +258,44 @@ static bool tag_address_part_generate return TRUE; } +/* + * Address Matching + */ + +bool sieve_address_stringlist_match + (struct sieve_address_part *addrp, struct sieve_coded_stringlist *key_list, + struct sieve_comparator *cmp, const char *data) +{ + bool matched = FALSE; + const struct message_address *addr; + + t_push(); + + addr = message_address_parse + (unsafe_data_stack_pool, (const unsigned char *) data, + strlen(data), 256, FALSE); + + while (!matched && addr != NULL) { + if (addr->domain != NULL) { + /* mailbox@domain */ + const char *part; + + i_assert(addr->mailbox != NULL); + + part = addrp->extract_from(addr); + + if ( sieve_stringlist_match(key_list, part, cmp) ) + matched = TRUE; + } + + addr = addr->next; + } + + t_pop(); + + return matched; +} + /* * Core address-part modifiers */ @@ -267,25 +307,46 @@ const struct sieve_argument address_domain_tag = const struct sieve_argument address_all_tag = { "all", tag_address_part_validate, tag_address_part_generate }; +static const char *addrp_all_extract_from + (const struct message_address *address) +{ + return t_strconcat(address->mailbox, "@", address->domain, NULL); +} + +static const char *addrp_domain_extract_from + (const struct message_address *address) +{ + return address->domain; +} + +static const char *addrp_localpart_extract_from + (const struct message_address *address) +{ + return address->mailbox; +} + const struct sieve_address_part all_address_part = { "all", &address_all_tag, SIEVE_ADDRESS_PART_ALL, - NULL + NULL, + addrp_all_extract_from }; const struct sieve_address_part local_address_part = { "localpart", &address_localpart_tag, SIEVE_ADDRESS_PART_LOCAL, - NULL + NULL, + addrp_localpart_extract_from }; const struct sieve_address_part domain_address_part = { "domain", &address_domain_tag, SIEVE_ADDRESS_PART_DOMAIN, - NULL + NULL, + addrp_domain_extract_from }; const struct sieve_address_part *sieve_core_address_parts[] = { diff --git a/src/lib-sieve/sieve-address-parts.h b/src/lib-sieve/sieve-address-parts.h index 233edf1e19c10b7e3a095bd9592c80f75b35ad76..ebc560e0c7d15ad2928922355947cfa1aa65e6e4 100644 --- a/src/lib-sieve/sieve-address-parts.h +++ b/src/lib-sieve/sieve-address-parts.h @@ -1,6 +1,10 @@ #ifndef __SIEVE_ADDRESS_PARTS_H #define __SIEVE_ADDRESS_PARTS_H +#include "message-address.h" + +#include "sieve-common.h" + enum sieve_address_part_code { SIEVE_ADDRESS_PART_ALL, SIEVE_ADDRESS_PART_LOCAL, @@ -14,6 +18,8 @@ struct sieve_address_part { enum sieve_address_part_code code; const struct sieve_extension *extension; + + const char *(*extract_from)(const struct message_address *address); }; void sieve_address_parts_link_tags @@ -38,6 +44,8 @@ const struct sieve_address_part *sieve_opr_address_part_read bool sieve_opr_address_part_dump (struct sieve_binary *sbin, sieve_size_t *address); -void sieve_address_parts_init_registry(struct sieve_interpreter *interp); +bool sieve_address_stringlist_match + (struct sieve_address_part *addrp, struct sieve_coded_stringlist *key_list, + struct sieve_comparator *cmp, const char *data); #endif /* __SIEVE_ADDRESS_PARTS_H */ diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c index 486e9fa9625ab54ffb3112987fb7b6d64d137edc..5e828aece8690547737602c70d5cacb3db9064cd 100644 --- a/src/lib-sieve/tst-address.c +++ b/src/lib-sieve/tst-address.c @@ -188,7 +188,7 @@ static bool tst_address_opcode_execute int i; for ( i = 0; !matched && headers[i] != NULL; i++ ) { - if ( sieve_stringlist_match(key_list, headers[i], cmp) ) + if ( sieve_address_stringlist_match(addrp, key_list, cmp, headers[i]) ) matched = TRUE; } }