|
Penetration Testing
mailing list archives
Re: [PEN-TEST] Sendmail: Keeping a copy of relayed email
From: "José M. Fandiño" <jm.fandino () FADESA ES>
Date: Wed, 30 Aug 2000 10:00:56 +0200
Hello,
I found this code, but I don't know the author.
It's working in sendmail 8.9.3
regards,
David Taylor wrote:
My problem is - I want to keep a copy of the incoming email that I relay
off my machine.
--
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS d- s+: a- C+++ UL++++$ P+ L+++ E--- W++ N+ o K- w---
O+ M+ V- PS PE+ Y PGP+>+++ t+ 5 X+++ R- tv@ b+++ DI-- D+++
G e- h++ !r !z
------END GEEK CODE BLOCK------ /* ------------------------------------------------------------
* "LogAll" feature to log any message through this MTA
* (c) /ARX cleanware 1998
*/
{
#define LOGALLHEADER "X-Logged"
#define LOGALLLEVEL 12
char logallrcsid[] =
"$Id: logall.c,v 1.11 1998/09/19 10:12:04 root Exp root $";
/*
* $Log: logall.c,v $
* Revision 1.11 1998/09/19 10:12:04 root
* published
*
* Revision 1.7 1998/09/17 07:12:49 root
* clobbered qtimestr
*
* ABSTRACT
* This routine logs every message in a mail folder
* before it is actually transmitted. The log is
* "envelope-oriented" which means it logs every message
* once - not for every recipient. You must also see
* the sendmail syslog for actual delivery. The log
* includes full message bodys.
*
* IMPLEMENTATION
* The logging code is compiled into the sendmail binary
* with the documented and often overlooked checkcompat()
* routine:
* see "Bryan Costales & Eric Allman: sendmail 2nd Edition
* §20 `The checkcompat() Cookbook' p.285ff"
* To check whether a message was already logged it adds
* a new header "X-Logged" to the message with the logging
* host, the envelope id and queued date/time as values.
* As long as this info doesn't change the message is no
* more logged.
*
* CONFIGURATION
* The logfile is configuerd in a new macro:
* D{LogAll}path
* where path is the full pathname of the logfile, which
* should be mode 600. REMEMBER THIS IS A FULL BODY LOG.
* So be prepared for a huge file on site with much traffic.
* The file must exist and every mail is appended to it.
* The macro should be inserted into a m4-config-file for
* example like this:
*
* LOCAL_CONFIG
* D{LogAll}/var/log/mail.log
*
* INSTALLATION
* This source fragment must be included into the source-file:
* .../sendmail-8.x.y/src/conf.c
* at the following position (with the full path name of its
* current location - here "/root/adm/mail/sendmail/logall.c"):
*
*>>old if (tTd(49, 1))
*>>old printf("checkcompat(to=%s, from=%s)\n",
*>>old to->q_paddr, e->e_from.q_paddr);
*>>old
*>>new #include "/root/adm/mail/sendmail/logall.c"
*>>old
*>>old # ifdef EXAMPLE_CODE
*
* the sendmail binary must be remaked and reinstalled at
* its proper position (normally /usr/sbin/sendmail).
*
* MANAGEMENT
* Since the logfile produced by LogAll is a standard Unix-mailfolder,
* the logged mails can be managed with every Unix mail-reader or MUA.
* The mails inside the log can be deleted, remailed, read with any
* mail user agent. If the logfile is the standard mail folder of a
* special "LogAll-user" this is especially easy and even "mail" can
* or a Windows-based IMAP-client can manage the logfile.
*
* COMPATIBILITY
* LogAll is tested with sendmail-8.8.5 and sendmail-8.9.1
* under Linux 2.0.29.
*
* AUTHOR
* Axel Reinhold - arx () hof baynet de
*
* LICENSE/WARRANTY
* The software is provided "AS IS" without warranties of any kind,
* either expressed or implied, including, but not limited to the
* implied warranties of merchantability and fitness for a particular
* purpose. The entire risc of the software is with you. In no event
* we will be liable for any damages, including any lost profits,
* lost savings or other incidental damages arising out of the use
* or inability to use the software, even if we have been advised
* of the possibility of such damages, or for any claim by another party.
* ------------------------------------------------------------
*/
int mid; /* sendmail macro id */
char *logall = NULL; /* log file path from macro LogAll */
char bfpath[512]; /* body file path */
char *hlogged = LOGALLHEADER; /* header field */
char hlogval[MAXLINE]; /* header value */
char *hlogvalp; /* header value pointer */
char qtimestr[80]; /* queued time string from asctime */
FILE *lf, *bf; /* log and body files */
ADDRESS *a; /* address structure */
HDR *h; /* header structure */
int toflag = 0; /* to header flag */
int fromflag = 0; /* from header flag */
long bfpos; /* remember file pos */
size_t b_read; /* bytes read counter */
unsigned char b_buf[512]; /* buffer for read/write body */
mid = macid("{LogAll}", NULL); /* get our config macro */
logall = macvalue(mid, e); /* to check whether and where to log*/
/* Use logging if macro is set and we can open the logfile */
if ((logall!=NULL) && ((lf = fopen(logall, "a"))!=NULL)) {
if (tTd(49, 1)) /* debug use of logging */
printf("checkcompat: LogAll=%s e_id=%s\n", logall, e->e_id);
/* construct the "X-Logged" header field */
strcpy(qtimestr, asctime(localtime(&e->e_ctime))); /* get time */
if (qtimestr[strlen(qtimestr)-1]=='\n') /* remove trailing */
qtimestr[strlen(qtimestr)-1]='\0'; /* line-feed asctime*/
sprintf(hlogval, "Logged by %s as %s at %s",
MyHostName, e->e_id, qtimestr); /* our header field */
/* add the header if it doesn't already exist */
hlogvalp = hvalue(hlogged, e->e_header); /* get actual field */
if (hlogvalp==NULL) addheader(hlogged, hlogval, &e->e_header);
/* Log the message if our header didn't exist or was not from us*/
if ((hlogvalp==NULL) || (strcmp(hlogvalp, hlogval)!=0)) {
/* lock the logfile exclusive */
if (lockfile(fileno(lf), logall, NULL, LOCK_EX)) ;
fseek(lf, 0, SEEK_END); /* go the eof for appending message */
/* syslog the usage of LogAll */
if (LogLevel >= LOGALLLEVEL) sm_syslog(LOG_INFO, e->e_id,
"LogAll to %s at %s", logall, qtimestr);
/* print the Unix From line to separate messages in log file*/
fprintf(lf, "From %s %s\n", e->e_from.q_user, qtimestr);
/* scan all headers */
for (h = e->e_header; h != NULL; h = h->h_link) {
/* check if our header is from us and recent */
/* if not change the field value to our field */
if (strcasecmp(h->h_field, hlogged)==0) {
if (hlogvalp!=NULL) {
h->h_value =
realloc(h->h_value, strlen(hlogval)+1);
strcpy(h->h_value, hlogval);
}
h->h_flags &= ~H_DEFAULT; /* set flag */
}
/* log the header if appropiate */
if ((h->h_value!=NULL) && ((h->h_flags & H_RESENT)==0)) {
fprintf(lf, "%s: %s\n", h->h_field, h->h_value);
}
if (h->h_flags & H_RCPT) toflag = 1; /* to-header*/
}
if (!toflag) { /* if no to-header construct from envelope */
fprintf(lf, "To:");
for (a = e->e_sendqueue; a != NULL; a = a->q_next)
fprintf(lf, " %s", a->q_paddr);
fprintf(lf, "\n");
}
fprintf(lf, "\n"); /* separate headers from body */
/* now add the body from temp file or queued data file */
sprintf(bfpath, "%s/df%s", QueueDir, e->e_id); /* body file */
if (e->e_dfp != NULL) { /* if body temp file is open use it */
bfpos = ftell(e->e_dfp);/* remember old position */
rewind(e->e_dfp); /* read from beginning */
while ((b_read = fread(b_buf, 1L, sizeof(b_buf), e->e_dfp)) != 0)
fwrite(b_buf, 1L, b_read, lf);
fseek(e->e_dfp, bfpos, SEEK_SET); /* set old pos */
}
else if ((bf = fopen(bfpath, "r")) != NULL) { /* body file */
while ((b_read = fread(b_buf, 1, sizeof(b_buf), bf)) != 0)
fwrite(b_buf, 1, b_read, lf);
fclose(bf);
}
else { /* no body could be opened */
if (tTd(49, 1))
printf("checkcompat: fopen(%s) failed\n", bfpath);
}
fprintf(lf, "\n");
if (lockfile(fileno(lf), logall, NULL, LOCK_UN)) ; /* unlock*/
}
fclose(lf);
}
/* ------------------------------------------------------------
* LogAll End
* ------------------------------------------------------------
*/
}
By Date
By Thread
Current thread:
- [PEN-TEST] Sendmail: Keeping a copy of relayed email, (continued)
|