Fix cert-try-verify when denied by event action
[exim.git] / src / src / sieve.c
index f96db358651561a7f9c0eff6d115bddb71869ebf..1303646ab34c81a8dca94fbf37888442146ca373 100644 (file)
@@ -1,5 +1,3 @@
-/* $Cambridge: exim/src/src/sieve.c,v 1.34 2008/01/29 12:08:43 michael Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
@@ -71,6 +69,7 @@ struct Sieve
   int require_enotify;
   struct Notification *notified;
 #endif
+  uschar *enotify_mailto_owner;
 #ifdef SUBADDRESS
   int require_subaddress;
 #endif
@@ -108,6 +107,38 @@ struct Notification
   struct Notification *next;
   };
 
+/* This should be a complete list of supported extensions, so that an external
+ManageSieve (RFC 5804) program can interrogate the current Exim binary for the
+list of extensions and provide correct information to a client.
+
+We'll emit the list in the order given here; keep it alphabetically sorted, so
+that callers don't get surprised.
+
+List *MUST* end with a NULL.  Which at least makes ifdef-vs-comma easier. */
+
+const uschar *exim_sieve_extension_list[] = {
+  CUS"comparator-i;ascii-numeric",
+  CUS"copy",
+#ifdef ENCODED_CHARACTER
+  CUS"encoded-character",
+#endif
+#ifdef ENOTIFY
+  CUS"enotify",
+#endif
+  CUS"envelope",
+#ifdef ENVELOPE_AUTH
+  CUS"envelope-auth",
+#endif
+  CUS"fileinto",
+#ifdef SUBADDRESS
+  CUS"subaddress",
+#endif
+#ifdef VACATION
+  CUS"vacation",
+#endif
+  NULL
+};
+
 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);
@@ -2970,7 +3001,7 @@ while (*filter->pc)
     subject.character=(uschar*)0;
     body.length=-1;
     body.character=(uschar*)0;
-    envelope_from=(sender_address && sender_address[0]) ? expand_string("$local_part_prefix$local_part$local_part_suffix@$domain") : US "";
+    envelope_from=(sender_address && sender_address[0]) ? expand_string(US"$local_part_prefix$local_part$local_part_suffix@$domain") : US "";
     for (;;)
       {
       if (parse_white(filter)==-1) return -1;
@@ -3037,11 +3068,11 @@ while (*filter->pc)
         for (already=filter->notified; already; already=already->next)
           {
           if (already->method.length==method.length
-              && (method.length==-1 || strcmp(already->method.character,method.character)==0)
+              && (method.length==-1 || Ustrcmp(already->method.character,method.character)==0)
               && already->importance.length==importance.length
-              && (importance.length==-1 || strcmp(already->importance.character,importance.character)==0)
+              && (importance.length==-1 || Ustrcmp(already->importance.character,importance.character)==0)
               && already->message.length==message.length
-              && (message.length==-1 || strcmp(already->message.character,message.character)==0))
+              && (message.length==-1 || Ustrcmp(already->message.character,message.character)==0))
             break;
           }
         if (already==(struct Notification*)0)
@@ -3058,7 +3089,6 @@ while (*filter->pc)
           if (filter_test == FTEST_NONE)
             {
             string_item *p;
-            header_line *h;
             int pid,fd;
 
             if ((pid = child_open_exim2(&fd,envelope_from,envelope_from))>=1)
@@ -3068,11 +3098,9 @@ while (*filter->pc)
               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 ? expand_string("$local_part_prefix$local_part$local_part_suffix@$domain") : from.character);
+              fprintf(f,"From: %s\n",from.length==-1 ? expand_string(US"$local_part_prefix$local_part$local_part_suffix@$domain") : from.character);
               for (p=recipient; p; p=p->next) fprintf(f,"To: %s\n",p->text);
-              fprintf(f,"Auto-submitted: sieve-notify\n");
+              fprintf(f,"Auto-Submitted: auto-notified; %s\n",filter->enotify_mailto_owner);
               if (header.length>0) fprintf(f,"%s",header.character);
               if (message.length==-1)
                 {
@@ -3403,8 +3431,8 @@ Returns:      1                success
               -1               syntax or execution error
 */
 
-static int parse_start(struct Sieve *filter, int exec,
-  address_item **generated)
+static int
+parse_start(struct Sieve *filter, int exec, address_item **generated)
 {
 filter->pc=filter->filter;
 filter->line=1;
@@ -3493,7 +3521,15 @@ while (parse_identifier(filter,CUS "require"))
     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;
+    else if (eq_octet(check,&str_enotify,0))
+      {
+      if (filter->enotify_mailto_owner == NULL)
+        {
+        filter->errmsg=CUS "enotify disabled";
+        return -1;
+        }
+        filter->require_enotify=1;
+      }
 #endif
 #ifdef SUBADDRESS
     else if (eq_octet(check,&str_subaddress,0)) filter->require_subaddress=1;
@@ -3541,7 +3577,8 @@ Arguments:
   filter      points to the entire file, read into store as a single string
   options     controls whether various special things are allowed, and requests
               special actions (not currently used)
-  sieve_vacation_directory  where to store vacation "once" files
+  vacation_directory    where to store vacation "once" files
+  enotify_mailto_owner  owner of mailto notifications
   useraddress string expression for :user part of address
   subaddress  string expression for :subaddress part of address
   generated   where to hang newly-generated addresses
@@ -3557,7 +3594,8 @@ Returns:      FF_DELIVERED     success, a significant action was taken
 
 int
 sieve_interpret(uschar *filter, int options, uschar *vacation_directory,
-  uschar *useraddress, uschar *subaddress, address_item **generated, uschar **error)
+  uschar *enotify_mailto_owner, uschar *useraddress, uschar *subaddress,
+  address_item **generated, uschar **error)
 {
 struct Sieve sieve;
 int r;
@@ -3583,6 +3621,20 @@ else
     }
   }
 
+if (enotify_mailto_owner == NULL)
+  sieve.enotify_mailto_owner = NULL;
+else
+  {
+  sieve.enotify_mailto_owner=expand_string(enotify_mailto_owner);
+  if (sieve.enotify_mailto_owner == NULL)
+    {
+    *error = string_sprintf("failed to expand \"%s\" "
+      "(sieve_enotify_mailto_owner): %s", enotify_mailto_owner,
+      expand_string_message);
+    return FF_ERROR;
+    }
+  }
+
 sieve.useraddress = useraddress == NULL ? CUS "$local_part_prefix$local_part$local_part_suffix" : useraddress;
 sieve.subaddress = subaddress;