X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fsieve.c;h=92cfb608e757d163bedd267a6d068bc63a025b2b;hb=1921d2ea1648c90d45da23f26cf8855465521426;hp=296a23c2d92d10c41c41873429d413e0272c5c2b;hpb=5ea815927da4109ae019a30dac22151c5b988094;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/sieve.c b/src/src/sieve.c index 296a23c2d..92cfb608e 100644 --- a/src/src/sieve.c +++ b/src/src/sieve.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/sieve.c,v 1.12 2005/06/17 10:47:05 ph10 Exp $ */ +/* $Cambridge: exim/src/src/sieve.c,v 1.17 2005/11/28 09:47:20 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -28,10 +28,16 @@ /* Undefine it for UNIX-style \n end-of-line terminators (default). */ #undef RFC_EOL -/* Define this for development of the subaddress Sieve extension. */ +/* Define this for development of the Sieve extension "envelope-auth". */ +#undef ENVELOPE_AUTH + +/* Define this for development of the Sieve extension "notify". */ +#undef NOTIFY + +/* Define this for the Sieve extension "subaddress". */ #define SUBADDRESS -/* Define this for the vacation Sieve extension. */ +/* Define this for the Sieve extension "vacation". */ #define VACATION /* Must be >= 1 */ @@ -52,6 +58,12 @@ struct Sieve int keep; int require_envelope; int require_fileinto; +#ifdef ENVELOPE_AUTH + int require_envelope_auth; +#endif +#ifdef NOTIFY + int require_notify; +#endif #ifdef SUBADDRESS int require_subaddress; #endif @@ -92,6 +104,8 @@ static uschar str_cc_c[]="Cc"; static const struct String str_cc={ str_cc_c, 2 }; static uschar str_bcc_c[]="Bcc"; static const struct String str_bcc={ str_bcc_c, 3 }; +static uschar str_auth_c[]="auth"; +static const struct String str_auth={ str_auth_c, 4 }; static uschar str_sender_c[]="Sender"; static const struct String str_sender={ str_sender_c, 6 }; static uschar str_resent_from_c[]="Resent-From"; @@ -102,6 +116,14 @@ static uschar str_fileinto_c[]="fileinto"; static const struct String str_fileinto={ str_fileinto_c, 8 }; static uschar str_envelope_c[]="envelope"; static const struct String str_envelope={ str_envelope_c, 8 }; +#ifdef ENVELOPE_AUTH +static uschar str_envelope_auth_c[]="envelope-auth"; +static const struct String str_envelope_auth={ str_envelope_auth_c, 13 }; +#endif +#ifdef NOTIFY +static uschar str_notify_c[]="notify"; +static const struct String str_notify={ str_notify_c, 6 }; +#endif #ifdef SUBADDRESS static uschar str_subaddress_c[]="subaddress"; static const struct String str_subaddress={ str_subaddress_c, 10 }; @@ -311,8 +333,7 @@ while (nl>0 && hl>0) if (hc&0x80) return 0; #endif /* tolower depends on the locale and only ASCII case must be insensitive */ - if ((nc&0x80) || (hc&0x80)) { if (nc!=hc) return 0; } - else if ((nc>='A' && nc<='Z' ? nc|0x20 : nc) != (hc>='A' && hc<='Z' ? hc|0x20 : hc)) return 0; + if ((nc>='A' && nc<='Z' ? nc|0x20 : nc) != (hc>='A' && hc<='Z' ? hc|0x20 : hc)) return 0; ++n; ++h; --nl; @@ -323,7 +344,7 @@ return (match_prefix ? nl==0 : nl==0 && hl==0); /************************************************* -* Octet-wise glob pattern search * +* Glob pattern search * *************************************************/ /* @@ -333,231 +354,99 @@ Arguments: Returns: 0 needle not found in haystack 1 needle found + -1 pattern error */ -static int eq_octetglob(const struct String *needle, - const struct String *haystack) +static int eq_glob(const struct String *needle, + const struct String *haystack, int ascii_caseless) { -struct String n,h; +const uschar *n,*h,*nend,*hend; +int may_advance=0; -n=*needle; -h=*haystack; -while (n.length) +n=needle->character; +h=haystack->character; +nend=n+needle->length; +hend=h+haystack->length; +while (n='A' && *npart<='Z' ? *npart|0x20 : *npart) != (*hpart>='A' && *hpart<='Z' ? *hpart|0x20 : *hpart)) + : *hpart!=*npart + ) { - while (h.length && (h.character[0]&0x80)) + if (may_advance) + /* string match after a star failed, advance and try again */ { - ++h.character; - --h.length; + ++h; + goto match_part; } + else return 0; } else { - ++h.character; - --h.length; - } + ++npart; + ++hpart; + }; } - else return 0; - break; } - case '\\': + /* at this point, a part was matched successfully */ + if (may_advance && npart==nend && hpart='A' && nc<='Z' ? nc|0x20 : nc) != (hc>='A' && hc<='Z' ? hc|0x20 : hc)) return 0; - ++h.character; - --h.length; - ++n.character; - --n.length; + ++h; + goto match_part; } + h=hpart; + n=npart; + may_advance=0; } } -return (h.length==0); +return (h==hend ? 1 : may_advance); } @@ -715,12 +604,20 @@ switch (mt) { case COMP_OCTET: { - if (eq_octetglob(needle,haystack)) r=1; + if ((r=eq_glob(needle,haystack,0))==-1) + { + filter->errmsg=CUS "syntactically invalid pattern"; + return -1; + } break; } case COMP_EN_ASCII_CASEMAP: { - if (eq_asciicaseglob(needle,haystack)) r=1; + if ((r=eq_glob(needle,haystack,1))==-1) + { + filter->errmsg=CUS "syntactically invalid pattern"; + return -1; + } break; } default: @@ -915,7 +812,7 @@ while (*r) *t++=*r++; } *t++='\0'; -value->character=rfc2047_decode(s,TRUE,US"utf-8",'\0',&value->length,&errmsg); +value->character=rfc2047_decode(s,check_rfc2047_length,US"utf-8",'\0',&value->length,&errmsg); } @@ -1949,6 +1846,9 @@ else if (parse_identifier(filter,CUS "envelope")) envelope-part is case insensitive "from" or "to" +#ifdef ENVELOPE_AUTH + envelope-part =/ "auth" +#endif */ enum Comparator comparator=COMP_EN_ASCII_CASEMAP; @@ -2011,7 +1911,7 @@ else if (parse_identifier(filter,CUS "envelope")) return -1; } *cond=0; - for (e=env; e->character; ++e) + for (e=env; e->length!=-1 && !*cond; ++e) { const uschar *envelopeExpr=CUS 0; uschar *envelope=US 0; @@ -2044,6 +1944,23 @@ else if (parse_identifier(filter,CUS "envelope")) case ADDRPART_DOMAIN: envelopeExpr=CUS "$domain"; break; } } +#ifdef ENVELOPE_AUTH + else if (eq_asciicase(e,&str_auth,0)) + { + switch (addressPart) + { + case ADDRPART_ALL: envelopeExpr=CUS "$authenticated_sender"; break; +#ifdef SUBADDRESS + case ADDRPART_USER: +#endif + case ADDRPART_LOCALPART: envelopeExpr=CUS "${local_part:$authenticated_sender}"; break; + case ADDRPART_DOMAIN: envelopeExpr=CUS "${domain:$authenticated_sender}"; break; +#ifdef SUBADDRESS + case ADDRPART_DETAIL: envelopeExpr=CUS 0; break; +#endif + } + } +#endif else { filter->errmsg=CUS "invalid envelope string"; @@ -2179,6 +2096,11 @@ while (*filter->pc) filter->errmsg=CUS "missing test"; return -1; } + if ((filter_test != FTEST_NONE && debug_selector != 0) || + (debug_selector & D_filter) != 0) + { + if (exec) debug_printf("if %s\n",cond?"true":"false"); + } m=parse_block(filter,exec ? cond : 0, generated); if (m==-1 || m==2) return m; if (m==0) @@ -2200,6 +2122,11 @@ while (*filter->pc) filter->errmsg=CUS "missing test"; return -1; } + if ((filter_test != FTEST_NONE && debug_selector != 0) || + (debug_selector & D_filter) != 0) + { + if (exec) debug_printf("elsif %s\n",cond?"true":"false"); + } m=parse_block(filter,exec && unsuccessful ? cond : 0, generated); if (m==-1 || m==2) return m; if (m==0) @@ -2312,7 +2239,7 @@ while (*filter->pc) fileinto-command = "fileinto" { fileinto-options } string ";" fileinto-options = fileinto-options =) [ ":copy" ] - */ + */ struct String folder; uschar *s; @@ -2366,6 +2293,54 @@ while (*filter->pc) } if (parse_semicolon(filter)==-1) return -1; } +#ifdef NOTIFY + else if (parse_identifier(filter,CUS "notify")) + { + /* + notify-command = "notify" { notify-options } ";" + notify-options = [":method" string] + [":message" string] + */ + + int m; + struct String method; + struct String message; + + if (!filter->require_notify) + { + filter->errmsg=CUS "missing previous require \"notify\";"; + return -1; + } + method.character=(uschar*)0; + method.length=-1; + message.character=(uschar*)0; + message.length=-1; + for (;;) + { + if (parse_white(filter)==-1) return -1; + if (parse_identifier(filter,CUS ":method")==1) + { + if (parse_white(filter)==-1) return -1; + if ((m=parse_string(filter,&method))!=1) + { + if (m==0) filter->errmsg=CUS "method string expected"; + return -1; + } + } + else if (parse_identifier(filter,CUS ":message")==1) + { + if (parse_white(filter)==-1) return -1; + if ((m=parse_string(filter,&message))!=1) + { + if (m==0) filter->errmsg=CUS "message string expected"; + return -1; + } + } + else break; + } + if (parse_semicolon(filter)==-1) return -1; + } +#endif #ifdef VACATION else if (parse_identifier(filter,CUS "vacation")) { @@ -2673,6 +2648,12 @@ filter->line=1; filter->keep=1; filter->require_envelope=0; filter->require_fileinto=0; +#ifdef ENVELOPE_AUTH +filter->require_envelope_auth=0; +#endif +#ifdef NOTIFY +filter->require_notify=0; +#endif #ifdef SUBADDRESS filter->require_subaddress=0; #endif @@ -2738,6 +2719,12 @@ while (parse_identifier(filter,CUS "require")) { if (eq_octet(check,&str_envelope,0)) filter->require_envelope=1; else if (eq_octet(check,&str_fileinto,0)) filter->require_fileinto=1; +#ifdef ENVELOPE_AUTH + else if (eq_octet(check,&str_envelope_auth,0)) filter->require_envelope_auth=1; +#endif +#ifdef NOTIFY + else if (eq_octet(check,&str_notify,0)) filter->require_notify=1; +#endif #ifdef SUBADDRESS else if (eq_octet(check,&str_subaddress,0)) filter->require_subaddress=1; #endif @@ -2838,12 +2825,12 @@ if (parse_start(&sieve,1,generated)==1) if (sieve.keep) { add_addr(generated,US"inbox",1,0,0,0); - msg = string_sprintf("Keep"); + msg = string_sprintf("Implicit keep"); r = FF_DELIVERED; } - else + else { - msg = string_sprintf("No keep"); + msg = string_sprintf("No implicit keep"); r = FF_DELIVERED; } }