X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/87fcc8b991cb2c6fb33e78593230685d104c6800..d2ee61144850b8e20cbf9017e94e2184e33fc0f6:/src/src/sieve.c diff --git a/src/src/sieve.c b/src/src/sieve.c index b8ade713b..a1a7b8883 100644 --- a/src/src/sieve.c +++ b/src/src/sieve.c @@ -1,10 +1,10 @@ -/* $Cambridge: exim/src/src/sieve.c,v 1.14 2005/11/14 11:41:23 ph10 Exp $ */ +/* $Cambridge: exim/src/src/sieve.c,v 1.25 2007/03/13 10:05:17 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) Michael Haardt 2003-2005 */ +/* Copyright (c) Michael Haardt 2003-2006 */ /* See the file NOTICE for conditions of use and distribution. */ /* This code was contributed by Michael Haardt. */ @@ -28,8 +28,11 @@ /* Undefine it for UNIX-style \n end-of-line terminators (default). */ #undef RFC_EOL -/* Define this for development of the Sieve extension "notify". */ -#undef NOTIFY +/* Define this for development of the Sieve extension "envelope-auth". */ +#undef ENVELOPE_AUTH + +/* Define this for development of the Sieve extension "enotify". */ +#undef ENOTIFY /* Define this for the Sieve extension "subaddress". */ #define SUBADDRESS @@ -55,8 +58,12 @@ struct Sieve int keep; int require_envelope; int require_fileinto; -#ifdef NOTIFY - int require_notify; +#ifdef ENVELOPE_AUTH + int require_envelope_auth; +#endif +#ifdef ENOTIFY + int require_enotify; + struct Notification *notified; #endif #ifdef SUBADDRESS int require_subaddress; @@ -87,6 +94,15 @@ struct String int length; }; +struct Notification + { + struct String method; + struct String importance; + struct String message; + struct Notification *next; + }; + +static int eq_asciicase(const struct String *needle, const struct String *haystack, int match_prefix); static int parse_test(struct Sieve *filter, int *cond, int exec); static int parse_commands(struct Sieve *filter, int exec, address_item **generated); @@ -98,6 +114,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"; @@ -108,9 +126,13 @@ 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 NOTIFY -static uschar str_notify_c[]="notify"; -static const struct String str_notify={ str_notify_c, 6 }; +#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 ENOTIFY +static uschar str_enotify_c[]="enotify"; +static const struct String str_enotify={ str_enotify_c, 7 }; #endif #ifdef SUBADDRESS static uschar str_subaddress_c[]="subaddress"; @@ -149,6 +171,10 @@ static const struct String str_comparator_iascii_numeric={ str_comparator_iascii /* Arguments: src UTF-8 string + dst US-ASCII string + +Returns + dst */ static struct String *quoted_printable_encode(const struct String *src, struct String *dst) @@ -190,13 +216,8 @@ for (pass=0; pass<=1; ++pass) || ( (ch==9 || ch==32) -#ifdef RFC_EOL && start+2length; line=0; - ++start; } else *new++='\n'; line=0; + ++start; } -#else - else if (ch=='\n') - { - if (pass==0) - ++dst->length; - else - *new++=*start; - ++line; - } -#endif else { if (pass==0) @@ -247,6 +257,250 @@ for (pass=0; pass<=1; ++pass) } +/************************************************* +* Check mail address for correct syntax * +*************************************************/ + +/* +Check mail address for being syntactically correct. + +Arguments: + filter points to the Sieve filter including its state + address String containing one address + +Returns + 1 Mail address is syntactically OK + -1 syntax error +*/ + +int check_mail_address(struct Sieve *filter, const struct String *address) +{ +int start, end, domain; +uschar *error,*ss; + +if (address->length>0) + { + ss = parse_extract_address(address->character, &error, &start, &end, &domain, + FALSE); + if (ss == NULL) + { + filter->errmsg=string_sprintf("malformed address \"%s\" (%s)", + address->character, error); + return -1; + } + else + return 1; + } +else + { + filter->errmsg=CUS "empty address"; + return -1; + } +} + + +/************************************************* +* Decode URI encoded string * +*************************************************/ + +/* +Arguments: + str URI encoded string + +Returns + 0 Decoding successful + -1 Encoding error +*/ + +#ifdef ENOTIFY +static int uri_decode(struct String *str) +{ +uschar *s,*t,*e; + +if (str->length==0) return 0; +for (s=str->character,t=s,e=s+str->length; slength=t-str->character; +return 0; +} + + +/************************************************* +* Parse mailto URI * +*************************************************/ + +/* +Parse mailto-URI. + + mailtoURI = "mailto:" [ to ] [ headers ] + to = [ addr-spec *("%2C" addr-spec ) ] + headers = "?" header *( "&" header ) + header = hname "=" hvalue + hname = *urlc + hvalue = *urlc + +Arguments: + filter points to the Sieve filter including its state + uri URI, excluding scheme + recipient + body + +Returns + 1 URI is syntactically OK + 0 Unknown URI scheme + -1 syntax error +*/ + +static int parse_mailto_uri(struct Sieve *filter, const uschar *uri, string_item **recipient, struct String *header, struct String *body) +{ +const uschar *start; +struct String to,hname,hvalue; +int capacity; +string_item *new; + +if (Ustrncmp(uri,"mailto:",7)) + { + filter->errmsg=US "Unknown URI scheme"; + return 0; + } +uri+=7; +if (*uri && *uri!='?') + for (;;) + { + /* match to */ + for (start=uri; *uri && *uri!='?' && (*uri!='%' || *(uri+1)!='2' || tolower(*(uri+2))!='c'); ++uri); + if (uri>start) + { + capacity=0; + to.character=(uschar*)0; + to.length=0; + to.character=string_cat(to.character,&capacity,&to.length,start,uri-start); + to.character[to.length]='\0'; + if (uri_decode(&to)==-1) + { + filter->errmsg=US"Invalid URI encoding"; + return -1; + } + new=store_get(sizeof(string_item)); + new->text=store_get(to.length+1); + if (to.length) memcpy(new->text,to.character,to.length); + new->text[to.length]='\0'; + new->next=*recipient; + *recipient=new; + } + else + { + filter->errmsg=US"Missing addr-spec in URI"; + return -1; + } + if (*uri=='%') uri+=3; + else break; + } +if (*uri=='?') + { + ++uri; + for (;;) + { + /* match hname */ + for (start=uri; *uri && (isalnum(*uri) || strchr("$-_.+!*'(),%",*uri)); ++uri); + if (uri>start) + { + capacity=0; + hname.character=(uschar*)0; + hname.length=0; + hname.character=string_cat(hname.character,&capacity,&hname.length,start,uri-start); + hname.character[hname.length]='\0'; + if (uri_decode(&hname)==-1) + { + filter->errmsg=US"Invalid URI encoding"; + return -1; + } + } + /* match = */ + if (*uri=='=') + ++uri; + else + { + filter->errmsg=US"Missing equal after hname"; + return -1; + } + /* match hvalue */ + for (start=uri; *uri && (isalnum(*uri) || strchr("$-_.+!*'(),%",*uri)); ++uri); + if (uri>start) + { + capacity=0; + hvalue.character=(uschar*)0; + hvalue.length=0; + hvalue.character=string_cat(hvalue.character,&capacity,&hvalue.length,start,uri-start); + hvalue.character[hvalue.length]='\0'; + if (uri_decode(&hvalue)==-1) + { + filter->errmsg=US"Invalid URI encoding"; + return -1; + } + } + if (hname.length==2 && strcmpic(hname.character, US"to")==0) + { + new=store_get(sizeof(string_item)); + new->text=store_get(hvalue.length+1); + if (hvalue.length) memcpy(new->text,hvalue.character,hvalue.length); + new->text[hvalue.length]='\0'; + new->next=*recipient; + *recipient=new; + } + else if (hname.length==4 && strcmpic(hname.character, US"body")==0) + *body=hvalue; + else + { + static struct String ignore[]= + { + {US"from",4}, + {US"subject",7}, + {US"received",8} + }; + static struct String *end=ignore+sizeof(ignore)/sizeof(ignore[0]); + struct String *i; + + for (i=ignore; ilength==-1) header->length=0; + capacity=header->length; + header->character=string_cat(header->character,&capacity,&header->length,hname.character,hname.length); + header->character=string_cat(header->character,&capacity,&header->length,CUS ": ",2); + header->character=string_cat(header->character,&capacity,&header->length,hvalue.character,hvalue.length); + header->character=string_cat(header->character,&capacity,&header->length,CUS "\n",1); + header->character[header->length]='\0'; + } + } + if (*uri=='&') ++uri; + else break; + } + } +if (*uri) + { + filter->errmsg=US"Syntactically invalid URI"; + return -1; + } +return 1; +} +#endif + + /************************************************* * Octet-wise string comparison * *************************************************/ @@ -346,7 +600,7 @@ Returns: 0 needle not found in haystack */ static int eq_glob(const struct String *needle, - const struct String *haystack, int ascii_caseless) + const struct String *haystack, int ascii_caseless, int match_octet) { const uschar *n,*h,*nend,*hend; int may_advance=0; @@ -376,14 +630,19 @@ while (nerrmsg=CUS "syntactically invalid pattern"; return -1; @@ -601,7 +861,7 @@ switch (mt) } case COMP_EN_ASCII_CASEMAP: { - if ((r=eq_glob(needle,haystack,1))==-1) + if ((r=eq_glob(needle,haystack,1,1))==-1) { filter->errmsg=CUS "syntactically invalid pattern"; return -1; @@ -770,6 +1030,10 @@ new_addr->next = *generated; *************************************************/ /* +Unfold the header field as described in RFC 2822 and remove all +leading and trailing white space, then perform MIME decoding and +translate the header field to UTF-8. + Arguments: value returned value of the field header name of the header field @@ -787,20 +1051,17 @@ value->length=0; value->character=(uschar*)0; t=r=s=expand_string(string_sprintf("$rheader_%s",quote(header))); -while (*r==' ') ++r; +while (*r==' ' || *r=='\t') ++r; while (*r) { if (*r=='\n') - { ++r; - while (*r==' ' || *r=='\t') ++r; - if (*r) *t++=' '; - } else *t++=*r++; } -*t++='\0'; -value->character=rfc2047_decode(s,TRUE,US"utf-8",'\0',&value->length,&errmsg); +while (t>s && (*(t-1)==' ' || *(t-1)=='\t')) --t; +*t='\0'; +value->character=rfc2047_decode(s,check_rfc2047_length,US"utf-8",'\0',&value->length,&errmsg); } @@ -970,6 +1231,7 @@ if (*filter->pc=='"') /* quoted string */ int foo=data->length; ++filter->pc; + /* that way, there will be at least one character allocated */ data->character=string_cat(data->character,&dataCapacity,&foo,CUS "",1); return 1; } @@ -981,6 +1243,15 @@ if (*filter->pc=='"') /* quoted string */ } else /* regular character */ { +#ifdef RFC_EOL + if (*filter->pc=='\r' && *(filter->pc+1)=='\n') ++filter->line; +#else + if (*filter->pc=='\n') + { + data->character=string_cat(data->character,&dataCapacity,&data->length,US"\r",1); + ++filter->line; + } +#endif data->character=string_cat(data->character,&dataCapacity,&data->length,filter->pc,1); filter->pc++; } @@ -1036,7 +1307,10 @@ else if (Ustrncmp(filter->pc,CUS "text:",5)==0) /* multiline string */ if (*filter->pc=='.' && *(filter->pc+1)=='\n') /* end of string */ #endif { - data->character=string_cat(data->character,&dataCapacity,&data->length,CUS "",1); + int foo=data->length; + + /* that way, there will be at least one character allocated */ + data->character=string_cat(data->character,&dataCapacity,&foo,CUS "",1); #ifdef RFC_EOL filter->pc+=3; #else @@ -1630,6 +1904,8 @@ if (parse_identifier(filter,CUS "address")) if (saveend == 0) break; header_value = end_addr + 1; } + parse_allow_group = FALSE; + parse_found_group = FALSE; } } return 1; @@ -1834,6 +2110,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; @@ -1929,6 +2208,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"; @@ -1955,6 +2251,48 @@ else if (parse_identifier(filter,CUS "envelope")) } return 1; } +#ifdef ENOTIFY +else if (parse_identifier(filter,CUS "valid_notif_method")) + { + /* + valid_notif_method = "valid_notif_method" + + */ + + struct String *uris,*u; + int m; + + if (!filter->require_enotify) + { + filter->errmsg=CUS "missing previous require \"enotify\";"; + return -1; + } + if (parse_white(filter)==-1) return -1; + if ((m=parse_stringlist(filter,&uris))!=1) + { + if (m==0) filter->errmsg=CUS "URI string list expected"; + return -1; + } + if (exec) + { + *cond=1; + for (u=uris; u->length!=-1 && *cond; ++u) + { + string_item *recipient; + struct String header,body; + + recipient=NULL; + header.length=-1; + header.character=(uschar*)0; + body.length=-1; + body.character=(uschar*)0; + if (parse_mailto_uri(filter,u->character,&recipient,&header,&body)!=1) + *cond=0; + } + } + return 1; + } +#endif else return 0; } @@ -2261,40 +2599,78 @@ while (*filter->pc) } if (parse_semicolon(filter)==-1) return -1; } -#ifdef NOTIFY +#ifdef ENOTIFY else if (parse_identifier(filter,CUS "notify")) { /* - notify-command = "notify" { notify-options } ";" - notify-options = [":method" string] + notify-command = "notify" { notify-options } ";" + notify-options = [":from" string] + [":importance" <"1" / "2" / "3">] + [":options" 1*(string-list / number)] [":message" string] */ int m; - struct String method; + struct String from; + struct String importance; + struct String *options; struct String message; + struct String method; + struct Notification *already; + string_item *recipient; + struct String header; + struct String body; + uschar *envelope_from,*envelope_to; - if (!filter->require_notify) + if (!filter->require_enotify) { - filter->errmsg=CUS "missing previous require \"notify\";"; + filter->errmsg=CUS "missing previous require \"enotify\";"; return -1; } - method.character=(uschar*)0; - method.length=-1; + from.character=(uschar*)0; + from.length=-1; + importance.character=(uschar*)0; + importance.length=-1; + options=(struct String*)0; message.character=(uschar*)0; message.length=-1; + recipient=NULL; + header.length=-1; + header.character=(uschar*)0; + body.length=-1; + body.character=(uschar*)0; + envelope_from=expand_string("$sender_address"); + envelope_to=expand_string("$local_part_prefix$local_part$local_part_suffix@$domain"); for (;;) { if (parse_white(filter)==-1) return -1; - if (parse_identifier(filter,CUS ":method")==1) + if (parse_identifier(filter,CUS ":from")==1) + { + if (parse_white(filter)==-1) return -1; + if ((m=parse_string(filter,&from))!=1) + { + if (m==0) filter->errmsg=CUS "from string expected"; + return -1; + } + } + else if (parse_identifier(filter,CUS ":importance")==1) { if (parse_white(filter)==-1) return -1; - if ((m=parse_string(filter,&method))!=1) + if ((m=parse_string(filter,&importance))!=1) + { + if (m==0) filter->errmsg=CUS "importance string expected"; + return -1; + } + if (importance.length!=1 || importance.character[0]<'1' || importance.character[0]>'3') { - if (m==0) filter->errmsg=CUS "method string expected"; + filter->errmsg=CUS "invalid importance"; return -1; } } + else if (parse_identifier(filter,CUS ":options")==1) + { + if (parse_white(filter)==-1) return -1; + } else if (parse_identifier(filter,CUS ":message")==1) { if (parse_white(filter)==-1) return -1; @@ -2306,7 +2682,83 @@ while (*filter->pc) } else break; } + if (parse_white(filter)==-1) return -1; + if ((m=parse_string(filter,&method))!=1) + { + if (m==0) filter->errmsg=CUS "missing method string"; + return -1; + } if (parse_semicolon(filter)==-1) return -1; + + for (already=filter->notified; already; already=already->next) + { + if (already->method.length==method.length + && (method.length==-1 || strcmp(already->method.character,method.character)==0) + && already->importance.length==importance.length + && (importance.length==-1 || strcmp(already->importance.character,importance.character)==0) + && already->message.length==message.length + && (message.length==-1 || strcmp(already->message.character,message.character)==0)) + break; + } + if (already==(struct Notification*)0) + /* New notification, process it */ + { + if (parse_mailto_uri(filter,method.character,&recipient,&header,&body)!=1) + return -1; + struct Notification *sent; + sent=store_get(sizeof(struct Notification)); + sent->method=method; + sent->importance=importance; + sent->message=message; + sent->next=filter->notified; + filter->notified=sent; + if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0) + { + debug_printf("Notification to `%s'.\n",method.character); + } +#ifndef COMPILE_SYNTAX_CHECKER + if (exec && filter_test == FTEST_NONE) + { + string_item *p; + header_line *h; + int pid,fd; + + if ((pid = child_open_exim2(&fd,envelope_to,envelope_to))>=1) + { + FILE *f; + uschar *buffer; + int buffer_capacity; + + f = fdopen(fd, "wb"); + for (h = header_list; h != NULL; h = h->next) + if (h->type == htype_received) fprintf(f,"%s",h->text); + fprintf(f,"From: %s\n",from.length==-1 ? envelope_to : from.character); + for (p=recipient; p; p=p->next) fprintf(f,"To: %s\n",p->text); + if (header.length>0) fprintf(f,"%s",header.character); + if (message.length==-1) + { + message.character=US"Notification"; + message.length=Ustrlen(message.character); + } + /* Allocation is larger than neccessary, but enough even for split MIME words */ + buffer_capacity=32+4*message.length; + buffer=store_get(buffer_capacity); + fprintf(f,"Subject: %s\n\n",parse_quote_2047(message.character, message.length, US"utf-8", buffer, buffer_capacity, TRUE)); + if (body.length>0) fprintf(f,"%s\n",body.character); + fflush(f); + (void)fclose(f); + (void)child_close(pid, 0); + } + } +#endif + } + else + { + if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0) + { + debug_printf("Repeated notification to `%s' ignored.\n",method.character); + } + } } #endif #ifdef VACATION @@ -2377,31 +2829,14 @@ while (*filter->pc) } else if (parse_identifier(filter,CUS ":from")==1) { - int start, end, domain; - uschar *error,*ss; - if (parse_white(filter)==-1) return -1; if ((m=parse_string(filter,&from))!=1) { if (m==0) filter->errmsg=CUS "from string expected"; return -1; } - if (from.length>0) - { - ss = parse_extract_address(from.character, &error, &start, &end, &domain, - FALSE); - if (ss == NULL) - { - filter->errmsg=string_sprintf("malformed address \"%s\" in " - "Sieve filter: %s", from.character, error); - return -1; - } - } - else - { - filter->errmsg=CUS "empty :from address in Sieve filter"; + if (check_mail_address(filter,&from)!=1) return -1; - } } else if (parse_identifier(filter,CUS ":addresses")==1) { @@ -2495,11 +2930,11 @@ while (*filter->pc) md5_start(&base); md5_end(&base, key.character, key.length, digest); for (i = 0; i < 16; i++) sprintf(CS (hexdigest+2*i), "%02X", digest[i]); - if (filter_test != FTEST_NONE) + if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0) { debug_printf("Sieve: mail was personal, vacation file basename: %s\n", hexdigest); } - else + if (filter_test == FTEST_NONE) { capacity=Ustrlen(filter->vacation_directory); start=capacity; @@ -2511,11 +2946,22 @@ while (*filter->pc) if (subject.length==-1) { - expand_header(&subject,&str_subject); - capacity=6; - start=6; - subject.character=string_cat(US"Auto: ",&capacity,&start,subject.character,subject.length); - subject.length=start; + uschar *subject_def; + + subject_def=expand_string(US"${if def:header_subject {true}{false}}"); + if (Ustrcmp(subject_def,"true")==0) + { + expand_header(&subject,&str_subject); + capacity=6; + start=6; + subject.character=string_cat(US"Auto: ",&capacity,&start,subject.character,subject.length); + subject.length=start; + } + else + { + subject.character=US"Automated reply"; + subject.length=Ustrlen(subject.character); + } } /* add address to list of generated addresses */ @@ -2533,9 +2979,9 @@ while (*filter->pc) else addr->reply->from = from.character; /* Allocation is larger than neccessary, but enough even for split MIME words */ - buffer_capacity=16+4*subject.length; + buffer_capacity=32+4*subject.length; buffer=store_get(buffer_capacity); - addr->reply->subject=parse_quote_2047(subject.character, subject.length, US"utf-8", buffer, buffer_capacity); + addr->reply->subject=parse_quote_2047(subject.character, subject.length, US"utf-8", buffer, buffer_capacity, TRUE); addr->reply->oncelog=once; addr->reply->once_repeat=days*86400; @@ -2544,16 +2990,12 @@ while (*filter->pc) if (reason_is_mime) { uschar *mime_body,*reason_end; -#ifdef RFC_EOL static const uschar nlnl[]="\r\n\r\n"; -#else - static const uschar nlnl[]="\n\n"; -#endif for ( mime_body=reason.character,reason_end=reason.character+reason.length; - mime_body<(reason_end-sizeof(nlnl)-1) && memcmp(mime_body,nlnl,sizeof(nlnl)-1); + mime_body<(reason_end-(sizeof(nlnl)-1)) && memcmp(mime_body,nlnl,(sizeof(nlnl)-1)); ++mime_body ); capacity = 0; @@ -2562,14 +3004,14 @@ while (*filter->pc) addr->reply->headers[start] = '\0'; capacity = 0; start = 0; - if (mime_body+(sizeof(nlnl)-1)reply->text = string_cat(NULL,&capacity,&start,mime_body,reason_end-mime_body); addr->reply->text[start] = '\0'; } else { - struct String qp; + struct String qp = { NULL, 0 }; /* Keep compiler happy (PH) */ capacity = 0; start = reason.length; @@ -2581,7 +3023,7 @@ while (*filter->pc) } } } - else if (filter_test != FTEST_NONE) + else if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0) { debug_printf("Sieve: mail was not personal, vacation would ignore it\n"); } @@ -2616,8 +3058,12 @@ filter->line=1; filter->keep=1; filter->require_envelope=0; filter->require_fileinto=0; -#ifdef NOTIFY -filter->require_notify=0; +#ifdef ENVELOPE_AUTH +filter->require_envelope_auth=0; +#endif +#ifdef ENOTIFY +filter->require_enotify=0; +filter->notified=(struct Notification*)0; #endif #ifdef SUBADDRESS filter->require_subaddress=0; @@ -2684,8 +3130,11 @@ 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 NOTIFY - else if (eq_octet(check,&str_notify,0)) filter->require_notify=1; +#ifdef ENVELOPE_AUTH + else if (eq_octet(check,&str_envelope_auth,0)) filter->require_envelope_auth=1; +#endif +#ifdef ENOTIFY + else if (eq_octet(check,&str_enotify,0)) filter->require_enotify=1; #endif #ifdef SUBADDRESS else if (eq_octet(check,&str_subaddress,0)) filter->require_subaddress=1;