Commit f9a28c03 f9a28c0373000d37b6021eaf845fec23f7608eb8 by Sergey Poznyakoff

Improve generation of session identifiers for server programs

* include/mailutils/acl.h (mu_acl_set_session_id): Remove proto.
* include/mailutils/server.h (mu_session_id): Remove extern.
(mu_sid): New proto.
* libmailutils/server/sid.c: New file.
* libmailutils/server/Makefile.am: Add sid.c
* libmailutils/server/ipsrv.c (mu_ip_tcp_accept)
(mu_ip_udp_accept): Remove calls to mu_acl_set_session_id.
(mu_ip_server_accept): Make sure output to mu_strerr is filtered so
that session ID is prepended to each line.
(mu_ip_server_loop): Remove.
* libmailutils/server/msrv.c (mu_m_server_check_acl): Remove call
to mu_acl_set_session_id.
* libmailutils/server/server.c (mu_session_id): Remove variable.

* imap4d/imap4d.c (get_client_address, set_strerr_flt)
(clr_strerr_flt): Remove unused functions.
(imap4d_connection): Simplify.
* pop3d/pop3d.c: Likewise.
1 parent f8ee4fc6
......@@ -17,8 +17,8 @@
#include "imap4d.h"
#include <mailutils/gsasl.h>
#include "mailutils/cli.h"
#include "mailutils/kwd.h"
#include <mailutils/cli.h>
#include <mailutils/kwd.h>
#include "tcpwrap.h"
mu_m_server_t server;
......@@ -706,83 +706,6 @@ imap4d_session_setup (char *username)
return imap4d_session_setup0 ();
}
int
get_client_address (int fd, struct sockaddr_in *pcs)
{
socklen_t len = sizeof *pcs;
if (getpeername (fd, (struct sockaddr *) pcs, &len) < 0)
{
mu_diag_funcall (MU_DIAG_ERROR, "getpeername", NULL, errno);
return 1;
}
return 0;
}
static int
set_strerr_flt (void)
{
mu_stream_t flt, trans[2];
int rc;
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET, trans);
if (rc == 0)
{
char sessidstr[10];
char *argv[] = { "inline-comment", NULL, "-S", NULL };
snprintf (sessidstr, sizeof sessidstr, "%08lx:", mu_session_id);
argv[1] = sessidstr;
rc = mu_filter_create_args (&flt, trans[0], "inline-comment", 3,
(const char **)argv,
MU_FILTER_ENCODE, MU_STREAM_WRITE);
mu_stream_unref (trans[0]);
if (rc == 0)
{
mu_stream_set_buffer (flt, mu_buffer_line, 0);
trans[0] = flt;
trans[1] = NULL;
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM,
MU_IOCTL_OP_SET, trans);
mu_stream_unref (trans[0]);
if (rc)
mu_error (_("%s failed: %s"), "MU_IOCTL_SET_STREAM",
mu_stream_strerror (mu_strerr, rc));
}
else
mu_error (_("cannot create log filter stream: %s"), mu_strerror (rc));
}
else
{
mu_error (_("%s failed: %s"), "MU_IOCTL_GET_STREAM",
mu_stream_strerror (mu_strerr, rc));
}
return rc;
}
static void
clr_strerr_flt (void)
{
mu_stream_t flt, trans[2];
int rc;
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET, trans);
if (rc == 0)
{
flt = trans[0];
rc = mu_stream_ioctl (flt, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET, trans);
if (rc == 0)
{
mu_stream_unref (trans[0]);
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM,
MU_IOCTL_OP_SET, trans);
if (rc == 0)
mu_stream_unref (flt);
}
}
}
void
imap4d_child_signal_setup (RETSIGTYPE (*handler) (int signo))
{
......@@ -901,21 +824,12 @@ imap4d_connection (int fd, struct sockaddr *sa, int salen,
struct mu_srv_config *pconf, void *data)
{
struct imap4d_srv_config *cfg = (struct imap4d_srv_config *) pconf;
int rc;
idle_timeout = pconf->timeout;
imap4d_transcript = pconf->transcript;
if (mu_log_session_id)
rc = set_strerr_flt ();
else
rc = 1;
idle_timeout = cfg->m_cfg.timeout;
imap4d_transcript = cfg->m_cfg.transcript;
imap4d_mainloop (fd, fd, cfg);
if (rc == 0)
clr_strerr_flt ();
return 0;
}
......@@ -1057,7 +971,7 @@ main (int argc, char **argv)
if (setgid (gr->gr_gid) == -1)
{
mu_error (_("error setting mail group: %s"), mu_strerror (errno));
exit (EX_OSERR);
//exit (EX_OSERR);
}
}
......
......@@ -66,6 +66,5 @@ int mu_acl_string_to_action (const char *str, mu_acl_action_t *pres);
int mu_acl_setenv (mu_acl_t acl, const char *name, const char *val);
const char *mu_acl_getenv (mu_acl_t acl, const char *name);
int mu_acl_set_session_id (mu_acl_t acl);
#endif
......
......@@ -22,8 +22,6 @@
#include <mailutils/types.h>
#include <signal.h>
extern unsigned long mu_session_id;
typedef int (*mu_conn_loop_fp) (int fd, void *conn_data, void *server_data);
typedef void (*mu_conn_free_fp) (void *conn_data, void *server_data);
typedef int (*mu_server_idle_fp) (void *server_data);
......@@ -71,7 +69,6 @@ int mu_ip_server_set_data (mu_ip_server_t srv,
int mu_ip_server_open (mu_ip_server_t srv);
int mu_ip_server_shutdown (mu_ip_server_t srv);
int mu_ip_server_accept (mu_ip_server_t srv, void *call_data);
int mu_ip_server_loop (mu_ip_server_t srv, void *call_data);
int mu_ip_server_get_fd (mu_ip_server_t srv);
int mu_ip_server_get_sockaddr (mu_ip_server_t srv, struct mu_sockaddr **psa);
const char *mu_ip_server_addrstr (mu_ip_server_t srv);
......@@ -96,7 +93,6 @@ struct mu_srv_config /* Configuration data for a single TCP server. */
/* Application-dependent data may follow */
};
typedef struct mu_m_server_connect_data mu_m_server_connect_data_t;
typedef int (*mu_m_server_handler_fp) (int fd, struct sockaddr *sa, int salen,
struct mu_srv_config *pconf,
......@@ -149,4 +145,6 @@ int mu_m_server_check_acl (mu_m_server_t msrv, struct sockaddr *s, int salen);
struct mu_cfg_param;
void mu_m_server_cfg_init (mu_m_server_t msrv, struct mu_cfg_param *app_param);
int mu_sid (char **);
#endif
......
......@@ -21,6 +21,7 @@ libserver_la_SOURCES = \
acl.c\
server.c\
msrv.c\
ipsrv.c
ipsrv.c\
sid.c
AM_CPPFLAGS = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
......
......@@ -36,7 +36,10 @@
#include <mailutils/errno.h>
#include <mailutils/nls.h>
#include <mailutils/sockaddr.h>
#include <mailutils/stream.h>
#include <mailutils/stdstream.h>
#include <mailutils/filter.h>
#include <mailutils/syslog.h>
struct _mu_ip_server
{
......@@ -386,7 +389,6 @@ mu_ip_tcp_accept (mu_ip_server_t srv, void *call_data)
mu_acl_result_t res;
int rc;
mu_acl_set_session_id (srv->acl);
rc = mu_acl_check_sockaddr (srv->acl, &client.sa, size, &res);
if (rc)
mu_debug (MU_DEBCAT_SERVER, MU_DEBUG_ERROR,
......@@ -470,7 +472,6 @@ mu_ip_udp_accept (mu_ip_server_t srv, void *call_data)
mu_acl_result_t res;
int rc;
mu_acl_set_session_id (srv->acl);
rc = mu_acl_check_sockaddr (srv->acl, &client.sa, size, &res);
if (rc)
mu_debug (MU_DEBCAT_SERVER, MU_DEBUG_ERROR,
......@@ -488,12 +489,91 @@ mu_ip_udp_accept (mu_ip_server_t srv, void *call_data)
return rc;
}
static int
set_strerr_flt (void)
{
mu_stream_t flt, trans[2];
int rc;
if (!mu_log_session_id)
return ENOSYS;
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET, trans);
if (rc == 0)
{
char *sid;
char *argv[] = { "inline-comment", NULL, "-S", NULL };
rc = mu_sid (&sid);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERR, "mu_sid", NULL, rc);
return 0;
}
argv[1] = sid;
rc = mu_filter_create_args (&flt, trans[0], "inline-comment", 3,
(const char **)argv,
MU_FILTER_ENCODE, MU_STREAM_WRITE);
free (sid);
mu_stream_unref (trans[0]);
if (rc == 0)
{
mu_stream_set_buffer (flt, mu_buffer_line, 0);
trans[0] = flt;
trans[1] = NULL;
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM,
MU_IOCTL_OP_SET, trans);
mu_stream_unref (trans[0]);
if (rc)
mu_error (_("%s failed: %s"), "MU_IOCTL_SET_STREAM",
mu_stream_strerror (mu_strerr, rc));
}
else
mu_error (_("cannot create log filter stream: %s"), mu_strerror (rc));
}
else
{
mu_error (_("%s failed: %s"), "MU_IOCTL_GET_STREAM",
mu_stream_strerror (mu_strerr, rc));
}
return rc;
}
static void
clr_strerr_flt (void)
{
mu_stream_t flt, trans[2];
int rc;
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET, trans);
if (rc == 0)
{
flt = trans[0];
rc = mu_stream_ioctl (flt, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET, trans);
if (rc == 0)
{
mu_stream_unref (trans[0]);
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM,
MU_IOCTL_OP_SET, trans);
if (rc == 0)
mu_stream_unref (flt);
}
}
}
int
mu_ip_server_accept (mu_ip_server_t srv, void *call_data)
{
int rc;
int flt;
if (!srv || srv->fd == -1)
return EINVAL;
flt = set_strerr_flt ();
switch (srv->type)
{
case MU_IP_UDP:
......@@ -510,27 +590,12 @@ mu_ip_server_accept (mu_ip_server_t srv, void *call_data)
mu_strerror (rc));
mu_ip_server_shutdown (srv);
}
if (flt == 0)
clr_strerr_flt ();
return rc;
}
int
mu_ip_server_loop (mu_ip_server_t srv, void *call_data)
{
if (!srv)
return EINVAL;
while (srv->fd != -1)
{
int rc = mu_ip_server_accept (srv, call_data);
if (rc && rc != EINTR)
{
mu_ip_server_shutdown (srv);
return rc;
}
}
return 0;
}
int
mu_ip_server_get_fd (mu_ip_server_t srv)
{
return srv->fd;
......
......@@ -676,7 +676,6 @@ mu_m_server_check_acl (mu_m_server_t msrv, struct sockaddr *s, int salen)
mu_acl_result_t res;
int rc;
mu_acl_set_session_id (msrv->acl);
rc = mu_acl_check_sockaddr (msrv->acl, s, salen, &res);
if (rc)
{
......
......@@ -41,8 +41,6 @@ struct _mu_connection
#define MU_SERVER_TIMEOUT 0x1
unsigned long mu_session_id;
struct _mu_server
{
int nfd;
......@@ -111,7 +109,6 @@ connection_loop (mu_server_t srv, fd_set *fdset)
{
int rc;
++mu_session_id;
rc = conn->f_loop (conn->fd, conn->data, srv->server_data);
switch (rc)
{
......@@ -300,11 +297,4 @@ mu_server_add_connection (mu_server_t srv,
return 0;
}
int
mu_acl_set_session_id (mu_acl_t acl)
{
char sessidstr[9];
snprintf (sessidstr, sizeof sessidstr, "%08lx", mu_session_id);
return mu_acl_setenv (acl, "sessid", sessidstr);
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2017 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; If not, see
<http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <mailutils/errno.h>
#include <mailutils/alloc.h>
#define SID_ABC "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
#define SID_LEN (sizeof (SID_ABC) - 1)
#define SID_LEN_SQR (SID_LEN * SID_LEN)
/* Generate (almost) unique session ID. The idea borrowed from Sendmail
queue ID.
*/
int
mu_sid (char **res)
{
static int init;
static unsigned int seqno = 0;
static char abc[] = SID_ABC;
struct timeval t;
struct tm *tm;
unsigned int n;
char sidbuf[9];
char *p;
if (!res)
return MU_ERR_OUT_PTR_NULL;
gettimeofday (&t, NULL);
if (!init)
{
seqno = getpid () + t.tv_sec + t.tv_usec;
init = 1;
}
n = seqno++ % SID_LEN_SQR;
tm = gmtime (&t.tv_sec);
sidbuf[0] = abc[tm->tm_year % SID_LEN];
sidbuf[1] = abc[tm->tm_mon];
sidbuf[2] = abc[tm->tm_mday];
sidbuf[3] = abc[tm->tm_hour];
sidbuf[4] = abc[tm->tm_min % SID_LEN];
sidbuf[5] = abc[tm->tm_sec % SID_LEN];
sidbuf[6] = abc[n / SID_LEN];
sidbuf[7] = abc[n % SID_LEN];
sidbuf[8] = 0;
p = strdup (sidbuf);
if (!p)
return errno;
*res = p;
return 0;
}
......@@ -393,90 +393,17 @@ pop3d_mainloop (int ifd, int ofd, struct pop3d_srv_config *cfg)
return status;
}
static int
set_strerr_flt ()
{
mu_stream_t flt, trans[2];
int rc;
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET, trans);
if (rc == 0)
{
char sessidstr[10];
char *argv[] = { "inline-comment", NULL, "-S", NULL };
snprintf (sessidstr, sizeof sessidstr, "%08lx:", mu_session_id);
argv[1] = sessidstr;
rc = mu_filter_create_args (&flt, trans[0], "inline-comment", 3,
(const char **)argv,
MU_FILTER_ENCODE, MU_STREAM_WRITE);
mu_stream_unref (trans[0]);
if (rc == 0)
{
mu_stream_set_buffer (flt, mu_buffer_line, 0);
trans[0] = flt;
trans[1] = NULL;
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM,
MU_IOCTL_OP_SET, trans);
mu_stream_unref (trans[0]);
if (rc)
mu_error (_("%s failed: %s"), "MU_IOCTL_SET_STREAM",
mu_stream_strerror (mu_strerr, rc));
}
else
mu_error (_("cannot create log filter stream: %s"), mu_strerror (rc));
}
else
{
mu_error (_("%s failed: %s"), "MU_IOCTL_GET_STREAM",
mu_stream_strerror (mu_strerr, rc));
}
return rc;
}
static void
clr_strerr_flt ()
{
mu_stream_t flt, trans[2];
int rc;
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET, trans);
if (rc == 0)
{
flt = trans[0];
rc = mu_stream_ioctl (flt, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET, trans);
if (rc == 0)
{
mu_stream_unref (trans[0]);
rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM,
MU_IOCTL_OP_SET, trans);
if (rc == 0)
mu_stream_unref (flt);
}
}
}
int
pop3d_connection (int fd, struct sockaddr *sa, int salen,
struct mu_srv_config *pconf,
void *data)
{
struct pop3d_srv_config *cfg = (struct pop3d_srv_config *) pconf;
int rc;
idle_timeout = pconf->timeout;
pop3d_transcript = pconf->transcript;
if (mu_log_session_id)
rc = set_strerr_flt ();
else
rc = 1;
idle_timeout = cfg->m_cfg.timeout;
pop3d_transcript = cfg->m_cfg.transcript;
pop3d_mainloop (fd, fd, cfg);
if (rc == 0)
clr_strerr_flt ();
return 0;
}
......