summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2008-06-30 17:12:29 +0000
committerStef Walter <stef@memberwebs.com>2008-06-30 17:12:29 +0000
commit04498c8e4f2fbe89174bf04b82bb9ed552bf3314 (patch)
treec9ec7f18484ac8167d5fcedd269bdc0afcb9f1e9
parent7561cc8758be2f1d17d1e856a8e268d3fcf402b3 (diff)
Release 1.10
-rw-r--r--ChangeLog4
-rw-r--r--configure.in4
-rw-r--r--doc/Makefile.am6
-rw-r--r--doc/clamsmtpd.816
-rwxr-xr-xdoc/man2html.pl230
-rw-r--r--src/clamsmtpd.c4
6 files changed, 261 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 0a9d15b..42b2279 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+1.10 [2007-06-30]
+ - Make the XFOWARD HELO available as a environment variable in scripts. [Glenn Matthys]
+ - Send an RSET to the server after filter fails an email.
+
1.9 [2007-05-28]
- Resolve any DNS name for each connection.
- Use my real name 'Stefan Walter'
diff --git a/configure.in b/configure.in
index 86c2775..895a099 100644
--- a/configure.in
+++ b/configure.in
@@ -36,8 +36,8 @@ dnl Stef Walter <stef@memberwebs.com>
dnl
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(clamsmtp, 1.9, stef@memberwebs.com)
-AM_INIT_AUTOMAKE(clamsmtp, 1.9)
+AC_INIT(clamsmtp, 1.10, stef@memberwebs.com)
+AM_INIT_AUTOMAKE(clamsmtp, 1.10)
LDFLAGS="$LDFLAGS -L/usr/local/lib"
CFLAGS="$CFLAGS -I/usr/local/include"
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 44dfc12..e2e8cad 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,3 +1,9 @@
man_MANS = clamsmtpd.8 clamsmtpd.conf.5
EXTRA_DIST = $(man_MANS) clamsmtpd.conf
+
+# Simple way to make docs
+html:
+ perl man2html.pl clamsmtpd.8 > clamsmtpd.html
+ perl man2html.pl clamsmtpd.conf.5 > clamsmtpd.conf.html
+
diff --git a/doc/clamsmtpd.8 b/doc/clamsmtpd.8
index 887efbe..0c11dcc 100644
--- a/doc/clamsmtpd.8
+++ b/doc/clamsmtpd.8
@@ -168,6 +168,22 @@ option is enabled, this specifies the file that the virus was saved to.
.It Ar RECIPIENTS
The email addresses of the email recipients. These are specified one per
line, in standard address format.
+.It Ar REMOTE
+If
+.Nm
+is being used to filter email between SMTP servers, then this is the
+IP address of the original client. In order for this information to be present
+(a) the SMTP client (sending server) must an send an XFORWARD command and (b)
+the SMTP server (receiving server) must accept that XFORWARD command without
+error.
+.It Ar REMOTE_HELO
+If
+.Nm
+is being used to filter email between SMTP servers, then this is the
+HELO/EHLO banner of the original client. In order for this information to be present
+(a) the SMTP client (sending server) must an send an XFORWARD command and (b)
+the SMTP server (receiving server) must accept that XFORWARD command without
+error.
.It Ar SENDER
The email address for the sender of the email.
.It Ar SERVER
diff --git a/doc/man2html.pl b/doc/man2html.pl
new file mode 100755
index 0000000..a6a7c3f
--- /dev/null
+++ b/doc/man2html.pl
@@ -0,0 +1,230 @@
+#!/usr/bin/perl
+
+# TODO: We need to make this more resilient
+# currently expects args without enforcing
+
+$FIL = $NAM = $SEC = @ARGV[0];
+
+$NAM =~ s/^([^.]+)\..+$/$1/;
+$SEC =~ s/^.+\.([^.]+)$/$1/;
+
+$command = "groff";
+@args = split(" ", "-Tascii -mdoc $FIL");
+
+$enable_include_links = 0;
+
+man($NAM, $SEC);
+
+sub man {
+ local($name, $section) = @_;
+ local($_, $title, $head, *MAN);
+ local($html_name, $html_section, $prefix);
+ local(@manargs);
+ local($query) = $name;
+
+ # $section =~ s/^([0-9ln]).*$/$1/;
+ $section =~ tr/A-Z/a-z/;
+
+ $prefix = "Man ";
+ if ($alttitle) {
+ $prefix = "";
+ $title = &encode_title($alttitle);
+ $head = &encode_data($alttitle);
+ } elsif ($section) {
+ $title = &encode_title("${name}($section)");
+ $head = &encode_data("${name}($section)");
+ } else {
+ $title = &encode_title("${name}");
+ $head = &encode_data("${name}");
+ }
+
+ print &html_header("$title");
+ print "<H1>Man Page: ${title}</H1>";
+ print "<PRE>\n";
+
+ $html_name = &encode_data($name);
+ $html_section = &encode_data($section);
+
+ #print Dumper($sectionpath);
+ #print "yy $section yy $manpath\n";
+ if ($name =~ /^\s*$/) {
+ print "Empty input, no man page given.\n";
+ return;
+ }
+
+ if (index($name, '*') != -1) {
+ print "Invalid character input '*': $name\n";
+ return;
+ }
+
+ if ($section !~ /^[0-9ln]\w*$/ && $section ne '') {
+ print "Sorry, section `$section' is not valid\n";
+ return;
+ }
+
+ if (!$section) {
+ if ($sectionpath->{$manpath}) {
+ $section = "-S " . $sectionpath->{$manpath}{'path'};
+ } else {
+ $section = '';
+ }
+ } else {
+ if ($sectionpath->{$manpath}{$section}) {
+ $section = "-S " . $sectionpath->{$manpath}{$section};
+ } else {
+ $section = "-S $section";
+ }
+ }
+
+ # print "X $command{'man'} @manargs -- x $name x\n";
+ &proc(*MAN, $command, @args) ||
+ &mydie ("$0: open of $command{'man'} command failed: $!\n");
+ if (eof(MAN)) {
+ # print "X $command{'man'} @manargs -- x $name x\n";
+ print "Sorry, no data found for `$html_name" .
+ ($html_section ? "($html_section)": '') . "'.\n";
+ return;
+ }
+
+ local($space) = 1;
+ local(@sect);
+ local($i, $j);
+ while(<MAN>) {
+ # remove tailing white space
+ if (/^\s+$/) {
+ next if $space;
+ $space = 1;
+ } else {
+ $space = 0;
+ }
+
+ $_ = &encode_data($_);
+ if($enable_include_links &&
+ m,(<B>)?\#include(</B>)?\s+(<B>)?\&lt\;(.*\.h)\&gt\;(</B>)?,) {
+ $match = $4; ($regexp = $match) =~ s/\./\\\./;
+ s,$regexp,\<A HREF=\"$BASE/usr/include/$match\"\>$match\</A\>,;
+ }
+ /^\s/ && # skip headers
+ s,((<[IB]>)?[\w\_\.\-]+\s*(</[IB]>)?\s*\(([1-9ln][a-zA-Z]*)\)),&mlnk($1),oige;
+
+ # detect E-Mail Addreses in manpages
+ if (/\@/) {
+ s/([a-z0-9_\-\.]+\@[a-z0-9\-\.]+\.[a-z]+)/<A HREF="mailto:$1">$1<\/A>/gi;
+ }
+
+ # detect URLs in manpages
+ if (m%tp://%) {
+ s,((ftp|http)://[^\s<>\)]+),<A HREF="$1">$1</A>,gi;
+ }
+
+ if (/^<B>\S+/ && m%^<B>([^<]+)%) {
+ $i = $1; $j = &encode_url($i);
+ s%^<B>([^<]+)</B>%<B>$i</B>%;
+ push(@sect, $1);
+ }
+ print;
+ }
+ close(MAN);
+
+ print "<H6>&nbsp;&nbsp;&nbsp;[ <a href='./'>back</a> | <a href='../../'>home</a> ]</h6>";
+ print "</BODY>\n";
+ print "</HTML>\n";
+
+ # Sleep 0.35 seconds to avoid DoS attacs
+ select undef, undef, undef, 0.35;
+}
+
+# encode unknown data for use in <TITLE>...</TITILE>
+sub encode_title {
+ # like encode_url but less strict (I couldn't find docs on this)
+ local($_) = @_;
+ s/([\000-\031\%\&\<\>\177-\377])/sprintf('%%%02x',ord($1))/eg;
+ $_;
+}
+
+# encode unknown data for use in a URL <A HREF="...">
+sub encode_url {
+ local($_) = @_;
+ # rfc1738 says that ";"|"/"|"?"|":"|"@"|"&"|"=" may be reserved.
+ # And % is the escape character so we escape it along with
+ # single-quote('), double-quote("), grave accent(`), less than(<),
+ # greater than(>), and non-US-ASCII characters (binary data),
+ # and white space. Whew.
+ s/([\000-\032\;\/\?\:\@\&\=\%\'\"\`\<\>\177-\377 ])/sprintf('%%%02x',ord($1))/eg;
+ s/%20/+/g;
+ $_;
+}
+# encode unknown data for use inside markup attributes <MARKUP ATTR="...">
+sub encode_attribute {
+ # rfc1738 says to use entity references here
+ local($_) = @_;
+ s/([\000-\031\"\'\`\%\&\<\>\177-\377])/sprintf('\&#%03d;',ord($1))/eg;
+ $_;
+}
+# encode unknown text data for using as HTML,
+# treats ^H as overstrike ala nroff.
+sub encode_data {
+ local($_) = @_;
+ local($str);
+
+ # Escape &, < and >
+ s,\010[><&],,g;
+ s/\&/\&amp\;/g;
+ s/\</\&lt\;/g;
+ s/\>/\&gt\;/g;
+
+ s,((_\010.)+),($str = $1) =~ s/.\010//g; "<I>$str</I>";,ge;
+ s,(.\010)+,$1,g;
+
+ if (!s,((.\010.)+\s+(.\010.)+),($str = $1) =~ s/.\010//g; "<B>$str</B>";,ge) {
+ s,((.\010.)+),($str = $1) =~ s/.\010//g; "<B>$str</B>";,ge;
+ }
+
+ s,.\010,,g;
+
+ $_;
+}
+
+sub html_header {
+ return qq{<HTML>
+<HEAD>
+<TITLE>$_[0]</TITLE>
+<link rev="made" href="mailto:wosch\@FreeBSD.ORG">
+<META name="robots" content="nofollow">
+<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
+<link rel="stylesheet" type="text/css" href="/swalter/style.css">
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000">\n\n};
+}
+
+sub mlnk {
+ local($matched) = @_;
+ return qq{<U>$matched</U>};
+}
+
+sub proc {
+ local(*FH, $prog, @args) = @_;
+ local($pid) = open(FH, "-|");
+ return undef unless defined($pid);
+ if ($pid == 0) {
+ exec $prog, @args;
+ &mydie("exec $prog failed\n");
+ }
+ 1;
+}
+
+# CGI script must die with error status 0
+sub mydie {
+ local($message) = @_;
+ print &html_header("Error");
+ print $message;
+
+print qq{
+<p>
+<A HREF="$BASE">Index Page and Help</A>
+</BODY>
+</HTML>
+};
+
+ exit(0);
+}
diff --git a/src/clamsmtpd.c b/src/clamsmtpd.c
index ab14081..deee41f 100644
--- a/src/clamsmtpd.c
+++ b/src/clamsmtpd.c
@@ -709,7 +709,9 @@ static int virus_action(clctx_t* ctx, const char* virus)
if(g_clstate.quarantine)
{
strlcpy(qfilename, g_clstate.directory, MAXPATHLEN);
- strlcat(qfilename, "/virus.", MAXPATHLEN);
+ if (qfilename[strlen(qfilename) - 1] != '/')
+ strlcat(qfilename, "/", MAXPATHLEN);
+ strlcat(qfilename, "virus.", MAXPATHLEN);
/* Points to null terminator */
t = qfilename + strlen(qfilename);