Commit 39dec3bc 39dec3bccc1688d620e15a526f924cb8315f74ee by Alain Magloire

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...
1 parent df064ef2
2001-04-23 Alain Magloire
Sergey Poznyakoff pointed out that errno change depending
* 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 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.
......
......@@ -32,3 +32,6 @@
/* Define _REENTRANT when using threads. */
#undef _REENTRANT
/* Define the default loggin facility. */
#undef LOG_FACILITY
......
......@@ -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)
......
......@@ -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
......
......@@ -34,6 +34,9 @@
#ifdef _POSIX_MAPPED_FILES
#include <sys/mman.h>
#ifndef MAP_FAILED
# define MAP_FAILED (void*)-1
#endif
struct _mapfile_stream
{
......
......@@ -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
{
/* 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
......
......@@ -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);
......
......@@ -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)
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
......
/* 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;
......
......@@ -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);
}
......
......@@ -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 */
......
......@@ -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;
}
......
......@@ -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,8 +145,11 @@ 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 */
{
syslog (LOG_INFO, "User '%s': authentication failed", arg);
return ERR_BAD_LOGIN;
}
}
#else /* !USE_LIBPAM */
_user = (char *) arg;
_pwd = pass;
......@@ -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);
}
......