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"