Re: mailfront on IPv6

Bruce Guenter <[email protected]> Tue, 28 Jun 2011 18:45:19 -0600
Newsgroups gmane.comp.sysutils.bgware
Message-ID <[email protected]>
--NKoe5XOeduwbEQHU
Content-Type: multipart/mixed; boundary="VrqPEDrXMn8OVzN4"
Content-Disposition: inline


--VrqPEDrXMn8OVzN4
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Wed, Jun 22, 2011 at 09:58:02PM -0400, John R. Levine wrote:
> I've been using it for a month or so, and it seems to work fine.

Great.

> There's a buglet in plugin-add-received.  The SMTP spec says that you put=
=20
> IPV6: in front of the IP address, e.g.
>=20
>   Received: from foo (bar [IPV6:2001:2002::123])
>       by zip (zap [IPV6:201a::345]) ; date

So, if $PROTO=3DTCP6 then add this prefix, right?

> The code to add to the routine str_catfromby() is obvious,

Well, not entirely obvious, particularly since the IP is also used in
place of the host name if it's not known, and also when adding a "fixup"
header.  I've attached the patch I'm testing now.

> Unrelated question: has anyone done STARTTLS?  There's patches for=20
> ofmipd or qmail-smtpd that show what you have to do, but it looks to me=
=20
> like the current plugin setup isn't adequate to stick the necessary shims=
=20
> to do the TLS on the way in and out.  I suppose you could do it by making=
=20
> a separate process and pipes, but ugh.

I'd like to do it, but it's not going to be handled by the normal plugin
setup.  Mailfront plugins operate within a somewhat generic protocol,
while STARTTLS needs to front the real wire protocol.

I actually think the separate process and pipes is probably the best way
to go about it, preferably if the parent process can get completely out
of the way, just leaving the TLS translator and a secondary mailfront
instance.

--=20
Bruce Guenter <[email protected]>                http://untroubled.org/

--VrqPEDrXMn8OVzN4
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="add-received-ipv6.patch"
Content-Transfer-Encoding: quoted-printable

diff --git a/plugin-add-received.c b/plugin-add-received.c
index 1ad5982..d767447 100644
--- a/plugin-add-received.c
+++ b/plugin-add-received.c
@@ -11,9 +11,9 @@ static str fixup_ip;
=20
 static const char* linkproto;
 static const char* local_host;
-static const char* local_ip;
+static str local_ip;
 static const char* remote_host;
-static const char* remote_ip;
+static str remote_ip;
=20
 static const char* date_string(void)
 {
@@ -25,10 +25,10 @@ static const char* date_string(void)
 }
=20
 static int str_catfromby(str* s, const char* helo_domain,
-			 const char* host, const char* ip)
+			 const char* host, const str* ip)
 {
   if (helo_domain =3D=3D 0)
-    helo_domain =3D (host !=3D 0) ? host : (ip !=3D 0) ? ip : UNKNOWN;
+    helo_domain =3D (host !=3D 0) ? host : (ip->len > 0) ? ip->s : UNKNOWN;
   if (!str_cats(s, helo_domain)) return 0;
   if (host !=3D 0 || ip !=3D 0) {
     if (!str_cats(s, " (")) return 0;
@@ -39,7 +39,7 @@ static int str_catfromby(str* s, const char* helo_domain,
     }
     if (ip !=3D 0)
       if (!str_catc(s, '[') ||
-	  !str_cats(s, ip) ||
+	  !str_cat(s, ip) ||
 	  !str_catc(s, ']'))
 	return 0;
     if (!str_catc(s, ')')) return 0;
@@ -50,13 +50,13 @@ static int str_catfromby(str* s, const char* helo_domai=
n,
 static int fixup_received(str* s)
 {
   if (local_host &&
-      local_ip &&
+      local_ip.len > 0 &&
       fixup_host.len > 0 &&
       fixup_ip.len > 0 &&
       (strcasecmp(local_host, fixup_host.s) !=3D 0 ||
-       strcasecmp(local_ip, fixup_ip.s) !=3D 0)) {
+       strcasecmp(local_ip.s, fixup_ip.s) !=3D 0)) {
     if (!str_cat3s(s, "Received: from ", local_host, " (")) return 0;
-    if (!str_cat4s(s, local_host, " [", local_ip, "])\n"
+    if (!str_cat4s(s, local_host, " [", local_ip.s, "])\n"
 		   "  by ")) return 0;
     if (!str_cat(s, &fixup_host)) return 0;
     if (!str_cats(s, " ([")) return 0;
@@ -80,10 +80,10 @@ static int build_received(str* s)
 {
   if (!str_cats(s, "Received: from ")) return 0;
   if (!str_catfromby(s, session_getstr("helo_domain"),
-		     remote_host, remote_ip))
+		     remote_host, &remote_ip))
     return 0;
   if (!str_cats(s, "\n  by ")) return 0;
-  if (!str_catfromby(s, local_host, 0, local_ip)) return 0;
+  if (!str_catfromby(s, local_host, 0, &local_ip)) return 0;
   if (!str_cat4s(s, "\n  with ", session_protocol(),
 		 " via ", linkproto))
     return 0;
@@ -91,13 +91,27 @@ static int build_received(str* s)
   return 1;
 }
=20
+static int str_copyip(str* s, const char* ip, int is_ipv6)
+{
+  s->len =3D 0;
+  if (ip !=3D 0) {
+    if (is_ipv6
+	&& !str_copys(s, "IPv6:"))
+      return 0;
+    return str_cats(s, ip);
+  }
+  return 1;
+}
+
 static const response* init(void)
 {
   const char* tmp;
+  int is_ipv6;
=20
   linkproto =3D getprotoenv(0);
-  local_ip =3D getprotoenv("LOCALIP");
-  remote_ip =3D getprotoenv("REMOTEIP");
+  is_ipv6 =3D linkproto !=3D 0 && strcasecmp(linkproto, "TCP6") =3D=3D 0;
+  if (!str_copyip(&local_ip, getprotoenv("LOCALIP"), is_ipv6)) return &res=
p_oom;
+  if (!str_copyip(&remote_ip, getprotoenv("REMOTEIP"), is_ipv6)) return &r=
esp_oom;
   local_host =3D getprotoenv("LOCALHOST");
   remote_host =3D getprotoenv("REMOTEHOST");
=20

--VrqPEDrXMn8OVzN4--

--NKoe5XOeduwbEQHU
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (GNU/Linux)

iEYEARECAAYFAk4KdZ8ACgkQ6W+y3GmZgOjvngCgqpC2mbfM6/8lDjqNKV53HK8N
VNMAnRpUC61ts6EiW4Ca7/v4WFy5HwDt
=BjEo
-----END PGP SIGNATURE-----

--NKoe5XOeduwbEQHU--