summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2009-02-25 20:12:34 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2009-02-25 20:12:34 (GMT)
commit27d1256d331d45bf68d96e9a8aa8175df2584978 (patch) (side-by-side diff)
treed4e28ce067fa001b7aff5a470c146a6d04eead96
parentc9178a6fef0184baed0e8456bb6c6d4091b4997c (diff)
downloadwydawca-27d1256d331d45bf68d96e9a8aa8175df2584978.tar.gz
wydawca-27d1256d331d45bf68d96e9a8aa8175df2584978.tar.bz2
Check incoming connections using libwrap; various bugfixes.
* configure.ac: Check for libwrap. * src/tcpwrap.c: New file. * src/Makefile.am (wydawca_SOURCES): Add tcpwrap.c * src/builtin.c, src/job.c, src/pidfile.c: Minor fixes. * src/config.c (assert_string_arg): Change to extern. (wydawca_kw): New block statement "tcp-wrapper" * src/net.c (wydawca_listener): Check fd using libwrap. * src/triplet.c (DECL_EXPAND_TIMER): Add missing return statement.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--configure.ac20
-rw-r--r--src/Makefile.am1
-rw-r--r--src/builtin.c1
-rw-r--r--src/config.c10
-rw-r--r--src/job.c29
-rw-r--r--src/net.c45
-rw-r--r--src/pidfile.c4
-rw-r--r--src/tcpwrap.c83
-rw-r--r--src/triplet.c2
-rw-r--r--src/wydawca.h9
10 files changed, 172 insertions, 32 deletions
diff --git a/configure.ac b/configure.ac
index 4f6eaa0..737e2dc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -88,6 +88,26 @@ WD_CHECK_LIB([gpgme],[main],[],
[/usr/pkg/lib /opt/lib /sw/lib])
# **********************
+# TCP wrappers
+# **********************
+AC_ARG_WITH(tcp-wrappers,
+ AC_HELP_STRING([--with-tcp-wrappers],
+ [compile with TCP wrappers support (default)]),
+ [status_tcpwrap=${withval}],
+ [status_tcpwrap=yes])
+
+if test "$status_tcpwrap" = yes; then
+ AC_CHECK_LIB(nsl, main)
+ AC_CHECK_LIB(wrap, main,, [status_tcpwrap=no])
+ if test "$status_tcpwrap" = yes; then
+ AC_CHECK_HEADERS(tcpd.h,,[status_tcpwrap=no])
+ fi
+fi
+if test "$status_tcpwrap" = yes; then
+ AC_DEFINE_UNQUOTED([WITH_LIBWRAP],1,[Defined if compiling with libwrap])
+fi
+
+# **********************
# Preprocessor
# **********************
AC_ARG_WITH([preprocessor],
diff --git a/src/Makefile.am b/src/Makefile.am
index fcfdb78..c91669e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,6 +34,7 @@ wydawca_SOURCES=\
process.c\
sql.c\
sql.h\
+ tcpwrap.c\
triplet.c\
verify.c\
wydawca.c\
diff --git a/src/builtin.c b/src/builtin.c
index 90b7c2f..d70a511 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -183,7 +183,6 @@ builtin_run (struct access_method *meth, void *handle, const char *req)
for (i = 0; i < meth->parmc; i++)
{
char *pat = meth->parmv[i];
- char *val;
if (pat[0] == '/')
{
diff --git a/src/config.c b/src/config.c
index bab1ed3..b1f339f 100644
--- a/src/config.c
+++ b/src/config.c
@@ -216,7 +216,7 @@ string_to_notification_target (gconf_locus_t *locus, const char *val,
}
-static int
+int
assert_string_arg (gconf_locus_t *locus,
enum gconf_callback_command cmd,
const gconf_value_t *value)
@@ -1147,7 +1147,6 @@ cb_spool (enum gconf_callback_command cmd,
struct spool *spool;
void **pdata = cb_data;
int rc, ec, i;
- const char *ep = NULL;
switch (cmd)
{
@@ -1247,6 +1246,13 @@ static struct gconf_keyword wydawca_kw[] = {
{ "listen", N_("socket"), N_("Listen on this address"),
gconf_type_sockaddr, &listen_sockaddr, },
+
+#ifdef WITH_LIBWRAP
+ { "tcp-wrapper", NULL, N_("Configure TCP wrappers"),
+ gconf_type_section, NULL, 0,
+ NULL, NULL, tcpwrapper_kw },
+#endif
+
{ "mailer", N_("url"), N_("Set mailer URL"),
gconf_type_string, &mailer, 0, cb_mailer },
{ "admin-address", N_("email"), N_("Set admin email address"),
diff --git a/src/job.c b/src/job.c
index 2c177cb..1baa0af 100644
--- a/src/job.c
+++ b/src/job.c
@@ -99,7 +99,8 @@ job_start (struct job *job)
}
if (debug_level)
- logmsg (LOG_DEBUG, _("starting job: %s, %lu"), job->spool->tag, job->uid);
+ logmsg (LOG_DEBUG, _("starting job: %s, %lu"),
+ job->spool->tag, (unsigned long)job->uid);
if (single_process)
{
@@ -113,6 +114,14 @@ job_start (struct job *job)
pid = fork ();
if (pid == 0)
{
+ int i;
+ signal (SIGHUP, SIG_DFL);
+ signal (SIGTERM, SIG_DFL);
+ signal (SIGQUIT, SIG_DFL);
+ signal (SIGINT, SIG_DFL);
+ signal (SIGCHLD, SIG_DFL);
+ for (i = getdtablesize (); i > 2; i--)
+ close (i);
exit (wydawca_scanner (job) ? WYDAWCA_EX_AGAIN : 0);
}
else if (pid == -1)
@@ -135,7 +144,8 @@ job_remove (struct job *job)
struct job *p;
if (debug_level)
- logmsg (LOG_DEBUG, _("removing job: %s, %lu"), job->spool->tag, job->uid);
+ logmsg (LOG_DEBUG, _("removing job: %s, %lu"),
+ job->spool->tag, (unsigned long)job->uid);
p = job->prev;
if (p)
p->next = job->next;
@@ -169,7 +179,7 @@ job_insert (struct job *job, struct job *elt)
p->prev = job;
}
-int
+void
schedule_job (const struct spool *spool, uid_t uid)
{
struct job *job;
@@ -178,7 +188,8 @@ schedule_job (const struct spool *spool, uid_t uid)
spool = &fake_spool;
if (debug_level)
- logmsg (LOG_DEBUG, _("scheduling job: %s, %lu"), spool->tag, uid);
+ logmsg (LOG_DEBUG, _("scheduling job: %s, %lu"),
+ spool->tag, (unsigned long)uid);
job = job_locate (spool, uid);
if (!job)
@@ -230,22 +241,24 @@ print_status (struct job *job, int expect_term)
logmsg (prio,
_("%lu (%s, %s) terminated on signal %d"),
- job->pid, job->spool->tag, pw->pw_name, WTERMSIG (status));
+ (unsigned long)job->pid, job->spool->tag,
+ pw->pw_name, WTERMSIG (status));
}
else if (WIFSTOPPED (status))
logmsg (LOG_NOTICE,
_("%lu (%s, %s) stopped on signal %d"),
- job->pid, job->spool->tag, pw->pw_name, WSTOPSIG (status));
+ (unsigned long)job->pid, job->spool->tag,
+ pw->pw_name, WSTOPSIG (status));
#ifdef WCOREDUMP
else if (WCOREDUMP (status))
logmsg (LOG_NOTICE,
_("%lu (%s, %s) dumped core"),
- job->pid, job->spool->tag, pw->pw_name);
+ (unsigned long)job->pid, job->spool->tag, pw->pw_name);
#endif
else
logmsg (LOG_ERR,
_("%lu (%s, %s) terminated with unrecognized status"),
- job->pid, job->spool->tag, pw->pw_name);
+ (unsigned long)job->pid, job->spool->tag, pw->pw_name);
}
void
diff --git a/src/net.c b/src/net.c
index 3874827..25bb4da 100644
--- a/src/net.c
+++ b/src/net.c
@@ -52,8 +52,7 @@ open_listener ()
/* FIXME: Check permissions? */
if (!S_ISSOCK (st.st_mode))
{
- logmsg (LOG_CRIT, _("%s: not a socket"),
- s_un->sun_path, strerror (errno));
+ logmsg (LOG_CRIT, _("%s: not a socket"), s_un->sun_path);
exit (EX_OSFILE);
}
unlink (s_un->sun_path);
@@ -94,17 +93,17 @@ trim_crlf (char *s)
s[--len] = 0;
}
}
-
+
void
-handle_connection (FILE *fp)
+handle_connection (FILE *in, FILE *out)
{
char *buf = NULL;
size_t buflen = 0;
const struct spool *spool;
char *p;
struct passwd *pw;
-
- if (getline (&buf, &buflen, fp) <= 0)
+
+ if (getline (&buf, &buflen, in) <= 0)
return;
trim_crlf (buf);
if (debug_level)
@@ -113,20 +112,20 @@ handle_connection (FILE *fp)
if (!spool)
{
if (all_spool_aliases && gl_list_search (all_spool_aliases, buf))
- fprintf (fp, "+ OK, all spools\r\n");
+ fprintf (out, "+ OK, all spools\r\n");
else
{
- fprintf (fp, "- Unknown service name\r\n");
+ fprintf (out, "- Unknown service name\r\n");
free (buf);
return;
}
}
else if (spool->url)
- fprintf (fp, "+ OK, URL %s\r\n", spool->url);
+ fprintf (out, "+ OK, URL %s\r\n", spool->url);
else
- fprintf (fp, "+ OK, spool %s\r\n", spool->tag);
-
- if (getline (&buf, &buflen, fp) <= 0)
+ fprintf (out, "+ OK, spool %s\r\n", spool->tag);
+
+ if (getline (&buf, &buflen, in) < 0)
{
logmsg (LOG_ERR, "protocol error");
free (buf);
@@ -184,7 +183,7 @@ wydawca_listener ()
while (!terminate)
{
int fd;
- FILE *fp;
+ FILE *in, *out;
int rc;
fd_set rset;
struct timeval to, *pto;
@@ -223,10 +222,22 @@ wydawca_listener ()
fd = accept (ctlfd, (struct sockaddr*) &addr, &len);
if (fd == -1)
continue;
- /* FIXME: Check if the connection is allowed */
- fp = fdopen (fd, "r+");
- handle_connection (fp);
- fclose (fp);
+ /* FIXME: Use Mailutils ACLs? */
+#ifdef WITH_LIBWRAP
+ if (!tcpwrap_access(fd))
+ {
+ close(fd);
+ continue;
+ }
+#endif
+
+ in = fdopen (fd, "r");
+ setlinebuf (in);
+ out = fdopen (fd, "w");
+ setlinebuf (out);
+ handle_connection (in, out);
+ fclose (in);
+ fclose (out);
}
}
diff --git a/src/pidfile.c b/src/pidfile.c
index 6da84f1..afbcb87 100644
--- a/src/pidfile.c
+++ b/src/pidfile.c
@@ -34,7 +34,7 @@ check_pidfile ()
if (fp)
{
unsigned long pid;
- if (fscanf (fp, "%ul\n", &pid) != 1)
+ if (fscanf (fp, "%lu\n", &pid) != 1)
{
logmsg (LOG_ERR, _("malformed pidfile %s"), pidfile);
if (!force_startup)
@@ -82,7 +82,7 @@ check_pidfile ()
exit (EX_UNAVAILABLE);
}
}
- fprintf (fp, "%lu\n", getpid ());
+ fprintf (fp, "%lu\n", (unsigned long) getpid ());
fclose (fp);
atexit (remove_pidfile);
}
diff --git a/src/tcpwrap.c b/src/tcpwrap.c
new file mode 100644
index 0000000..eccf21b
--- a/dev/null
+++ b/src/tcpwrap.c
@@ -0,0 +1,83 @@
+/* wydawca - automatic release submission daemon
+ Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff
+
+ Wydawca is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+ Wydawca 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with wydawca. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "wydawca.h"
+#include <mailutils/syslog.h>
+
+#ifdef WITH_LIBWRAP
+# include <tcpd.h>
+
+static int tcpwrap_enable;
+static char *tcpwrap_daemon;
+int deny_severity = LOG_INFO;
+int allow_severity = LOG_INFO;
+
+static int
+cb_syslog_priority (enum gconf_callback_command cmd,
+ gconf_locus_t *locus,
+ void *varptr,
+ gconf_value_t *value,
+ void *cb_data)
+{
+ if (assert_string_arg (locus, cmd, value))
+ return 1;
+
+ if (mu_string_to_syslog_priority (value->v.string, varptr))
+ gconf_error (locus, 0, _("Unknown syslog priority `%s'"),
+ value->v.string);
+ return 0;
+}
+
+struct gconf_keyword tcpwrapper_kw[] = {
+ { "enable", NULL,
+ N_("Enable TCP wrapper access control. Default is \"yes\"."),
+ gconf_type_bool, &tcpwrap_enable },
+ { "daemon", N_("name"),
+ N_("Set daemon name for TCP wrapper lookups. Default is program name."),
+ gconf_type_string, &tcpwrap_daemon },
+ { "allow-table", N_("file"),
+ N_("Use file for positive client address access control "
+ "(default: /etc/hosts.allow)."),
+ gconf_type_string, &hosts_allow_table },
+ { "deny-table", N_("file"),
+ N_("Use file for negative client address access control "
+ "(default: /etc/hosts.deny)."),
+ gconf_type_string, &hosts_deny_table },
+ { "allow-syslog-priority", N_("prio"),
+ N_("Log host allows at this syslog priority."),
+ gconf_type_string, &allow_severity, 0, cb_syslog_priority },
+ { "deny-syslog-priority", N_("prio"),
+ N_("Log host denies at this syslog priority."),
+ gconf_type_string, &deny_severity, 0, cb_syslog_priority },
+ { NULL }
+};
+
+int
+tcpwrap_access(int fd)
+{
+ struct request_info req;
+
+ if (!tcpwrap_enable)
+ return 1;
+ request_init(&req,
+ RQ_DAEMON,
+ tcpwrap_daemon ? tcpwrap_daemon : program_name,
+ RQ_FILE, fd, NULL);
+ fromhost(&req);
+ return hosts_access(&req);
+}
+
+#endif
diff --git a/src/triplet.c b/src/triplet.c
index 285c831..a79d28a 100644
--- a/src/triplet.c
+++ b/src/triplet.c
@@ -566,7 +566,7 @@ __cat2__(expand_timer_,what) (struct metadef *def, void *data) \
{ \
wydawca_timer_t t = timer_stop ((char*)def->data); \
def->storage = timer_format_time (__cat2__(timer_get_,what) (t)); \
- def->value = def->storage; \
+ return def->value = def->storage; \
}
DECL_EXPAND_TIMER(real)
diff --git a/src/wydawca.h b/src/wydawca.h
index f093504..863200f 100644
--- a/src/wydawca.h
+++ b/src/wydawca.h
@@ -437,6 +437,8 @@ int parse_time_interval (const char *str, time_t *pint, const char **endp);
/* config.c */
void config_init (void);
void config_help (void);
+int assert_string_arg (gconf_locus_t *, enum gconf_callback_command,
+ const gconf_value_t *);
/* vtab.c */
@@ -505,7 +507,7 @@ extern char *report_string;
/* job.c */
-int schedule_job (const struct spool *spool, uid_t uid);
+void schedule_job (const struct spool *spool, uid_t uid);
void job_init (void);
void job_queue_runner (void);
@@ -529,3 +531,8 @@ char *wydawca_lockname (const char *tag);
int wydawca_lock (const char *lockname);
void wydawca_unlock (const char *lockname);
void wydawca_lock_init (void);
+
+
+/* tcpwrap.h */
+extern struct gconf_keyword tcpwrapper_kw[];
+int tcpwrap_access(int fd);

Return to:

Send suggestions and report system problems to the System administrator.