Re: [vchkpw] vdelivermail qmail-queue ALPHA patch - take 3

2006-05-10 Thread Joshua Megerman
>>> On May 9, 2006, at 12:57 PM, Jeremy Kitchen wrote:
 the problem is that vpopmail is using qmail-inject to forward
 messages.
 qmail-inject does not tolerate malformed messages.

 it's that simple.
>>>
>>> Any volunteers to review the code in vdelivermail.c and modify it to
>>> use qmail-queue instead of qmail-inject?
>>>
>> OK, here's a quick stab at a basic patch - I modified qmail_inject_open
>> to
>> open qmail-queue appropriately (no args), and changed deliver_mail to
>> talk
>> to it.  I THINK :)
>>
>> There's no bounds checking and so forth in here, there are a few places
>> where there really needs to be some extra code to make sure that the
>> data
>> acquired is valid, but it's designed to be proof-of-concept.  It
>> compiles,
>> but that's all I can guarantee.
>>
>> Use at your own risk, yada yada...  Feel free to modify it as needed, I
>> have no ego attached to this code :)
>>
> OK, so I can't stand writing sloppy code :)  Here's an updated version of
> the patch that handles things a little better (albeit in a slightly more
> complicated manner), and cleans up a couple remaining stragglers of the
> changeover.
>
And here's another update.  I realized as I was driving home last night
that I'd made a mistake (that's what I get for coding while tired :)) and
was printing double NULLs in the envelope.  This fixes it (and simplifies
the code a little too).

Josh
-- 
Joshua Megerman
SJGames MIB #5273 - OGRE AI Testing Division
You can't win; You can't break even; You can't even quit the game.
  - Layman's translation of the Laws of Thermodynamics
--- vdelivermail.c.orig	2006-05-09 17:35:00.0 -0400
+++ vdelivermail.c	2006-05-10 09:09:19.0 -0400
@@ -72,6 +72,7 @@
 
 #define BUFF_SIZE 300
 int fdm;
+int fde;
 
 #define EXIT_BOUNCE 100
 #define EXIT_DEFER 111
@@ -304,33 +305,41 @@
 }
 #endif
 
-/* Forks off qmail-inject.  Returns PID of child, or 0 for failure. */
-pid_t qmail_inject_open(char *address)
+/* Forks off qmail-queue.  Returns PID of child, or 0 for failure. */
+pid_t qmail_queue_open()
 {
  int pim[2];
+ int pie[2];
+
  pid_t pid;
- static char *binqqargs[4];
+ static char *binqqargs[2];
 
 if ( pipe(pim) == -1) return 0;
+if ( pipe(pie) == -1) return 0;
 
 switch(pid=vfork()){
   case -1:
 close(pim[0]);
 close(pim[1]);
+close(pie[0]);
+close(pie[1]);
 printf ("Unable to fork: %d.", errno);
 return 0;
   case 0:
 close(pim[1]);
+close(pie[1]);
 if (vfd_move(0,pim[0]) == -1 ) _exit(-1);
+if (vfd_move(1,pie[0]) == -1 ) _exit(-1);
 binqqargs[0] = QMAILINJECT;
-binqqargs[1] = "--";
-binqqargs[2] = (*address == '&' ? &address[1] : &address[0]);
+binqqargs[1] = 0;
 execv(*binqqargs, binqqargs);
-printf ("Unable to launch qmail-inject.");
+printf ("Unable to launch qmail-queue.");
 exit (EXIT_DEFER);/* child's exit caught later */
 }
 fdm = pim[1];
+fde = pie[1];
 close(pim[0]);
+close(pie[0]);
 return(pid);
 }
 
@@ -628,10 +637,18 @@
   char *dtline;
   char *atpos;
   int dtlen;
+  char *sender = 0;
+  char keychar[2] = { 'F', 'T' };
+  char *envptrs[4] = { keychar, sender, keychar+1, address };
+  int envlens[4] = { 1, 0, 1, 0 }; // sender and address get initialized later
+  int writestr;
 
   if (*address=='&') ++address;  /* will this case ever happen? */
-  inject_pid = qmail_inject_open(address);
-  if (inject_pid == 0) vexiterr (EXIT_DEFER, "system error, can't open qmail-inject");
+  envptrs[3] = address;
+  envlens[3] = strlen(address) + 1;
+
+  inject_pid = qmail_queue_open();
+  if (inject_pid == 0) vexiterr (EXIT_DEFER, "system error, can't open qmail-queue");
   
   /* use the DTLINE variable, but skip past the dash in 
* [EMAIL PROTECTED] 
@@ -665,13 +682,33 @@
   }
   
   if (fdcopy (fdm, 0, DeliveredTo, strlen(DeliveredTo)) != 0) {
-  printf ("write to qmail-inject failed: %d\n", errno);
+  printf ("write to qmail-queue failed: %d\n", errno);
   close(fdm);
+  close(fde);
   waitpid(inject_pid,&child,0);
   vexiterr (EXIT_DEFER, "system error");
   }
 
+  if (!(sender = getenv("SENDER"))) {
+  printf ("unable to acquire SENDER from environment\n");
+  close(fdm);
+  close(fde);
+  vexiterr (EXIT_DEFER, "system error");
+  }
+  envptrs[1] = sender;
+  envlens[1] = strlen(sender) + 1;
+
+  for (writestr = 0; writestr < 4; writestr++) {
+if ((write(fde, (void *)envptrs[writestr], envlens[writestr])) != envlens[writestr]) {
+printf ("write to qmail-queue failed: %d\n", errno);
+close(fdm);
+close(fde);
+vexiterr (EXIT_DEFER, "system error");
+}
+  }
+
   close(fdm);
+  close(fde);
   wait

Re: [vchkpw] vdelivermail qmail-queue ALPHA patch

2006-05-09 Thread Joshua Megerman
>> On May 9, 2006, at 12:57 PM, Jeremy Kitchen wrote:
>>> the problem is that vpopmail is using qmail-inject to forward messages.
>>> qmail-inject does not tolerate malformed messages.
>>>
>>> it's that simple.
>>
>> Any volunteers to review the code in vdelivermail.c and modify it to
>> use qmail-queue instead of qmail-inject?
>>
> OK, here's a quick stab at a basic patch - I modified qmail_inject_open to
> open qmail-queue appropriately (no args), and changed deliver_mail to talk
> to it.  I THINK :)
>
> There's no bounds checking and so forth in here, there are a few places
> where there really needs to be some extra code to make sure that the data
> acquired is valid, but it's designed to be proof-of-concept.  It compiles,
> but that's all I can guarantee.
>
> Use at your own risk, yada yada...  Feel free to modify it as needed, I
> have no ego attached to this code :)
>
OK, so I can't stand writing sloppy code :)  Here's an updated version of
the patch that handles things a little better (albeit in a slightly more
complicated manner), and cleans up a couple remaining stragglers of the
changeover.

Josh
-- 
Joshua Megerman
SJGames MIB #5273 - OGRE AI Testing Division
You can't win; You can't break even; You can't even quit the game.
  - Layman's translation of the Laws of Thermodynamics
[EMAIL PROTECTED]--- vdelivermail.c.orig	2006-05-09 17:35:00.0 -0400
+++ vdelivermail.c	2006-05-09 18:33:26.0 -0400
@@ -72,6 +72,7 @@
 
 #define BUFF_SIZE 300
 int fdm;
+int fde;
 
 #define EXIT_BOUNCE 100
 #define EXIT_DEFER 111
@@ -304,33 +305,41 @@
 }
 #endif
 
-/* Forks off qmail-inject.  Returns PID of child, or 0 for failure. */
-pid_t qmail_inject_open(char *address)
+/* Forks off qmail-queue.  Returns PID of child, or 0 for failure. */
+pid_t qmail_queue_open()
 {
  int pim[2];
+ int pie[2];
+
  pid_t pid;
- static char *binqqargs[4];
+ static char *binqqargs[2];
 
 if ( pipe(pim) == -1) return 0;
+if ( pipe(pie) == -1) return 0;
 
 switch(pid=vfork()){
   case -1:
 close(pim[0]);
 close(pim[1]);
+close(pie[0]);
+close(pie[1]);
 printf ("Unable to fork: %d.", errno);
 return 0;
   case 0:
 close(pim[1]);
+close(pie[1]);
 if (vfd_move(0,pim[0]) == -1 ) _exit(-1);
+if (vfd_move(1,pie[0]) == -1 ) _exit(-1);
 binqqargs[0] = QMAILINJECT;
-binqqargs[1] = "--";
-binqqargs[2] = (*address == '&' ? &address[1] : &address[0]);
+binqqargs[1] = 0;
 execv(*binqqargs, binqqargs);
-printf ("Unable to launch qmail-inject.");
+printf ("Unable to launch qmail-queue.");
 exit (EXIT_DEFER);/* child's exit caught later */
 }
 fdm = pim[1];
+fde = pie[1];
 close(pim[0]);
+close(pie[0]);
 return(pid);
 }
 
@@ -628,10 +637,18 @@
   char *dtline;
   char *atpos;
   int dtlen;
+  char *sender = 0;
+  char keychar[3] = "FT";
+  char *envptrs[6] = { keychar, sender, keychar+2, keychar+1, address, keychar+2 };
+  int envlens[6] = { 1, 0, 1, 1, 0, 1 }; // sender and address get initialized later
+  int writestr;
 
   if (*address=='&') ++address;  /* will this case ever happen? */
-  inject_pid = qmail_inject_open(address);
-  if (inject_pid == 0) vexiterr (EXIT_DEFER, "system error, can't open qmail-inject");
+  envptrs[4] = address;
+  envlens[4] = strlen(address) + 1;
+
+  inject_pid = qmail_queue_open();
+  if (inject_pid == 0) vexiterr (EXIT_DEFER, "system error, can't open qmail-queue");
   
   /* use the DTLINE variable, but skip past the dash in 
* [EMAIL PROTECTED] 
@@ -665,13 +682,33 @@
   }
   
   if (fdcopy (fdm, 0, DeliveredTo, strlen(DeliveredTo)) != 0) {
-  printf ("write to qmail-inject failed: %d\n", errno);
+  printf ("write to qmail-queue failed: %d\n", errno);
   close(fdm);
+  close(fde);
   waitpid(inject_pid,&child,0);
   vexiterr (EXIT_DEFER, "system error");
   }
 
+  if (!(sender = getenv("SENDER"))) {
+  printf ("unable to acquire SENDER from environment\n");
+  close(fdm);
+  close(fde);
+  vexiterr (EXIT_DEFER, "system error");
+  }
+  envptrs[1] = sender;
+  envlens[1] = strlen(sender) + 1;
+
+  for (writestr = 0; writestr < 6; writestr++) {
+if ((write(fde, (void *)envptrs[writestr], envlens[writestr])) != envlens[writestr]) {
+printf ("write to qmail-queue failed: %d\n", errno);
+close(fdm);
+close(fde);
+vexiterr (EXIT_DEFER, "system error");
+}
+  }
+
   close(fdm);
+  close(fde);
   waitpid(inject_pid,&child,0);
   if (wait_exitcode(child) == 0) return;
   vexiterr (EXIT_DEFER, "system error");