(I wonder if lladdr is too rarely-used option... :) )

Well, I researched on this problem a bit and wrote a patch, which is
probably low-quality (ideologically wrong) but, at least, fixes the
problem for me.

* Interesting note: line in options.c in current svn got comment '/*
FQDN -- IP address only */' near it and the same problem. Something is
quite wrong here...

P.S. Sorry for quite imperfect English.

-- 
"If everything seems under control, you're not going fast enough"
diff -dpr def/openvpn-2.1~rc9/options.c openvpn-2.1~rc9/options.c
*** def/openvpn-2.1~rc9/options.c	2008-09-05 21:13:50.765908501 +0500
--- openvpn-2.1~rc9/options.c	2008-09-06 12:12:44.089177436 +0500
*************** add_option (struct options *options,
*** 3432,3442 ****
    else if (streq (p[0], "lladdr") && p[1])
      {
        VERIFY_PERMISSION (OPT_P_UP);
!       if (ip_addr_dotted_quad_safe (p[1]))
  	options->lladdr = p[1];
        else
  	{
! 	  msg (msglevel, "lladdr parm '%s' must be an IP address", p[1]);
  	  goto err;
  	}
      }
--- 3432,3442 ----
    else if (streq (p[0], "lladdr") && p[1])
      {
        VERIFY_PERMISSION (OPT_P_UP);
!       if (mac_addr_safe (p[1]))
  	options->lladdr = p[1];
        else
  	{
! 	  msg (msglevel, "lladdr parm '%s' must be an MAC address", p[1]);
  	  goto err;
  	}
      }
diff -dpr def/openvpn-2.1~rc9/socket.c openvpn-2.1~rc9/socket.c
*** def/openvpn-2.1~rc9/socket.c	2008-09-05 21:13:54.719908359 +0500
--- openvpn-2.1~rc9/socket.c	2008-09-06 12:51:34.860177616 +0500
*************** ip_addr_dotted_quad_safe (const char *do
*** 294,299 ****
--- 294,340 ----
    }
  }
  
+ bool
+ mac_addr_safe (const char *mac_addr)
+ {
+   /* verify non-NULL */
+   if (!mac_addr)
+     return false;
+ 
+   /* verify length is within limits */
+   if (strlen (mac_addr) > 17)
+     return false;
+ 
+   /* verify that all chars are either alphanumeric or ':' and that no
+      alphanumeric substring is greater than 2 chars */
+   {
+     int nnum = 0;
+     const char *p = mac_addr;
+     int c;
+ 
+     while ((c = *p++))
+       {
+ 	if ( (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') )
+ 	  {
+ 	    ++nnum;
+ 	    if (nnum > 2)
+ 	      return false;
+ 	  }
+ 	else if (c == ':')
+ 	  {
+ 	    nnum = 0;
+ 	  }
+ 	else
+ 	  return false;
+       }
+   }
+ 
+   /* error-checking is left to script invoked in lladdr.c */
+   return true;
+ 
+ }
+ 
+ 
  static void
  update_remote (const char* host,
  	       struct openvpn_sockaddr *addr,
diff -dpr def/openvpn-2.1~rc9/socket.h openvpn-2.1~rc9/socket.h
*** def/openvpn-2.1~rc9/socket.h	2008-09-05 21:13:47.757908852 +0500
--- openvpn-2.1~rc9/socket.h	2008-09-06 12:10:39.586178166 +0500
*************** void link_socket_update_buffer_sizes (st
*** 397,402 ****
--- 397,403 ----
  #define OIA_ERROR     -1
  int openvpn_inet_aton (const char *dotted_quad, struct in_addr *addr);
  bool ip_addr_dotted_quad_safe (const char *dotted_quad);
+ bool mac_addr_safe (const char *mac_addr);
  
  socket_descriptor_t create_socket_tcp (void);
  

Reply via email to