diff options
author | Alain Magloire <alainm@gnu.org> | 2001-04-24 05:09:27 +0000 |
---|---|---|
committer | Alain Magloire <alainm@gnu.org> | 2001-04-24 05:09:27 +0000 |
commit | 39dec3bccc1688d620e15a526f924cb8315f74ee (patch) | |
tree | e3528aace005926def7cc70654bdcc23b660cff9 | |
parent | df064ef2b8140a8269106eb3c300a33a27fbdc50 (diff) | |
download | mailutils-39dec3bccc1688d620e15a526f924cb8315f74ee.tar.gz mailutils-39dec3bccc1688d620e15a526f924cb8315f74ee.tar.bz2 |
2001-04-23 Alain Magloire
* pop3d/*.[ch]: Rename all the pop function pop3d_xx()
instead of pop3_xx() to be consistent with imap4d/*.
* mailbox/mbx_pop.c (pop_user): This is sudden death; for many pop
servers, it is important to let them time to remove locks or move
the .user.pop files. This happen when we do BUSY_CHECK(). For
example, the user does not want to read the entire file, and wants
start to read a new message, closing the connection and immediately
contact the server again, and we'll end up having
"-ERR Mail Lock busy" or something similar. To prevent this race
condition we sleep 2 seconds.
2001-04-23 Sergey Poznyakoff
It is often convenient to separte log outputs from POP and SMTP
servers. --with-log-facility flag which allows to specify to which
log facility the loggin output should be directed.
System administrators often prefere to have more information about
unsuccessfull authentications. I have added more verbose logging
to pop3d/user.c. Both failed attempts and possible account probes
(USER immediately followed by QUIT) are logged.
Made pop3d to be less verbose about its WELCOME prompt. When the
symbol TERSE_MODE is defined, pop3d introduces itself just as
+OK POP3 ready <apop_hash>
insead of divulging its type and version. This is a bit paranoid,
but it is better to be on the safe side...
-rw-r--r-- | ChangeLog | 57 | ||||
-rw-r--r-- | acconfig.h | 3 | ||||
-rw-r--r-- | configure.in | 11 | ||||
-rw-r--r-- | doc/mailutils.texi | 2 | ||||
-rw-r--r-- | mailbox/mapfile_stream.c | 3 | ||||
-rw-r--r-- | mailbox/mbx_pop.c | 27 | ||||
-rw-r--r-- | pop3d/apop.c | 12 | ||||
-rw-r--r-- | pop3d/auth.c | 2 | ||||
-rw-r--r-- | pop3d/capa.c | 2 | ||||
-rw-r--r-- | pop3d/dele.c | 2 | ||||
-rw-r--r-- | pop3d/extra.c | 32 | ||||
-rw-r--r-- | pop3d/list.c | 2 | ||||
-rw-r--r-- | pop3d/noop.c | 4 | ||||
-rw-r--r-- | pop3d/pop3d.c | 119 | ||||
-rw-r--r-- | pop3d/pop3d.h | 58 | ||||
-rw-r--r-- | pop3d/signal.c | 5 | ||||
-rw-r--r-- | pop3d/user.c | 20 |
17 files changed, 248 insertions, 113 deletions
@@ -1,6 +1,61 @@ +2001-04-23 Alain Magloire + + * pop3d/*.[ch]: Rename all the pop function pop3d_xx() + instead of pop3_xx() to be consistent with imap4d/*. + + * mailbox/mbx_pop.c (pop_user): This is sudden death; for many pop + servers, it is important to let them time to remove locks or move + the .user.pop files. This happen when we do BUSY_CHECK(). For + example, the user does not want to read the entire file, and wants + start to read a new message, closing the connection and immediately + contact the server again, and we'll end up having + "-ERR Mail Lock busy" or something similar. To prevent this race + condition we sleep 2 seconds. + +2001-04-23 Sergey Poznyakoff + + It is often convenient to separte log outputs from POP and SMTP + servers. --with-log-facility flag which allows to specify to which + log facility the loggin output should be directed. + System administrators often prefere to have more information about + unsuccessfull authentications. I have added more verbose logging + to pop3d/user.c. Both failed attempts and possible account probes + (USER immediately followed by QUIT) are logged. + Made pop3d to be less verbose about its WELCOME prompt. When the + symbol TERSE_MODE is defined, pop3d introduces itself just as + +OK POP3 ready <apop_hash> + insead of divulging its type and version. This is a bit paranoid, + but it is better to be on the safe side... + + * configure.in: ARGPINC gets assigne a relative path, due + to which the compilation fails if the package is configure with + --srdir=<path> option. + * configure.in: --with-log-facility new option. + * acconfig.h: LOG_FACILITY + + * doc/mailutils.texi: Typo. + + * mailbox/mapfile_stream.c: Define MAP_FAILED. + + * pop3d/extra.c (pop3_abquit): new case ERR_MBOX_SYNC. + (pop3_signal): Syslog the reason. + * pop3d/pop3d.c (pop_mainloop): Syslog the hostname of + the user on connect. + (pop3_daemon): Log to many children. Lacks call to exit(), so if + pop3d is run as a daemon, any child after exiting from + pop3_mainloop tries to accept() from already closed socket + and issues spurious error messages. + (pop3_mainloop): Check if the mailbox is uptodate if not + and the size shrink, bail out. Do not send version number. + * pop3d/pop3d.h: ERR_MBOX_SYNC define. WELCOME removed. + * pop3d/signal (pop3_sigchld): Lacks signal() call, due to which + the signal handler gets cleared after first SIGCHLD and all + subsequent children, when finished, just hang around like zombies. + * pop3d/user.c: Log to LOG_FACILITY all the errors. + 2001-04-23 Alain Magloire - Sergey Poznyakoff pointed out that errno change depending + Sergey Poznyakoff pointed out that errno changes depending if _REENTRANT is set or not. So for enable thread we take the approach of always defining _REENTRANT. He also noted that when in standalone the child was not exiting. diff --git a/acconfig.h b/acconfig.h index 4b308cbf6..ad8b738ae 100644 --- a/acconfig.h +++ b/acconfig.h @@ -32,3 +32,6 @@ /* Define _REENTRANT when using threads. */ #undef _REENTRANT + +/* Define the default loggin facility. */ +#undef LOG_FACILITY diff --git a/configure.in b/configure.in index ff4d08126..f6b70b474 100644 --- a/configure.in +++ b/configure.in @@ -42,6 +42,15 @@ AC_ARG_WITH(db2, *) AC_MSG_ERROR(bad value ${withval} for --with-db) ;; esac],[usedb2=no]) +AC_MSG_CHECKING(for log facility) +log_facility="LOG_MAIL" +AC_ARG_WITH(log-facility, + [ --with-log-facility=facility enable logging to the given facility], + AC_TRY_COMPILE([#include <syslog.h>], int lf = $withval, + log_facility=$withval)) +AC_DEFINE_UNQUOTED(LOG_FACILITY, $log_facility) +AC_MSG_RESULT($log_facility) + dnl Check for headers AC_HEADER_STDC AC_HEADER_DIRENT @@ -79,7 +88,7 @@ if test x"$ac_cv_func_argp_parse" != xyes; then AC_REPLACE_FUNCS(strndup strnlen strchrnul) ARGPLIBS="../argp/libargp.a" ARGPLIB="libargp.a" - ARGPINCS="-I../argp" + ARGPINCS='-I$(top_srcdir)/argp' AC_SUBST(ARGPLIBS) AC_SUBST(ARGPLIB) AC_SUBST(ARGPINCS) diff --git a/doc/mailutils.texi b/doc/mailutils.texi index 5abb27b55..f5032409e 100644 --- a/doc/mailutils.texi +++ b/doc/mailutils.texi @@ -158,7 +158,7 @@ mailers. @end group @end example -For example writing a simple @command{from} command that will list the +For example writing a simple @code{from} command that will list the @emph{From} and @emph{Subject} headers of every mail in a folder. @example diff --git a/mailbox/mapfile_stream.c b/mailbox/mapfile_stream.c index 4098fd5f0..f20b8fec4 100644 --- a/mailbox/mapfile_stream.c +++ b/mailbox/mapfile_stream.c @@ -34,6 +34,9 @@ #ifdef _POSIX_MAPPED_FILES #include <sys/mman.h> +#ifndef MAP_FAILED +# define MAP_FAILED (void*)-1 +#endif struct _mapfile_stream { diff --git a/mailbox/mbx_pop.c b/mailbox/mbx_pop.c index eceb38d76..158b075ea 100644 --- a/mailbox/mbx_pop.c +++ b/mailbox/mbx_pop.c @@ -24,6 +24,8 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <sys/time.h> +#include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <stdarg.h> @@ -112,6 +114,7 @@ static int pop_attr_flags __P ((attribute_t, int *)); static int pop_uidl __P ((message_t, char *, size_t, size_t *)); static int pop_uid __P ((message_t, size_t *)); static int fill_buffer __P ((pop_data_t, char *, size_t)); +static int pop_sleep __P ((int)); static int pop_readline __P ((pop_data_t)); static int pop_read_ack __P ((pop_data_t)); static int pop_writeline __P ((pop_data_t, const char *, ...)); @@ -512,7 +515,18 @@ pop_open (mailbox_t mbox, int flags) stream_setbufsiz (mbox->stream, BUFSIZ); } else - stream_close (mbox->stream); + { + /* This is sudden death: for many pop servers, it is important to + let them time to remove locks or move the .user.pop files. This + happen when we do BUSY_CHECK(). For example, the user does not + want to read the entire file, and wants start to read a new + message, closing the connection and immediately contact the + server again, and we'll end up having "-ERR Mail Lock busy" or + something similar. To prevent this race condition we sleep 2 + seconds. */ + stream_close (mbox->stream); + pop_sleep (2); + } mpd->state = POP_OPEN_CONNECTION; case POP_OPEN_CONNECTION: @@ -1739,6 +1753,17 @@ pop_retr (pop_message_t mpm, char *buffer, size_t buflen, off_t offset, return 0; } +/* GRRRRR!! We can not use sleep in the library since this we'll + muck up any alarm() done by the user. */ +static int +pop_sleep (int seconds) +{ + struct timeval tval; + tval.tv_sec = seconds; + tval.tv_usec = 0; + return select (1, NULL, NULL, NULL, &tval); +} + /* C99 says that a conforming implementation of snprintf () should return the number of char that would have been call but many old GNU/Linux && BSD implementations return -1 on error. Worse QnX/Neutrino actually does not diff --git a/pop3d/apop.c b/pop3d/apop.c index c01e8221f..74fe4cf26 100644 --- a/pop3d/apop.c +++ b/pop3d/apop.c @@ -20,7 +20,7 @@ /* Check if a username exists in APOP password file returns pointer to password if found, otherwise NULL */ char * -pop3_apopuser (const char *user) +pop3d_apopuser (const char *user) { char *password; char buf[POP_MAXCMDLEN]; @@ -88,7 +88,7 @@ pop3_apopuser (const char *user) if (password == NULL) { fclose (apop_file); - pop3_abquit (ERR_NO_MEM); + pop3d_abquit (ERR_NO_MEM); } password[0] = '\0'; @@ -122,7 +122,7 @@ pop3_apopuser (const char *user) } int -pop3_apop (const char *arg) +pop3d_apop (const char *arg) { char *tmp, *user_digest, *password; struct passwd *pw; @@ -138,15 +138,15 @@ pop3_apop (const char *arg) if (strlen (arg) == 0) return ERR_BAD_ARGS; - username = pop3_cmd (arg); + username = pop3d_cmd (arg); if (strlen (username) > (POP_MAXCMDLEN - APOP_DIGEST)) { free (username); return ERR_BAD_ARGS; } - user_digest = pop3_args (arg); + user_digest = pop3d_args (arg); - password = pop3_apopuser (username); + password = pop3d_apopuser (username); if (password == NULL) { free (username); diff --git a/pop3d/auth.c b/pop3d/auth.c index 44d0fbe54..6e5fa1ee4 100644 --- a/pop3d/auth.c +++ b/pop3d/auth.c @@ -20,7 +20,7 @@ /* AUTH is not yet implemented */ int -pop3_auth (const char *arg) +pop3d_auth (const char *arg) { (void)arg; if (state != AUTHORIZATION) diff --git a/pop3d/capa.c b/pop3d/capa.c index 1d3241d93..1b2100692 100644 --- a/pop3d/capa.c +++ b/pop3d/capa.c @@ -18,7 +18,7 @@ #include "pop3d.h" int -pop3_capa (const char *arg) +pop3d_capa (const char *arg) { if (strlen (arg) != 0) return ERR_BAD_ARGS; diff --git a/pop3d/dele.c b/pop3d/dele.c index 7efe94846..47ef5f0b0 100644 --- a/pop3d/dele.c +++ b/pop3d/dele.c @@ -20,7 +20,7 @@ /* DELE adds a message number to the list of messages to be deleted on QUIT */ int -pop3_dele (const char *arg) +pop3d_dele (const char *arg) { size_t num = 0; message_t msg; diff --git a/pop3d/extra.c b/pop3d/extra.c index feee141ab..39f790b78 100644 --- a/pop3d/extra.c +++ b/pop3d/extra.c @@ -21,7 +21,7 @@ after the first space, or a zero length string if no space */ char * -pop3_args (const char *cmd) +pop3d_args (const char *cmd) { int space = -1, i = 0, len; char *buf; @@ -29,7 +29,7 @@ pop3_args (const char *cmd) len = strlen (cmd) + 1; buf = malloc (len * sizeof (char)); if (buf == NULL) - pop3_abquit (ERR_NO_MEM); + pop3d_abquit (ERR_NO_MEM); while (space < 0 && i < len) { @@ -58,7 +58,7 @@ pop3_args (const char *cmd) the string, whichever occurs first */ char * -pop3_cmd (const char *cmd) +pop3d_cmd (const char *cmd) { char *buf; int i = 0, len; @@ -66,7 +66,7 @@ pop3_cmd (const char *cmd) len = strlen (cmd) + 1; buf = malloc (len * sizeof (char)); if (buf == NULL) - pop3_abquit (ERR_NO_MEM); + pop3d_abquit (ERR_NO_MEM); for (i = 0; i < len; i++) { @@ -84,7 +84,7 @@ pop3_cmd (const char *cmd) being killed on a signal */ int -pop3_abquit (int reason) +pop3d_abquit (int reason) { mailbox_close (mbox); mailbox_destroy (&mbox); @@ -118,6 +118,11 @@ pop3_abquit (int reason) syslog (LOG_INFO, "No socket to send to"); break; + case ERR_MBOX_SYNC: + syslog (LOG_ERR, "Mailbox was updated by other party: %s", username); + fprintf (ofile, "-ERR Mailbox updated by other party or corrupt\r\n"); + break; + default: fprintf (ofile, "-ERR Quitting (reason unknown)\r\n"); syslog (LOG_ERR, "Unknown quit"); @@ -133,7 +138,7 @@ pop3_abquit (int reason) /* Prints out usage information and exits the program */ void -pop3_usage (char *argv0) +pop3d_usage (char *argv0) { printf ("Usage: %s [OPTIONS]\n", argv0); printf ("Runs the GNU POP3 daemon.\n\n"); @@ -151,19 +156,20 @@ pop3_usage (char *argv0) exit (0); } -/* Default signal handler to call the pop3_abquit() function */ +/* Default signal handler to call the pop3d_abquit() function */ void -pop3_signal (int signo) +pop3d_signal (int signo) { (void)signo; - pop3_abquit (ERR_SIGNAL); + syslog (LOG_CRIT, "got signal %d", signo); + pop3d_abquit (ERR_SIGNAL); } /* Gets a line of input from the client */ char * -pop3_readline (int fd) +pop3d_readline (int fd) { fd_set rfds; struct timeval tv; @@ -183,17 +189,17 @@ pop3_readline (int fd) { available = select (fd + 1, &rfds, NULL, NULL, &tv); if (!available) - pop3_abquit (ERR_TIMEOUT); + pop3d_abquit (ERR_TIMEOUT); } nread = read (fd, buf, sizeof (buf) - 1); if (nread < 1) - pop3_abquit (ERR_DEAD_SOCK); + pop3d_abquit (ERR_DEAD_SOCK); buf[nread] = '\0'; ret = realloc (ret, (total + nread + 1) * sizeof (char)); if (ret == NULL) - pop3_abquit (ERR_NO_MEM); + pop3d_abquit (ERR_NO_MEM); memcpy (ret + total, buf, nread + 1); total += nread; } diff --git a/pop3d/list.c b/pop3d/list.c index 0ddda0262..7c9a9e651 100644 --- a/pop3d/list.c +++ b/pop3d/list.c @@ -20,7 +20,7 @@ /* Displays the size of message number arg or all messages (if no arg) */ int -pop3_list (const char *arg) +pop3d_list (const char *arg) { size_t mesgno; size_t size = 0; diff --git a/pop3d/noop.c b/pop3d/noop.c index c6a146b94..516a6e16c 100644 --- a/pop3d/noop.c +++ b/pop3d/noop.c @@ -1,5 +1,5 @@ /* GNU mailutils - a suite of utilities for electronic mail - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,7 +20,7 @@ /* Does nothing */ int -pop3_noop (const char *arg) +pop3d_noop (const char *arg) { if (strlen (arg) != 0) return ERR_BAD_ARGS; diff --git a/pop3d/pop3d.c b/pop3d/pop3d.c index 08eee6170..09354b5ce 100644 --- a/pop3d/pop3d.c +++ b/pop3d/pop3d.c @@ -74,7 +74,7 @@ main (int argc, char **argv) break; case 'h': - pop3_usage (argv[0]); + pop3d_usage (argv[0]); break; case 'i': @@ -123,21 +123,21 @@ main (int argc, char **argv) } /* Set the signal handlers. */ - signal (SIGINT, pop3_signal); - signal (SIGQUIT, pop3_signal); - signal (SIGILL, pop3_signal); - signal (SIGBUS, pop3_signal); - signal (SIGFPE, pop3_signal); - signal (SIGSEGV, pop3_signal); - signal (SIGTERM, pop3_signal); - signal (SIGSTOP, pop3_signal); - signal (SIGPIPE, pop3_signal); + signal (SIGINT, pop3d_signal); + signal (SIGQUIT, pop3d_signal); + signal (SIGILL, pop3d_signal); + signal (SIGBUS, pop3d_signal); + signal (SIGFPE, pop3d_signal); + signal (SIGSEGV, pop3d_signal); + signal (SIGTERM, pop3d_signal); + signal (SIGSTOP, pop3d_signal); + signal (SIGPIPE, pop3d_signal); if (timeout < 600) /* RFC 1939 says no less than 10 minutes. */ timeout = 0; /* So we'll turn it off. */ if (mode == DAEMON) - pop3_daemon_init (); + pop3d_daemon_init (); /* Change directory. */ chdir ("/"); @@ -149,10 +149,10 @@ main (int argc, char **argv) /* Actually run the daemon. */ if (mode == DAEMON) - pop3_daemon (maxchildren); - /* exit() -- no way out of daemon except a signal. */ + pop3d_daemon (maxchildren); + /* exit (0) -- no way out of daemon except a signal. */ else - status = pop3_mainloop (fileno (stdin), fileno (stdout)); + status = pop3d_mainloop (fileno (stdin), fileno (stdout)); /* Close the syslog connection and exit. */ closelog (); @@ -161,7 +161,7 @@ main (int argc, char **argv) /* Sets things up for daemon mode. */ void -pop3_daemon_init (void) +pop3d_daemon_init (void) { pid_t pid; unsigned int i; @@ -171,7 +171,7 @@ pop3_daemon_init (void) if (pid == -1) { perror ("fork failed:"); - exit (-1); + exit (1); } else if (pid > 0) exit (0); /* Parent exits. */ @@ -191,18 +191,18 @@ pop3_daemon_init (void) /* Close inherited file descriptors. */ for (i = 0; i < MAXFD; ++i) - close(i); + close (i); #ifdef HAVE_SIGACTION { struct sigaction act; - act.sa_handler = pop3_sigchld; + act.sa_handler = pop3d_sigchld; sigemptyset (&act.sa_mask); act.sa_flags = 0; sigaction (SIGCHLD, &act, NULL); } #else - signal (SIGCHLD, pop3_sigchld); + signal (SIGCHLD, pop3d_sigchld); #endif } @@ -210,7 +210,7 @@ pop3_daemon_init (void) executes the proper functions. Also handles the bulk of error reporting. */ int -pop3_mainloop (int infile, int outfile) +pop3d_mainloop (int infile, int outfile) { int status = OK; char *buf, *arg, *cmd; @@ -220,17 +220,28 @@ pop3_mainloop (int infile, int outfile) ifile = infile; ofile = fdopen (outfile, "w"); if (ofile == NULL) - pop3_abquit (ERR_NO_OFILE); + pop3d_abquit (ERR_NO_OFILE); state = AUTHORIZATION; curr_time = time (NULL); /* FIXME: Retreive hostname with getpeername() and log. */ syslog (LOG_INFO, "Incoming connection opened"); + /* log information on the connecting client */ + { + struct sockaddr_in cs; + int len = sizeof cs; + if (getpeername (infile, (struct sockaddr*)&cs, &len) < 0) + syslog (LOG_ERR, "can't obtain IP address of client: %s", + strerror (errno)); + else + syslog (LOG_INFO, "connect from %s", inet_ntoa(cs.sin_addr)); + } + /* Prepare the shared secret for APOP. */ local_hostname = malloc (MAXHOSTNAMELEN + 1); if (local_hostname == NULL) - pop3_abquit (ERR_NO_MEM); + pop3d_abquit (ERR_NO_MEM); gethostname (local_hostname, MAXHOSTNAMELEN); htbuf = gethostbyname (local_hostname); @@ -242,52 +253,64 @@ pop3_mainloop (int infile, int outfile) md5shared = malloc (strlen (local_hostname) + 51); if (md5shared == NULL) - pop3_abquit (ERR_NO_MEM); + pop3d_abquit (ERR_NO_MEM); snprintf (md5shared, strlen (local_hostname) + 50, "<%u.%u@%s>", getpid (), (int)time (NULL), local_hostname); free (local_hostname); - fprintf (ofile, "+OK POP3 " WELCOME " %s\r\n", md5shared); + fprintf (ofile, "+OK POP3 Ready %s\r\n", md5shared); while (state != UPDATE) { fflush (ofile); status = OK; - buf = pop3_readline (ifile); - cmd = pop3_cmd (buf); - arg = pop3_args (buf); + buf = pop3d_readline (ifile); + cmd = pop3d_cmd (buf); + arg = pop3d_args (buf); + + if (state == TRANSACTION && !mailbox_is_updated (mbox)) + { + static size_t mailbox_size; + size_t newsize = 0; + mailbox_get_size (mbox, &newsize); + /* Did we shrink? */ + if (!mailbox_size) + mailbox_size = newsize; + else (newsize < mailbox_size) + pop3d_abquit (ERR_MBOX_SYNC); + } if (strlen (arg) > POP_MAXCMDLEN || strlen (cmd) > POP_MAXCMDLEN) status = ERR_TOO_LONG; else if (strlen (cmd) > 4) status = ERR_BAD_CMD; else if (strncasecmp (cmd, "RETR", 4) == 0) - status = pop3_retr (arg); + status = pop3d_retr (arg); else if (strncasecmp (cmd, "DELE", 4) == 0) - status = pop3_dele (arg); + status = pop3d_dele (arg); else if (strncasecmp (cmd, "USER", 4) == 0) - status = pop3_user (arg); + status = pop3d_user (arg); else if (strncasecmp (cmd, "QUIT", 4) == 0) - status = pop3_quit (arg); + status = pop3d_quit (arg); else if (strncasecmp (cmd, "APOP", 4) == 0) - status = pop3_apop (arg); + status = pop3d_apop (arg); else if (strncasecmp (cmd, "AUTH", 4) == 0) - status = pop3_auth (arg); + status = pop3d_auth (arg); else if (strncasecmp (cmd, "STAT", 4) == 0) - status = pop3_stat (arg); + status = pop3d_stat (arg); else if (strncasecmp (cmd, "LIST", 4) == 0) - status = pop3_list (arg); + status = pop3d_list (arg); else if (strncasecmp (cmd, "NOOP", 4) == 0) - status = pop3_noop (arg); + status = pop3d_noop (arg); else if (strncasecmp (cmd, "RSET", 4) == 0) - status = pop3_rset (arg); + status = pop3d_rset (arg); else if ((strncasecmp (cmd, "TOP", 3) == 0) && (strlen (cmd) == 3)) - status = pop3_top (arg); + status = pop3d_top (arg); else if (strncasecmp (cmd, "UIDL", 4) == 0) - status = pop3_uidl (arg); + status = pop3d_uidl (arg); else if (strncasecmp (cmd, "CAPA", 4) == 0) - status = pop3_capa (arg); + status = pop3d_capa (arg); else status = ERR_BAD_CMD; @@ -326,12 +349,12 @@ pop3_mainloop (int infile, int outfile) } /* Runs GNU POP3 in standalone daemon mode. This opens and binds to a port - (default 110) then executes a pop3_mainloop() upon accepting a connection. + (default 110) then executes a pop3d_mainloop() upon accepting a connection. It starts maxchildren child processes to listen to and accept socket connections. */ void -pop3_daemon (unsigned int maxchildren) +pop3d_daemon (unsigned int maxchildren) { SA server, client; pid_t pid; @@ -342,7 +365,7 @@ pop3_daemon (unsigned int maxchildren) if (listenfd == -1) { syslog (LOG_ERR, "socket: %s", strerror(errno)); - exit (-1); + exit (1); } size = 1; /* Use size here to avoid making a new variable. */ setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof(size)); @@ -355,19 +378,20 @@ pop3_daemon (unsigned int maxchildren) if (bind (listenfd, (struct sockaddr *)&server, size) == -1) { syslog (LOG_ERR, "bind: %s", strerror (errno)); - exit (-1); + exit (1); } if (listen (listenfd, 128) == -1) { syslog (LOG_ERR, "listen: %s", strerror (errno)); - exit (-1); + exit (1); } for (;;) { if (children > maxchildren) { + syslog (LOG_ERR, "too many children"); pause (); continue; } @@ -377,7 +401,7 @@ pop3_daemon (unsigned int maxchildren) if (errno == EINTR) continue; syslog (LOG_ERR, "accept: %s", strerror (errno)); - exit (-1); + exit (1); } pid = fork (); @@ -387,8 +411,7 @@ pop3_daemon (unsigned int maxchildren) { int status; close (listenfd); - /* syslog(); FIXME log the info on the connecting client. */ - status = pop3_mainloop (connfd, connfd); + status = pop3d_mainloop (connfd, connfd); closelog (); exit (status); } diff --git a/pop3d/pop3d.h b/pop3d/pop3d.h index 107f16bec..739225588 100644 --- a/pop3d/pop3d.h +++ b/pop3d/pop3d.h @@ -26,9 +26,6 @@ /* You can edit the messages the POP server prints out here */ -/* Initial greeting */ -#define WELCOME "Welcome to " IMPL " (" PACKAGE " " VERSION ")" - /* A command that doesn't exist */ #define BAD_COMMAND "Invalid command" @@ -158,6 +155,7 @@ #define ERR_NO_OFILE 14 #define ERR_TIMEOUT 15 #define ERR_UNKNOWN 16 +#define ERR_MBOX_SYNC 17 #ifndef __P # ifdef __STDC__ @@ -179,32 +177,30 @@ extern time_t curr_time; extern char *md5shared; extern unsigned int children; -extern int pop3_dele __P ((const char *arg)); -extern int pop3_list __P ((const char *arg)); -extern int pop3_noop __P ((const char *arg)); -extern int pop3_quit __P ((const char *arg)); -extern int pop3_retr __P ((const char *arg)); -extern int pop3_rset __P ((const char *arg)); -extern int pop3_stat __P ((const char *arg)); -extern int pop3_top __P ((const char *arg)); -extern int pop3_uidl __P ((const char *arg)); -extern int pop3_user __P ((const char *arg)); -extern int pop3_apop __P ((const char *arg)); -extern int pop3_auth __P ((const char *arg)); -extern int pop3_capa __P ((const char *arg)); -extern char *pop3_args __P ((const char *cmd)); -extern char *pop3_cmd __P ((const char *cmd)); -extern int pop3_mesg_exist __P ((int mesg)); -extern int pop3_abquit __P ((int reason)); -extern int pop3_lock __P ((void)); -extern int pop3_unlock __P ((void)); -extern int pop3_getsizes __P ((void)); -extern int pop3_mainloop __P ((int infile, int outfile)); -extern void pop3_daemon __P ((unsigned int maxchildren)); -extern void pop3_usage __P ((char *argv0)); -extern void pop3_signal __P ((int)); -extern void pop3_sigchld __P ((int)); -extern void pop3_daemon_init __P ((void)); -extern char *pop3_apopuser __P ((const char *user)); -extern char *pop3_readline __P ((int fd)); +extern int pop3d_dele __P ((const char *arg)); +extern int pop3d_list __P ((const char *arg)); +extern int pop3d_noop __P ((const char *arg)); +extern int pop3d_quit __P ((const char *arg)); +extern int pop3d_retr __P ((const char *arg)); +extern int pop3d_rset __P ((const char *arg)); +extern int pop3d_stat __P ((const char *arg)); +extern int pop3d_top __P ((const char *arg)); +extern int pop3d_uidl __P ((const char *arg)); +extern int pop3d_user __P ((const char *arg)); +extern int pop3d_apop __P ((const char *arg)); +extern int pop3d_auth __P ((const char *arg)); +extern int pop3d_capa __P ((const char *arg)); +extern char *pop3d_args __P ((const char *cmd)); +extern char *pop3d_cmd __P ((const char *cmd)); +extern int pop3d_abquit __P ((int reason)); +extern int pop3d_lock __P ((void)); +extern int pop3d_unlock __P ((void)); +extern int pop3d_mainloop __P ((int infile, int outfile)); +extern void pop3d_daemon __P ((unsigned int maxchildren)); +extern void pop3d_usage __P ((char *argv0)); +extern void pop3d_signal __P ((int)); +extern void pop3d_sigchld __P ((int)); +extern void pop3d_daemon_init __P ((void)); +extern char *pop3d_apopuser __P ((const char *user)); +extern char *pop3d_readline __P ((int fd)); #endif /* _POP3D_H */ diff --git a/pop3d/signal.c b/pop3d/signal.c index 6ea0d498c..fd2e65727 100644 --- a/pop3d/signal.c +++ b/pop3d/signal.c @@ -29,5 +29,10 @@ pop3_sigchld (int signo) errno = 0; while ( (pid = waitpid(-1, &status, WNOHANG)) > 0) --children; +#ifndef HAVE_SIGACTION + /* On some system, signal implements the unreliabe sematic and + has to be rearm. */ + signal (SIGCHLD, pop3_sigchld); +#endif errno = old_errno; } diff --git a/pop3d/user.c b/pop3d/user.c index 04e228ae7..534170d5b 100644 --- a/pop3d/user.c +++ b/pop3d/user.c @@ -24,9 +24,8 @@ static char *_pwd; static char *_user; static int _perr = 0; -#define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) { \ - pam_end(pamh, 0); \ - return ERR_BAD_LOGIN; } +#define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) \ + goto pam_errlab; static int PAM_gnupop3d_conv (int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) @@ -119,6 +118,7 @@ pop3_user (const char *arg) free (cmd); return ERR_BAD_CMD; } + if ((strcasecmp (cmd, "PASS") == 0)) { free (cmd); @@ -145,7 +145,10 @@ pop3_user (const char *arg) spw = getspnam ((char *)arg); if (spw == NULL || strcmp (spw->sp_pwdp, crypt (pass, spw->sp_pwdp))) #endif /* HAVE_SHADOW_H */ - return ERR_BAD_LOGIN; + { + syslog (LOG_INFO, "User '%s': authentication failed", arg); + return ERR_BAD_LOGIN; + } } #else /* !USE_LIBPAM */ _user = (char *) arg; @@ -160,8 +163,14 @@ pop3_user (const char *arg) PAM_ERROR; pamerror = pam_setcred (pamh, PAM_ESTABLISH_CRED); PAM_ERROR; +pam_errlab: pam_end (pamh, PAM_SUCCESS); - openlog ("gnu-pop3d", LOG_PID, LOG_MAIL); + openlog ("gnu-pop3d", LOG_PID, LOG_FACILITY); + if (pamerror != PAM_SUCCESS) + { + syslog (LOG_INFO, "User '%s': authentication failed", _user); + return ERR_BAD_LOGIN; + } #endif /* USE_LIBPAM */ @@ -210,6 +219,7 @@ pop3_user (const char *arg) } else if (strcasecmp (cmd, "QUIT") == 0) { + syslog (LOG_INFO, "Possible probe of account '%s'", arg); free (cmd); return pop3_quit (pass); } |