diff options
author | Bob Beck <beck@cvs.openbsd.org> | 1998-06-03 08:57:15 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 1998-06-03 08:57:15 +0000 |
commit | d9b92cbaf895bd1dcceb0fd26800ad24987baf69 (patch) | |
tree | 41afede3648d213aeba801bd1271f23079d90f57 /libexec | |
parent | 367fd290a971c5e21a3d686c8ec40ec94f59569b (diff) |
-p port option for damon mode
-i pidfile option to write pid file for daemon mode
-l address option to restrict listen address
-q option and accumlog.c for on-line syslog entries
multiple buglet fixes, memeset, long, formatting etc.
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/smtpd/smtpd/Makefile | 4 | ||||
-rw-r--r-- | libexec/smtpd/smtpd/smtpd.8 | 38 | ||||
-rw-r--r-- | libexec/smtpd/smtpfwdd/Makefile | 4 | ||||
-rw-r--r-- | libexec/smtpd/smtpfwdd/smtpfwdd.8 | 9 | ||||
-rw-r--r-- | libexec/smtpd/src/CREDITS | 7 | ||||
-rw-r--r-- | libexec/smtpd/src/Makefile | 6 | ||||
-rw-r--r-- | libexec/smtpd/src/accumlog.c | 184 | ||||
-rw-r--r-- | libexec/smtpd/src/address_check.c | 41 | ||||
-rw-r--r-- | libexec/smtpd/src/smtp.h | 4 | ||||
-rw-r--r-- | libexec/smtpd/src/smtpd.c | 259 | ||||
-rw-r--r-- | libexec/smtpd/src/smtpd.h | 14 | ||||
-rw-r--r-- | libexec/smtpd/src/smtpfwdd.c | 32 |
12 files changed, 508 insertions, 94 deletions
diff --git a/libexec/smtpd/smtpd/Makefile b/libexec/smtpd/smtpd/Makefile index 65e9be10571..41b9de08586 100644 --- a/libexec/smtpd/smtpd/Makefile +++ b/libexec/smtpd/smtpd/Makefile @@ -1,9 +1,9 @@ # from: @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $OpenBSD: Makefile,v 1.3 1997/12/12 20:44:37 beck Exp $ +# $OpenBSD: Makefile,v 1.4 1998/06/03 08:56:56 beck Exp $ PROG= smtpd CFLAGS+=-I${.CURDIR}/../src -SRCS= smtpd.c address_check.c +SRCS= smtpd.c address_check.c accumlog.c BINOWN= root BINGRP= daemon BINMODE=500 diff --git a/libexec/smtpd/smtpd/smtpd.8 b/libexec/smtpd/smtpd/smtpd.8 index 81a35f87565..8e5390bd3a1 100644 --- a/libexec/smtpd/smtpd/smtpd.8 +++ b/libexec/smtpd/smtpd/smtpd.8 @@ -1,4 +1,4 @@ -.\" $Id: smtpd.8,v 1.6 1997/12/14 01:05:30 deraadt Exp $ +.\" $Id: smtpd.8,v 1.7 1998/06/03 08:56:58 beck Exp $ .Dd Dec 10, 1997 .Dt SMTPD 8 .Os OpenBSD @@ -8,13 +8,16 @@ Obtuse Systems SMTPD message storing daemon .Sh SYNOPSIS .Nm smtpd -.Op Fl HPDL +.Op Fl HPDLq .Op Fl c Ar chrootdir .Op Fl d Ar spooldir .Op Fl u Ar user .Op Fl g Ar group .Op Fl m Ar myname .Op Fl s Ar maxsize +.Op Fl l Ar listenip +.Op Fl p Ar listenport +.Op Fl i Ar pidfile .Sh DESCRIPTION The .Nm smtpd @@ -57,6 +60,27 @@ Disable host checking against the DNS. By default .Nm smtpd checks and will complain in the syslogs if the DNS information for a host seems to indicate a possible spoof or misconfiguration. +.It Fl i +specify a filename that +.Nm smtpd +should lock and write it's pid to when running as a daemon. +Doesn't do anything if running from inetd. Default pid file +in daemon mode is +.Pa /var/run/smtpd.pid +On BSD systems, or +.Pa /usr/spool/smtpd/smtpd.pid +on non-BSD systems. +.It Fl l +specify an ip address in dotted quad format for +.Nm smtpd +to accept connections to. In daemon mode this limits the address +that +.Nm smtpd +listens on. In inetd mode, smtpd will issue a 521 error +code and exit if connected to on an address other than the specified +one. By default, +.Nm smtpd +accepts a connection no matter what address it is connected to on. .It Fl L Suppress children in daemon mode (above) from doing an openlog() call. This means your syslogs won't have pid @@ -69,6 +93,11 @@ Specify .Ar myname , the hostname the daemon should announce itself as. the default is whatever gethostname() returns. +.It Fl p +specify a decimal port number for +.Nm smtpd +to listen when running as a daemon. Doesn't do anything if running +from inetd. .It Fl P Enable paranoid mode of operation, in this mode connections are dropped from any client feeding @@ -77,6 +106,11 @@ a suspicious hostname, FROM:, or RCPT: line containing characters indicative of an attempt to do something evil, or any message headers that aren't 8bit clean. The default is to log such occurances and substitute for the offending characters, but not drop the connection. +.It Fl q +Tell +.Nm smtpd +to be quieter. By default smtpd emits very verbose syslog messages. With +this option it will emit one line of log for each normal message exchange. .It Fl s Specify .Ar maxsize diff --git a/libexec/smtpd/smtpfwdd/Makefile b/libexec/smtpd/smtpfwdd/Makefile index 6ba3c1e2ecc..f6bab7ebc76 100644 --- a/libexec/smtpd/smtpfwdd/Makefile +++ b/libexec/smtpd/smtpfwdd/Makefile @@ -1,9 +1,9 @@ # from: @(#)Makefile 8.1 (Berkeley) 6/6/93 -# $OpenBSD: Makefile,v 1.3 1997/12/12 20:44:38 beck Exp $ +# $OpenBSD: Makefile,v 1.4 1998/06/03 08:57:00 beck Exp $ PROG= smtpfwdd CFLAGS+=-I${.CURDIR}/../src -SRCS= smtpfwdd.c +SRCS= smtpfwdd.c accumlog.c BINOWN= root BINGRP= daemon BINMODE=500 diff --git a/libexec/smtpd/smtpfwdd/smtpfwdd.8 b/libexec/smtpd/smtpfwdd/smtpfwdd.8 index c66bdbc1c2a..17e599e4aad 100644 --- a/libexec/smtpd/smtpfwdd/smtpfwdd.8 +++ b/libexec/smtpd/smtpfwdd/smtpfwdd.8 @@ -1,4 +1,4 @@ -.\" $Id: smtpfwdd.8,v 1.5 1997/12/13 20:20:00 deraadt Exp $ +.\" $Id: smtpfwdd.8,v 1.6 1998/06/03 08:57:01 beck Exp $ .Dd Dec 10, 1997 .Dt SMTPFWDD 8 .Os OpenBSD @@ -8,7 +8,7 @@ Obtuse Systems SMTPFWDD message forwarding daemon .Sh SYNOPSIS .Nm smtpfwdd -.Op Fl HPDL +.Op Fl q .Op Fl d Ar spooldir .Op Fl u Ar user .Op Fl g Ar group @@ -55,6 +55,11 @@ seconds indicating how often the master .Nm smtpfwdd process should wake up and check the spool directory for new mail to forward. Default is 10 seconds. +.It Fl q +Tell +.Nm smtpfwdd +to be quieter. By default smtpfwdd emits very verbose syslog messages. With +this option it will emit one line of log for each normal message exchange. .It Fl s Specify a different mail program to use to forward mail. The default is diff --git a/libexec/smtpd/src/CREDITS b/libexec/smtpd/src/CREDITS index 2ac0993991f..c45b9b6ff7a 100644 --- a/libexec/smtpd/src/CREDITS +++ b/libexec/smtpd/src/CREDITS @@ -120,3 +120,10 @@ What: Bug where smtpd wouldn't catch sigpipe if client goes away while sending message body - could make smtpd exit and leave an incomplete spool file sitting in the spool dir. +Who: Simon J. Gerraty <sjg@quick.com.au> +What: Contributed new -q logging format and fixes for spaces within + quoted local-part so smtpd doesn't smack X400 messages. + +Who: Henning P. Schmiedehausen <hps@tanstaafl.de> +What: Contributed -l option to allow for smtpd to be restricted to + answering on only one address on a box with many addresses. diff --git a/libexec/smtpd/src/Makefile b/libexec/smtpd/src/Makefile index 2a133a16fb3..c050915cc4e 100644 --- a/libexec/smtpd/src/Makefile +++ b/libexec/smtpd/src/Makefile @@ -346,16 +346,18 @@ CFLAGS = -g -O -Wall -DUSE_FLOCK -DUSE_MKSTEMP $(OPTIONS) all: smtpd smtpfwdd -smtpd: smtpd.o address_check.o +smtpd: smtpd.o address_check.o accumlog.o $(CC) -o smtpd smtpd.o address_check.o $(LD_LIBS) -smtpfwdd: smtpfwdd.o +smtpfwdd: smtpfwdd.o accumlog.o $(CC) -o smtpfwdd smtpfwdd.o $(LD_LIBS) smtpd.o: smtpd.c smtpd.h smtp.h smtpfwdd.o: smtpfwdd.c smtp.h +accumlog.o: accumlog.c + indent: indent $(INDENT_ARGS) smtpd.c indent $(INDENT_ARGS) smtpfwdd.c diff --git a/libexec/smtpd/src/accumlog.c b/libexec/smtpd/src/accumlog.c new file mode 100644 index 00000000000..8c29cd0ea19 --- /dev/null +++ b/libexec/smtpd/src/accumlog.c @@ -0,0 +1,184 @@ +/* + * $Id: accumlog.c,v 1.1 1998/06/03 08:57:05 beck Exp $ + * + * Copyright (c) 1998 Obtuse Systems Corporation <info@obtuse.com> + * Copyright (c) 1998 Simon J. Gerraty <sjg@quick.com.au> + * From: accumlog.c,v 1.1 1998/03/29 07:47:02 sjg + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Obtuse Systems + * Corporation and its contributors. + * 4. Neither the name of the Obtuse Systems Corporation nor the names + * of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY OBTUSE SYSTEMS CORPORATION AND + * CONTRIBUTORS ``AS IS''AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL OBTUSE SYSTEMS CORPORATION OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * NAME: + * accumlog - append info to log entry + * + * SYNOPSIS: + * int accumlog(level, fmt, ...) + * + * DESCRIPTION: + * If "fmt" is null we flush any accumulated log + * to syslog otherwise we just append it to an existing entry. + * + * AUTHOR: + * Simon J. Gerraty <sjg@quick.com.au> + */ + +/* + * @(#)Copyright (c) 1998 Simon J. Gerraty. + * + * This is free software. It comes with NO WARRANTY. + * Permission to use, modify and distribute this source code + * is granted subject to the following conditions. + * 1/ that the above copyright notice and this notice + * are preserved in all copies and that due credit be given + * to the author. + * 2/ that any changes to this code are clearly commented + * as such so that the author does not get blamed for bugs + * other than his own. + * + * Please send copies of changes and bug-fixes to: + * sjg@quick.com.au + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> +#if defined(__STDC__) || defined(__cplusplus) +#include <stdarg.h> +#else +#include <varargs.h> +#endif +#include <syslog.h> +#include <sys/types.h> +#include <string.h> +#include <sysexits.h> /* exit codes so smtpd/smtpfwdd can exit properly -BB */ +#ifdef HAVE_MALLOC_H +# include <malloc.h> +#else +extern char *malloc(), *realloc(); +#endif + +#ifdef MAIN +# define LOG_HUNK 10 +#endif + +#ifndef LOG_HUNK +# define LOG_HUNK 128 +#endif +#ifndef MAX +# define MAX(a, b) (((a) < (b)) ? (b) : (a)) +#endif + +int +#ifdef __STDC__ +accumlog(int level, const char *fmt, ...) { +#else +accumlog(va_alist) + va_dcl +{ + int level; + char *fmt; +#endif + va_list va; + static char *log = 0; + static int lsz = 0; + static int lx = 0; + int i, x, space = 0; + +#ifdef __STDC__ + va_start(va, fmt); +#else + va_start(va); + level = va_arg(va, int); + fmt = va_arg(va, char *); +#endif + if (log == 0) { + lsz = 2 * LOG_HUNK; + if ((log = (char *) malloc(lsz)) == 0) { + syslog(LOG_ERR, "accumlog: malloc(%d): %m", lsz); + exit(EX_OSERR); + } + } + if (fmt == 0) { + if (lx > 0) { + syslog(level, "%s", log); + space = lx; + lx = 0; + } + va_end(va); + return space; /* how much logged */ + } + do { + space = lsz - lx; + x = vsnprintf(&log[lx], space, fmt, va); + if (x < 0) { + syslog(LOG_ERR, "accumlog: vsnprintf(\"%s\", ...): %m", fmt); + lx = 0; /* lose */ + } + if (x > 0 && (i = x + (LOG_HUNK / 2)) > space) { + lsz += MAX(i, LOG_HUNK); + if ((log = realloc(log, lsz)) == 0) { + syslog(LOG_ERR, "accumlog: realloc(%d): %m", lsz); + exit(EX_OSERR); + } + + } + } while (x > 0 && x > space) ; + + if (x > 0) { + lx += x; + if (log[lx - 1] == '\n') + lx--; + } + + va_end(va); + return lx; +} + +#ifdef MAIN +int +main(argc, argv) + int argc; + char **argv; +{ + int i; + + openlog("accumlog", 0, LOG_LOCAL0); + accumlog(LOG_INFO, "PID=%d\n", getpid()); /* should lose the \n */ + + for (i = 1; i < argc; i++) + accumlog(LOG_INFO, ", argv[%d]='%s'", i, argv[i]); + accumlog(LOG_INFO, 0); + exit(EX_OK); +} +#endif diff --git a/libexec/smtpd/src/address_check.c b/libexec/smtpd/src/address_check.c index 9a77a8820b5..46d31eca70e 100644 --- a/libexec/smtpd/src/address_check.c +++ b/libexec/smtpd/src/address_check.c @@ -1,5 +1,5 @@ /* - * $Id: address_check.c,v 1.2 1997/12/14 01:42:27 beck Exp $ + * $Id: address_check.c,v 1.3 1998/06/03 08:57:05 beck Exp $ * * Copyright (c) 1996, 1997 Obtuse Systems Corporation. All rights * reserved. @@ -241,12 +241,21 @@ rfc931_ident(struct peer_info *pi, int ident) sprintf(tbuf, "%u,%u\r\n", ntohs(pi->peer_sa->sin_port), ntohs(pi->my_sa->sin_port)); - if (write(fd, tbuf, strlen(tbuf)) != strlen(tbuf)) { - alarm(0); - signal(SIGALRM, SIG_DFL); - close(fd); - return(0); - } + i=0; + while (i < strlen(tbuf)) { + int j; + j=write(fd, tbuf+i, (strlen(tbuf+i))); + if (j < 0) { + syslog(LOG_DEBUG, "write error sending ident request (%m)"); + alarm(0); + signal(SIGALRM, SIG_DFL); + close(fd); + return(0); + } + else if (j > 0){ + i+=j; + } + } /* read the answer back */ @@ -480,10 +489,10 @@ int masked_ip_match(char *tok, char *string) char *p, *tbuf; int period_cnt, non_digit; - unsigned long adt, mat, madt; - unsigned long *addr, *mask; + in_addr_t adt, mat, madt; + in_addr_t *addr, *mask; - mat=0xffffffff; + mat=INADDR_BROADCAST; addr=&adt; mask=&mat; @@ -516,7 +525,7 @@ int masked_ip_match(char *tok, char *string) if ( period_cnt == 3 ) { int a1, a2, a3, a4; - sscanf(tbuf,"%d.%d.%d.%d",&a1,&a2,&a3,&a4); + sscanf(tbuf,"%u.%u.%u.%u",&a1,&a2,&a3,&a4); if ( a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255 ) { return(0); } @@ -529,10 +538,10 @@ int masked_ip_match(char *tok, char *string) } else if ( strcmp(tbuf,"0") == 0 ) { ((char *)addr)[0] = 0; - ((char *)addr)[1] = 0; - ((char *)addr)[2] = 0; - ((char *)addr)[3] = 0; - + ((char *)addr)[1] = 0; + ((char *)addr)[2] = 0; + ((char *)addr)[3] = 0; + } else { /* not a masked address */ return(match_case_pattern(tok, string)); @@ -540,7 +549,7 @@ int masked_ip_match(char *tok, char *string) free(tbuf); if (*p == '/'){ - int bits; + long bits; char *end; p += 1; diff --git a/libexec/smtpd/src/smtp.h b/libexec/smtpd/src/smtp.h index 29db4a8a93d..aa8007ce56f 100644 --- a/libexec/smtpd/src/smtp.h +++ b/libexec/smtpd/src/smtp.h @@ -1,7 +1,7 @@ /* * Obtuse smtp store/forward daemon include file * - * $Id: smtp.h,v 1.1 1997/12/12 05:50:27 beck Exp $ + * $Id: smtp.h,v 1.2 1998/06/03 08:57:07 beck Exp $ * * Copyright (c) 1996, 1997 Obtuse Systems Corporation. All rights * reserved. @@ -86,3 +86,5 @@ struct smtp_victim { long location; /* start of RCPT line in spoolfile */ struct smtp_victim * next; }; + +extern int accumlog(int level, const char *fmt, ...); diff --git a/libexec/smtpd/src/smtpd.c b/libexec/smtpd/src/smtpd.c index 389ec7c06d6..6e9b68ddfb0 100644 --- a/libexec/smtpd/src/smtpd.c +++ b/libexec/smtpd/src/smtpd.c @@ -2,7 +2,7 @@ * smtpd, Obtuse SMTP daemon, storing agent. does simple collection of * mail messages, for later forwarding by smtpfwdd. * - * $Id: smtpd.c,v 1.5 1998/03/09 08:14:49 deraadt Exp $ + * $Id: smtpd.c,v 1.6 1998/06/03 08:57:11 beck Exp $ * * Copyright (c) 1996, 1997 Obtuse Systems Corporation. All rights * reserved. @@ -40,7 +40,7 @@ char *obtuse_copyright = "Copyright 1996 - Obtuse Systems Corporation - All rights reserved."; -char *obtuse_rcsid = "$Id: smtpd.c,v 1.5 1998/03/09 08:14:49 deraadt Exp $"; +char *obtuse_rcsid = "$Id: smtpd.c,v 1.6 1998/06/03 08:57:11 beck Exp $"; #include <stdarg.h> #include <stdlib.h> @@ -140,7 +140,7 @@ char *client_claimed_name = "UNKNOWN"; char *spoolfile = NULL; char *spooldir = SPOOLSUBDIR; /* this is relative to our chroot. */ int read_timeout = READ_TIMEOUT; -int maxsize = 0; +long maxsize = 0; int outfd, replyfd; #ifdef SUNOS_GETOPT extern char *optarg; @@ -154,6 +154,20 @@ int NoHostChecks = NO_HOSTCHECKS; int Paranoid_Smtp = PARANOID_SMTP; int Paranoid_Dns = PARANOID_DNS; int exiting = 0; +int VerboseSyslog = 1; + +#ifndef SMTPD_PID_DIR +#if defined(OpenBSD) || defined(FreeBSD) || defined(NetBSD) +# define SMTPD_PID_DIR "/var/run" +#else +# define SMTPD_PID_DIR SPOOLDIR +#endif +#endif + +#ifndef SMTPD_PID_FILENAME +#define SMTPD_PID_FILENAME "smtpd.pid" +#endif + /* * Generate the usual cryptic usage statement @@ -427,7 +441,7 @@ flush_smtp_mbuf(struct smtp_mbuf *buf, int fd, int len) } } } else { - syslog(LOG_CRIT, "You can't write %d bytes from a buffer with only %d in it!", len, buf->offset); + syslog(LOG_CRIT, "You can't write %d bytes from a buffer with only %d in it!", len, (int) buf->offset); } } @@ -515,7 +529,7 @@ write_smtp_mbuf(struct smtp_mbuf *mbuf, * let's hope there is enough to syslog :-) */ syslog(LOG_CRIT, "malloc said no to a %d byte buffer!", - (mbuf->size + len + 1024)); + (int)(mbuf->size + len + 1024)); return (0); } } @@ -551,7 +565,7 @@ read_smtp_mbuf(struct smtp_mbuf *mbuf, * let's hope there is enough to syslog :-) */ syslog(LOG_ERR, "malloc said no to a %d byte buffer!", - (mbuf->size + len + 1024)); + (int)(mbuf->size + len + 1024)); errno = ENOMEM; return (-1); } @@ -559,6 +573,8 @@ read_smtp_mbuf(struct smtp_mbuf *mbuf, /* * buffer is now big enough */ + + fflush(NULL); signal(SIGALRM, read_alarm_timeout); alarm(read_timeout); howmany = read(fd, mbuf->tail, len); @@ -805,6 +821,10 @@ smtp_exit(int val) if (exiting++<3) { flush_smtp_mbuf(reply_buf, replyfd, reply_buf->offset); } + + if (!VerboseSyslog) { + accumlog(LOG_INFO, 0); /* flush? */ + } exit(val); } @@ -1049,22 +1069,6 @@ smtp_cleanitup(const unsigned char *s) /* - * does string s look like a source routed mail address? - */ - -int -is_src_route(const unsigned char *s) -{ - while (*s != '\0') { - if ( (*s == '%') || (*s == '!') ) - return 1; - s++; - } - return 0; -} - - -/* * is smtp command "cmd" legal in state "state" */ int @@ -1388,8 +1392,18 @@ smtp_parse_cmd(unsigned char *inbuf, /* * log the connection */ - syslog(LOG_INFO, "SMTP HELO from %s(%s) as \"%s\"", - peerinfo.peer_clean_reverse_name, peerinfo.peer_ok_addr, client_claimed_name); + if (VerboseSyslog) { + syslog(LOG_INFO, "SMTP HELO from %s(%s) as \"%s\"", + peerinfo.peer_clean_reverse_name, + peerinfo.peer_ok_addr, client_claimed_name); + } + else { + accumlog(LOG_INFO, 0); /* flush anything left */ + accumlog(LOG_INFO, "relay=%s/%s", + peerinfo.peer_clean_reverse_name, peerinfo.peer_ok_addr); + if (strcasecmp(peerinfo.peer_clean_reverse_name, client_claimed_name)) + accumlog(LOG_INFO, " as \"%s\"", client_claimed_name); + } state_change(state, HELO, SUCCESS); } else if (strcasecmp(verb, "MAIL") == 0) { if (!cmd_ok(MAIL, state)) { @@ -1425,9 +1439,9 @@ smtp_parse_cmd(unsigned char *inbuf, */ cp = NULL; if (buf[0] == '"' || buf[1] == '"') - cp = strrchr(buf, '"'); /* REVISIT: find last " */ + cp = strrchr(buf, '"'); /* REVISIT: find last " */ if (cp == NULL) - cp = buf; + cp = buf+1; cp = strchr(cp+1, ' '); if (cp != NULL) { /* stuff on the end */ @@ -1473,8 +1487,12 @@ smtp_parse_cmd(unsigned char *inbuf, /* * log the connection */ - syslog(LOG_INFO, "mail from %s", - current_from_mailpath); + if (VerboseSyslog) { + syslog(LOG_INFO, "mail from %s", current_from_mailpath); + } else { + accumlog(LOG_INFO, " from=%s", current_from_mailpath); + } + /* * put our output in the outbuf */ @@ -1518,8 +1536,15 @@ smtp_parse_cmd(unsigned char *inbuf, } buf += 3; SPANBLANK(buf); + /* + * <sjg> if local-part contains ", then spaces are allowed + */ cp = NULL; - cp = strchr(buf, ' '); + if (buf[0] == '"' || buf[1] == '"') + cp = strrchr(buf, '"'); /* REVISIT: find last " */ + if (cp == NULL) + cp = buf; + cp = strchr(cp+1, ' '); if (cp != NULL) { /* stuff on the end */ *cp = '\0'; @@ -1634,7 +1659,14 @@ smtp_parse_cmd(unsigned char *inbuf, break; case 0: /* we matched a "deny" rule. syslog and send back failure message */ - syslog(LOG_INFO, "Forbidden FROM or RCPT for host %s(%s) - Abandoning session", peerinfo.peer_clean_reverse_name, peerinfo.peer_ok_addr); + if (VerboseSyslog) { + syslog(LOG_INFO, "Forbidden FROM or RCPT for host %s(%s) - Abandoning session", + peerinfo.peer_clean_reverse_name, peerinfo.peer_ok_addr); + } + else { + accumlog(LOG_INFO, " forbidden FROM or RCPT"); + accumlog(LOG_INFO, 0); /* flush it */ + } { char *c; c = make_check_fail_reply(peerinfo.peer_clean_ident, @@ -1665,7 +1697,12 @@ smtp_parse_cmd(unsigned char *inbuf, } } badrcpt = 1; - syslog(LOG_INFO, "Discarded bad recipient %s", victim); + + if (VerboseSyslog) { + syslog(LOG_INFO, "Discarded bad recipient %s", victim); + } else { + accumlog(LOG_INFO, " discarded bad recipient=%s", victim); + } state_change(state, RCPT, ERROR); break; @@ -1686,7 +1723,11 @@ smtp_parse_cmd(unsigned char *inbuf, /* * log the recipient. */ - syslog(LOG_INFO, "Recipient %s", victim); + if (VerboseSyslog) { + syslog(LOG_INFO, "Recipient %s", victim); + } else { + accumlog(LOG_INFO, " to=%s", victim); + } if (write_smtp_mbuf(outbuf, "RCPT ", strlen("RCPT ")) && write_smtp_mbuf(outbuf, victim, strlen(victim)) && write_smtp_mbuf(outbuf, "\n", 1)) { @@ -1759,7 +1800,7 @@ snarfdata(int in, int out, long *size, int bin) /* * initial message size */ - max = (*size ? *size : INT_MAX); + max = (*size ? *size : LONG_MAX); /* @@ -1769,12 +1810,12 @@ snarfdata(int in, int out, long *size, int bin) * the program will probably die and the bug will (hopefully) get fixed). */ - buf = alloc_smtp_mbuf(64); + buf = alloc_smtp_mbuf(1024); if (buf == NULL) { syslog(LOG_DEBUG, "Couldn't allocate input buffer for data command"); return (5); } - outbuf = alloc_smtp_mbuf(64); + outbuf = alloc_smtp_mbuf(1024); if (outbuf == NULL) { syslog(LOG_DEBUG, "Couldn't allocate output buffer for data command"); return (5); @@ -1788,11 +1829,20 @@ snarfdata(int in, int out, long *size, int bin) snarfed = read_smtp_mbuf(buf, in, 1024); if (snarfed < 0) { - syslog(LOG_INFO, "read error receiving message body: %m"); + if (VerboseSyslog) { + syslog(LOG_INFO, "read error receiving message body: %m"); + } else { + accumlog(LOG_INFO, " read error receiving message body: %s", + strerror(errno)); + } return (2); } if (snarfed == 0) { - syslog(LOG_INFO, "EOF while receiving message body"); + if (VerboseSyslog) { + syslog(LOG_INFO, "EOF while receiving message body"); + } else { + accumlog(LOG_INFO, " EOF while receiving message body"); + } return (2); } if (outbuf->size < buf->size) { @@ -1969,7 +2019,8 @@ int main(int argc, char **argv) { int opt; - char *optstring = "xc:d:u:s:g:m:HPDL"; + long smtp_port = 25; + char *optstring = "l:p:q:d:u:s:g:m:i:cHPDL"; int i, k; smtp_state_set last_state_s, current_state_s; /* The real state vector. */ smtp_state last_state, current_state; /* Pointers to the state vector. */ @@ -1979,9 +2030,12 @@ main(int argc, char **argv) char *groupname = SMTP_GROUP; struct passwd *user = NULL; struct group *group = NULL; - struct sigaction new_sa, old_sa; + struct sigaction new_sa; int daemon_mode = 0; int listen_fd = -1; /* make gcc be quiet */ + int pid_fd = -1; + char *pid_fname = NULL; + struct in_addr listen_addr; int child_no_openlog = 0; /* don't openlog() in children - use inherited * parent fd */ @@ -1990,10 +2044,11 @@ main(int argc, char **argv) peerinfo.peer_clean_forward_name = "UNKNOWN"; peerinfo.peer_clean_reverse_name = "UNKNOWN"; peerinfo.peer_ok_addr = ""; - + umask (077); openlog("smtpd", LOG_PID | LOG_NDELAY, LOG_FACILITY); + listen_addr.s_addr = INADDR_ANY; #if SET_LOCALE /* try to set our localization to the one specified */ @@ -2013,6 +2068,37 @@ main(int argc, char **argv) while ((opt = getopt(argc, argv, optstring)) > 0) { #endif switch (opt) { + case 'p': + { + char *foo; + smtp_port = strtol(optarg, &foo, 10); + if (*foo != '\0') { + /* this doesn't smell like a number. Bail */ + syslog(LOG_ERR, "Invalid port argument for the \"-p\" option"); + show_usage(); + exit(EX_USAGE); + } + } + break; + case 'l': + listen_addr.s_addr = inet_addr(optarg); + if (listen_addr.s_addr == htonl(INADDR_NONE)) { + syslog(LOG_ERR, "Invalid ip address given for the \"-l\" option"); + show_usage(); + exit(EX_USAGE); + } + break; + case 'i': + if (optarg[0] != '/') { + syslog(LOG_ERR, "The \"-i\" option requires an absolute pathname argument\n"); + show_usage(); + exit(EX_USAGE); + } + pid_fname = optarg; + break; + case 'q': + VerboseSyslog = 0; + break; case 'c': if (optarg[0] != '/') { syslog(LOG_ERR, "The \"-c\" option requires an absolute pathname argument\n"); @@ -2238,13 +2324,14 @@ main(int argc, char **argv) memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; - sa.sin_port = htons(25); - sa.sin_addr.s_addr = INADDR_ANY; + sa.sin_port = htons(smtp_port); + sa.sin_addr.s_addr = listen_addr.s_addr; /* Need to do this while we're still root */ if ( bind(listen_fd, (struct sockaddr *)&sa, sizeof(sa)) < 0 ) { - syslog(LOG_ERR, "Can't bind listen socket to port 25 in daemon mode (%m)"); + syslog(LOG_ERR, "Can't bind listen socket to port %ld in daemon mode (%m)" + , smtp_port); exit(EX_OSERR); } @@ -2262,6 +2349,23 @@ main(int argc, char **argv) syslog(LOG_INFO, "Log reopened."); } + if (daemon_mode) { + /* open pid file fd while we're still root. */ + + if ( (pid_fname == NULL) && + (((pid_fname = malloc(sizeof(SMTPD_PID_DIR) + + sizeof(SMTPD_PID_FILENAME) + 2))) + != NULL ) ) { + (void) sprintf(pid_fname, "%s/%s", SMTPD_PID_DIR, SMTPD_PID_FILENAME); + } + if (pid_fname != NULL) { + if ((pid_fd = open(pid_fname, O_CREAT | O_WRONLY, 0644)) < 0) { + syslog(LOG_ERR, "Couldn't create pid file %s: %m", pid_fname); + exit(EX_CONFIG); + } + } + } + if (chrootdir != NULL) { if (chdir(chrootdir) != 0) { syslog(LOG_CRIT, "Couldn't chdir to directory %s! (%m)", @@ -2282,6 +2386,7 @@ main(int argc, char **argv) syslog(LOG_CRIT, "NULL spool directory! Aborting."); abort(); } + if (setgid(group->gr_gid) != 0) { syslog(LOG_ERR, "I can't change groups! Setgid failed! (%m)"); syslog(LOG_ERR, "Exiting due to setgid failure"); @@ -2310,6 +2415,26 @@ main(int argc, char **argv) } setsid(); + /* write our pid into the (inherited) pid_fd */ + + if (pid_fd >= 0) { + char buf[80]; +#ifdef USE_FLOCK + if (lockf(pid_fd, F_TLOCK, 0) != 0) +#else + if (flock(pid_fd, LOCK_EX|LOCK_NB) != 0) +#endif + { + syslog(LOG_ERR, + "Couldn't get lock on pid file %s! Am I already running?", pid_fname); + exit(1); + } + sprintf(buf, "%d\n", getpid()); + write(pid_fd, buf, strlen(buf)); + /* do not close - leave this fd open to keep lock */ + } + + if ( listen(listen_fd,10) < 0 ) { syslog(LOG_ERR, "Can't listen on socket in daemon mode (%m)"); exit(EX_OSERR); @@ -2318,6 +2443,7 @@ main(int argc, char **argv) failures = 0; syslog(LOG_INFO,"smtpd running in daemon mode - ready to accept connections"); + while (1) { int fd; int slen; @@ -2357,6 +2483,7 @@ main(int argc, char **argv) * and break out of the loop to allow the regular inetd-style * processing to occur. */ + close(pid_fd); /* we don't need this anymore */ dup2(fd,0); dup2(fd,1); @@ -2385,13 +2512,11 @@ main(int argc, char **argv) #ifdef BSD_SIGNAL signal(SIGPIPE, SIG_IGN); #else + memset(&new_sa, 0, sizeof(new_sa)); new_sa.sa_handler = SIG_IGN; (void)sigemptyset(&new_sa.sa_mask); new_sa.sa_flags = SA_RESTART; -#ifdef __linux__ - new_sa.sa_restorer = NULL; -#endif - if ( sigaction( SIGPIPE, &new_sa, &old_sa ) != 0 ) { + if ( sigaction( SIGPIPE, &new_sa, NULL ) != 0 ) { syslog(LOG_CRIT,"CRITICAL - sigaction failed (%m)"); exit(EX_OSERR); } @@ -2587,6 +2712,30 @@ main(int argc, char **argv) zap_state(current_state); zap_state(last_state); + if (!daemon_mode && listen_addr.s_addr != INADDR_ANY) { + /* Are we allowed to talk on the address we accepted this connection + * on? - check to see that we are the defined listening address, or + * the loopback. + */ + if ((listen_addr.s_addr != peerinfo.my_sa->sin_addr.s_addr) + && (listen_addr.s_addr != htonl(INADDR_LOOPBACK)) + ) + { + /* tell the client to go away - we're not allowed to talk. */ + writereply(reply_buf, 521, 0, + peerinfo.my_clean_reverse_name, + " ", + m521msg, + NULL); + flush_smtp_mbuf(reply_buf, replyfd, reply_buf->offset); + syslog(LOG_INFO, "Refused connection attempt from %s(%s) to %s(%s)", + peerinfo.peer_clean_reverse_name, peerinfo.peer_ok_addr, + peerinfo.my_clean_reverse_name, inet_ntoa(listen_addr)); + smtp_exit(EX_OK); + } + } + + writereply(reply_buf, 220, 0, peerinfo.my_clean_reverse_name, " ", @@ -2608,7 +2757,11 @@ main(int argc, char **argv) /* * eof */ - syslog(LOG_INFO, "EOF on client fd. At least they could say goodbye!"); + if (VerboseSyslog) { + syslog(LOG_INFO, "EOF on client fd. At least they could say goodbye!"); + } else { + accumlog(LOG_INFO, "EOF on client fd."); + } smtp_exit(EX_OSERR); } offset = 0; @@ -2666,8 +2819,14 @@ main(int argc, char **argv) smtp_close_spoolfile(outfd); writereply(reply_buf, 250, 0, m250gotit, NULL); flush_smtp_mbuf(reply_buf, replyfd, reply_buf->offset); - syslog(LOG_INFO, "Received %ld bytes of message body from %s(%s)", - msize, peerinfo.peer_clean_reverse_name, peerinfo.peer_ok_addr); + if (VerboseSyslog) { + syslog(LOG_INFO, "Received %ld bytes of message body from %s(%s)", + msize, peerinfo.peer_clean_reverse_name, + peerinfo.peer_ok_addr); + } else { + accumlog(LOG_INFO, " bytes=%ld", msize); + accumlog(LOG_INFO, 0); /* flush */ + } clear_state(SNARF_DATA, current_state); clear_state(OK_RCPT, current_state); clear_state(OK_MAIL, current_state); diff --git a/libexec/smtpd/src/smtpd.h b/libexec/smtpd/src/smtpd.h index f71ece066b6..3c44da82cd6 100644 --- a/libexec/smtpd/src/smtpd.h +++ b/libexec/smtpd/src/smtpd.h @@ -1,6 +1,6 @@ /* Obtuse smtpd SMTP store daemon header file * - * $Id: smtpd.h,v 1.1 1997/12/12 05:50:27 beck Exp $ + * $Id: smtpd.h,v 1.2 1998/06/03 08:57:12 beck Exp $ * * Copyright (c) 1996, 1997 Obtuse Systems Corporation. All rights * reserved. @@ -164,13 +164,9 @@ extern int smtpd_addr_check(const char *, struct peer_info *, const char *, cons #define m554msg "This daemon finds you amusing.. Go read the forging FAQ.." #define m554norcpt "I gotta know who gets this masterpiece of forgery!" #define m554nofrom "Yeesh! Ya gotta give a FROM when forging mail, that's the whole point!" - -#ifdef USE_521 -#define m521msg "doesn't talk SMTP, Sorry" -#define m521first "Sorry, I've been told I can't talk to you" -#endif +#define m521msg "says \"Go away or I shall taunt you a second time you second-hand electric donkey-bottom biters..\"" #else /* Boring sendmail/RFC821-ish messages */ -#define m220msg "Sendmail ready. " +#define m220msg "Sendmail 4.1/SMI-4.1 ready." #define m221msg "Closing connection" #define m250helook "pleased to meet you," #define m250fromok "sender OK" @@ -202,9 +198,5 @@ extern int smtpd_addr_check(const char *, struct peer_info *, const char *, cons #define m554msg "Transaction failed" #define m554norcpt "Transaction failed" #define m554nofrom "Transaction failed" - -#ifdef USE_521 #define m521msg "Doesn't talk SMTP, Sorry" -#define m521first "Doesn't talk SMTP, Sorry" -#endif #endif diff --git a/libexec/smtpd/src/smtpfwdd.c b/libexec/smtpd/src/smtpfwdd.c index b166707eb67..612e4bd14c2 100644 --- a/libexec/smtpd/src/smtpfwdd.c +++ b/libexec/smtpd/src/smtpfwdd.c @@ -4,7 +4,7 @@ * to pick it up and invokes sendmail (or sendmail-like agent) to * deliver it. * - * $Id: smtpfwdd.c,v 1.2 1998/03/09 08:14:51 deraadt Exp $ + * $Id: smtpfwdd.c,v 1.3 1998/06/03 08:57:14 beck Exp $ * * Copyright (c) 1996, 1997 Obtuse Systems Corporation. All rights * reserved. @@ -41,7 +41,7 @@ */ char *obtuse_copyright = "Copyright 1996 - Obtuse Systems Corporation - All rights reserved."; -char *obtuse_rcsid = "$Id: smtpfwdd.c,v 1.2 1998/03/09 08:14:51 deraadt Exp $"; +char *obtuse_rcsid = "$Id: smtpfwdd.c,v 1.3 1998/06/03 08:57:14 beck Exp $"; #include <stdio.h> #include <signal.h> @@ -122,6 +122,8 @@ int children = 0; int maxchildren = MAXCHILDREN; int poll_time = POLL_TIME; int gc_int = COMPLETION_WAIT; +int VerboseSyslog = 1; + #ifdef SUNOS_GETOPT extern char *optarg; @@ -591,6 +593,9 @@ forward(char *fname) body = ftell(f); victim = victims; sentout = 0; + if (!VerboseSyslog) { + accumlog(LOG_INFO, "Forwading %s", fname); + } while (victim != NULL) { int status, pid, pidw, i, rstart; struct smtp_victim *sv = victim; @@ -616,7 +621,11 @@ forward(char *fname) av[i++] = from; rstart = i; while (i < MAXARGS - 2) { - syslog(LOG_INFO, "forwarding to recipient %s", victim->name); + if (VerboseSyslog) { + syslog(LOG_INFO, "forwarding to recipient %s", victim->name); + } else { + accumlog(LOG_INFO, " to=%s", victim->name); + } av[i++] = victim->name; victim = victim->next; if (victim == NULL) { @@ -731,8 +740,12 @@ forward(char *fname) /* * All seems to have worked */ - - syslog(LOG_INFO, "%s forwarded to %d recipients", fname, sentout); + if (VerboseSyslog) { + syslog(LOG_INFO, "%s forwarded to %d recipients", fname, sentout); + } else { + accumlog(LOG_INFO, ", forwarded to %d recipients", sentout); + accumlog(LOG_INFO, 0); /* flush */ + } if (unlink(fname) != 0) { syslog(LOG_CRIT, "Couldn't remove spool file %s! (%m)", fname); exit(EX_CONFIG); @@ -764,7 +777,7 @@ int main(int argc, char **argv) { int opt; - char *optstring = "u:g:d:s:C:M:P:"; + char *optstring = "qu:g:d:s:M:P:"; int pid; char *username = SMTP_USER; @@ -783,6 +796,9 @@ main(int argc, char **argv) while ((opt = getopt(argc, argv, optstring)) > 0) { #endif switch (opt) { + case 'q': + VerboseSyslog = 0; + break; case 'd': if (optarg[0] != '/') { fprintf(stderr, "The \"-d\" option requires an absolute pathname argument, \"%s\" is bogus\n", optarg); @@ -1102,6 +1118,10 @@ main(int argc, char **argv) sleep(1); reap_children(); } + if (!VerboseSyslog) { + /* should be empty - but just in case */ + accumlog(LOG_INFO, 0); + } /* * If we have a file with an appropriate name and it is * complete then create a child which will try to forward the |