Re: [vchkpw] vdelivermail qmail-queue ALPHA patch - take 3
>>> 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
>> 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");