Package: ssmtp
Version: 2.61-6kb2
Severity: normal
Tags: patch

It's nice to see that the upcoming version enables IPv6 support, however,
the issue of numeric IPv6 addresses is still open.

So, here's a patch.  I used URL-style method of escaping: [1:2::3] -- IMO
it's much cleaner than exim4-style doubling of colons: 1::2::::3 or
replacing them with a random character: 1|2||3.


-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/dash
Kernel: Linux 2.6.16-2-686
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
--- ../trunk/ssmtp.c	2006-06-01 17:06:47.776447000 +0200
+++ ssmtp.c	2006-06-08 00:49:56.973094750 +0200
@@ -162,7 +162,7 @@
 	}
 
 	if(pw == (struct passwd *)NULL) {
-		/* Far to early to save things */
+		/* Far too early to save things */
 		if(log_level > 0) {
 			log_event(LOG_ERR, "No sender failing horribly!");
 		}
@@ -374,6 +374,50 @@
 }
 
 /*
+hostport() -- Parse host and port, updating globals accordingly
+*/
+void hostport(char *p, char *delim)
+{
+	char *right;
+
+	if (*p=='[')
+	{
+		if (!(right = strchr(p, ']')))
+			die("hostport() -- unmatched '['");
+		if (!(mailhost = strndup(p+1, right-p-1)))
+			die("hostport() -- strndup() failed");
+		
+		if (right[1] && !strchr(delim, right[1]))
+			die("hostport() -- cruft after ']'");
+		p=right+1;
+	}
+	else
+	{
+		if (!(right = strpbrk(p, delim)))
+			right = strchr(p, 0);
+		if (p==right)
+			die("hostport() -- null host");
+		if (!(mailhost = strndup(p, right-p)))
+			die("hostport() -- strndup() failed");
+		p=right;
+	}
+	
+	while(*p && strchr(delim,*p))
+		p++;
+	if (isdigit(*p))
+	{
+		port=strtoul(p, 0, 10);
+		if (port<=0 || port>65535)
+			die("hostport() -- invalid port number");
+	}
+
+	if(log_level > 0) {
+		log_event(LOG_INFO, "Set MailHub=\"%s\"\n", mailhost);
+		log_event(LOG_INFO, "Set RemotePort=\"%d\"\n", port);
+	}
+}
+
+/*
 revaliases() -- Parse the reverse alias file
 	Fix globals to use any entry for sender
 */
@@ -404,20 +448,8 @@
 					}
 				}
 
-				if((p = strtok(NULL, " \t\r\n:"))) {
-					if((mailhost = strdup(p)) == (char *)NULL) {
-						die("revaliases() -- strdup() failed");
-					}
-
-					if((p = strtok(NULL, " \t\r\n:"))) {
-						port = atoi(p);
-					}
-
-					if(log_level > 0) {
-						log_event(LOG_INFO, "Set MailHub=\"%s\"\n", mailhost);
-						log_event(LOG_INFO,
-							"via SMTP Port Number=\"%d\"\n", port);
-					}
+				if((p = strtok(NULL, "\r\n"))) {
+					hostport(p, ": \t");
 				}
 			}
 		}
@@ -828,7 +860,7 @@
  * 		The set of delimiters.
  * Return value:
  *	The first token, copied by strndup (caller have to free it),
- * 	if a token is found, or NULL if isn't (os strndup fails)
+ * 	if a token is found, or NULL if isn't (or strndup fails)
  * 	*s points to the rest of the string
  */
 char *firsttok(char **s, const char *delim)
@@ -894,19 +926,7 @@
 				}
 			}
 			else if(strcasecmp(p, "MailHub") == 0) {
-				if((mailhost = strdup(q)) == (char *)NULL) {
-					die("parse_config() -- strdup() failed");
-				}
-
-				if((r = firsttok(&begin, "= \t\n:")) != NULL) {
-					port = atoi(r);
-					free(r);
-				}
-
-				if(log_level > 0) {
-					log_event(LOG_INFO, "Set MailHub=\"%s\"\n", mailhost);
-					log_event(LOG_INFO, "Set RemotePort=\"%d\"\n", port);
-				}
+				hostport(rightside, "= \t\n:");
 			}
 			else if(strcasecmp(p, "HostName") == 0) {
 				free(hostname);
@@ -1146,6 +1166,21 @@
 #endif
 
 #ifdef INET6
+	/* Allow escaping addresses with [] */
+	if (*host=='[')
+	{
+		char *right = strchr(host, ']');
+		if (!right) {
+			log_event(LOG_ERR, "Unmatched ']' in %s", host);
+			return(-1);
+		}
+		if (right[1]) {
+			log_event(LOG_ERR, "Cruft after ']' in %s", host);
+			return(-1);
+		}
+		host=strndup(host+1, right-host-1);
+	}
+
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_family = p_family;
 	hints.ai_socktype = SOCK_STREAM;
@@ -1382,7 +1417,7 @@
 handler() -- A "normal" non-portable version of an alarm handler
 			Alas, setting a flag and returning is not fully functional in
 			BSD: system calls don't fail when reading from a ``slow'' device
-			like a socket. So we longjump instead, which is erronious on
+			like a socket. So we longjump instead, which is erroneous on
 			a small number of machines and ill-defined in the language
 */
 void handler(void)
--- ../trunk/debian/config	2006-06-01 17:06:47.776447000 +0200
+++ debian/config	2006-06-08 01:30:43.513994000 +0200
@@ -15,7 +15,19 @@
 	db_set ssmtp/root "$root"
 	if [ -n "$mailhub" ]
 	then
-		if [ `expr index "$mailhub" :` -ne 0 ]
+		if echo "$mailhub"|grep -q '^\['
+		then
+			port="${mailhub#\[*\]}"
+			port="${port#:}"
+			if [ -n "$port" ]
+			then
+				db_set ssmtp/port "$port"
+			else
+				db_set ssmtp/port 25
+			fi
+			mailhub="${mailhub:1}"
+			db_set ssmtp/mailhub "${mailhub%]*}"
+		elif [ `expr index "$mailhub" :` -ne 0 ]
 		then
 			db_set ssmtp/port "${mailhub#*:}"
 			db_set ssmtp/mailhub "${mailhub%:*}"
--- ../trunk/debian/postinst	2006-06-01 17:06:47.776447000 +0200
+++ debian/postinst	2006-06-08 01:21:43.364236750 +0200
@@ -15,6 +15,10 @@
 
 db_get ssmtp/mailhub
 mailhub="${RET:-mail}"
+if test "$mailhub" != "${mailhub/:/}"
+then
+	mailhub="[$mailhub]"
+fi
 
 db_get ssmtp/port
 port="$RET"

Reply via email to