On Mon, Mar 11, 2019 at 05:11:56PM +0100, Otto Moerbeek wrote:

> 
> I was going to test your diff but it does not apply. Your mailer seems
> to convert spaces and or tabs to funny char sequences. Please fix
> (test by mailing to yourself and applying with patch(1)) and resend,
> 
>       -Otto
> 

So I reworked the diff to apply and use the proper formatting
(regulart sapces and tabs instead of UTF-8 non breaking spaces).

I also fixed a case of parsing IPv6 addresses.

Anyone willing to ok?

        -Otto

Index: conf.y
===================================================================
RCS file: /cvs/src/usr.sbin/sasyncd/conf.y,v
retrieving revision 1.19
diff -u -p -r1.19 conf.y
--- conf.y      9 Apr 2017 02:40:24 -0000       1.19
+++ conf.y      12 Mar 2019 12:59:18 -0000
@@ -30,8 +30,10 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
+#include <arpa/inet.h>
 #include <ctype.h>
 #include <fcntl.h>
+#include <ifaddrs.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -48,6 +50,7 @@ struct cfgstate       cfgstate;
 int    conflen = 0;
 char   *confbuf, *confptr;
 
+int check_peer_addr(const char *);
 int    yyparse(void);
 int    yylex(void);
 void   yyerror(const char *);
@@ -172,17 +175,8 @@ setting            : INTERFACE STRING
                | PEER STRING
                {
                        struct syncpeer *peer;
-                       int              duplicate = 0;
 
-                       for (peer = LIST_FIRST(&cfgstate.peerlist); peer;
-                            peer = LIST_NEXT(peer, link))
-                               if (strcmp($2, peer->name) == 0) {
-                                       duplicate++;
-                                       break;
-                               }
-                       if (duplicate)
-                               free($2);
-                       else {
+                       if (check_peer_addr($2)) {
                                peer = calloc(1, sizeof *peer);
                                if (!peer) {
                                        log_err("config: calloc(1, %lu) "
@@ -191,10 +185,11 @@ setting           : INTERFACE STRING
                                        YYERROR;
                                }
                                peer->name = $2;
-                       }
-                       LIST_INSERT_HEAD(&cfgstate.peerlist, peer, link);
-                       cfgstate.peercnt++;
-                       log_msg(2, "config: add peer %s", peer->name);
+                               LIST_INSERT_HEAD(&cfgstate.peerlist, peer, 
link);
+                               cfgstate.peercnt++;
+                               log_msg(2, "config: add peer %s", peer->name);
+                       } else
+                               free($2);
                }
                | LISTEN ON STRING af port
                {
@@ -284,6 +279,72 @@ match(char *token)
 }
 
 int
+check_peer_addr(const char *peer_addr)
+{
+       int valid = 1;
+       short peer_family = AF_UNSPEC;
+       struct ifaddrs *ifap = 0, *ifa;
+       struct syncpeer *peer;
+       struct sockaddr_in sa;
+       struct sockaddr_in6 sa6;
+
+       if (inet_pton(AF_INET, peer_addr, &sa.sin_addr) == 1)
+               peer_family = AF_INET;
+
+       if (peer_family == AF_UNSPEC && inet_pton(AF_INET6, peer_addr,
+           &sa6.sin6_addr) == 1)
+               peer_family = AF_INET6;
+
+       if (peer_family == AF_UNSPEC) {
+               log_msg(2, "config: skip unparseable peer %s", peer_addr);
+               valid = 0;
+       }
+
+       if (valid && getifaddrs(&ifap) == 0) {
+               for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+                       if (!ifa->ifa_addr || ifa->ifa_addr->sa_family !=
+                           peer_family)
+                               continue;
+
+                       switch (ifa->ifa_addr->sa_family) {
+                       case AF_INET:
+                               if (memcmp(&sa.sin_addr,
+                                   &((struct sockaddr_in 
*)ifa->ifa_addr)->sin_addr,
+                                   sizeof(struct in_addr)) == 0) 
+                                       valid = 0;
+                               break;
+                       case AF_INET6:
+                               if (memcmp(&sa6.sin6_addr,
+                                   &((struct sockaddr_in6 
*)ifa->ifa_addr)->sin6_addr,
+                                   sizeof(struct in6_addr)) == 0)
+                                       valid = 0;
+                               break;
+                       }
+
+                       if (!valid) {
+                               log_msg(2, "config: skip local peer %s",
+                                   peer_addr);
+                               break;
+                       }
+               }
+               freeifaddrs(ifap);
+       }
+
+       if (valid) {
+               for (peer = LIST_FIRST(&cfgstate.peerlist); peer;
+                       peer = LIST_NEXT(peer, link)) {
+                       if (strcmp(peer_addr, peer->name) == 0) {
+                               log_msg(2, "config: skip duplicate peer %s",
+                                   peer_addr);
+                               valid = 0;
+                       }
+               }
+       }
+
+       return valid;
+}
+
+int
 yylex(void)
 {
        char *p;
@@ -325,7 +386,7 @@ yylex(void)
        /* Numerical token? */
        if (isdigit(*confptr)) {
                for (p = confptr; *p; p++)
-                       if (*p == '.') /* IP address, or bad input */
+                       if (*p == '.' || *p == ':') /* IP address, or bad input 
*/
                                goto is_string;
                v = (int)strtol(confptr, (char **)NULL, 10);
                yylval.val = v;

Reply via email to