Commit Diff


commit - a04936c92b2a7823bd2b7696e4ac8cb1dcaac0e6
commit + 4574fbd094b0b258d32078f6feb25547df97a8de
blob - 0c1414fbb658de7a0d751983512466dc20244838
blob + 2eaa14e61a0d7ee3891732a2843c21671c18fbf9
--- opensmtpd.c
+++ opensmtpd.c
@@ -1941,8 +1941,9 @@ osmtpd_addrtoss(char *addr, struct sockaddr_storage *s
 	struct sockaddr_in *sin;
 	struct sockaddr_in6 *sin6;
 	struct sockaddr_un *sun;
+	size_t n;
 
-	if (strncasecmp(addr, "ipv6:", 5) == 0) {
+	if (addr[0] == '[') {
 		sin6 = (struct sockaddr_in6 *)ss;
 		sin6->sin6_len = sizeof(*sin6);
 		sin6->sin6_family = AF_INET6;
@@ -1951,25 +1952,38 @@ osmtpd_addrtoss(char *addr, struct sockaddr_storage *s
 			if ((port = strrchr(addr, ':')) == NULL)
 				osmtpd_errx(1, "Invalid line received: invalid "
 				    "address (%s): %s", addr, linedup);
+			if (port[-1] != ']')
+				osmtpd_errx(1, "Invalid line received: invalid "
+				    "address (%s): %s", addr, linedup);
 			port++;
 			sin6->sin6_port = htons(strtonum(port, 0, UINT16_MAX,
 			    &errstr));
 			if (errstr != NULL)
 				osmtpd_errx(1, "Invalid line received: invalid "
 				    "address (%s): %s", addr, linedup);
-			port[-1] = '\0';
+			port[-2] = '\0';
+		} else {
+			n = strlen(addr);
+			if (addr[n - 1] != ']')
+				osmtpd_errx(1, "Invalid line received: invalid "
+				    "address (%s): %s", addr, linedup);
+			addr[n - 1] = '\0';
 		}
-		switch (inet_pton(AF_INET6, addr + 5, &(sin6->sin6_addr))) {
+		switch (inet_pton(AF_INET6, addr + 1, &(sin6->sin6_addr))) {
 		case 1:
 			break;
 		case 0:
 			if (hasport)
-				port[-1] = ':';
+				port[-2] = ']';
+			else
+				addr[n - 1] = ']';
 			osmtpd_errx(1, "Invalid line received: invalid address "
 			    "(%s): %s", addr, linedup);
 		default:
 			if (hasport)
-				port[-1] = ':';
+				port[-2] = ']';
+			else
+				addr[n - 1] = ']';
 			osmtpd_err(1, "Can't parse address (%s): %s", addr,
 			    linedup);
 		}