Browse code

Fixed --lladdr bug introduced in 2.1-rc9 where input validation code was incorrectly expecting the lladdr parameter to be an IP address when it is actually a MAC address (HoverHell).

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3339 e7ae566f-a301-0410-adde-c780ea21d3b5

james authored on 2008/09/20 05:12:43
Showing 3 changed files
... ...
@@ -3436,11 +3436,11 @@ add_option (struct options *options,
3436 3436
   else if (streq (p[0], "lladdr") && p[1])
3437 3437
     {
3438 3438
       VERIFY_PERMISSION (OPT_P_UP);
3439
-      if (ip_addr_dotted_quad_safe (p[1])) /* FQDN -- IP address only */
3439
+      if (mac_addr_safe (p[1])) /* MAC address only */
3440 3440
 	options->lladdr = p[1];
3441 3441
       else
3442 3442
 	{
3443
-	  msg (msglevel, "lladdr parm '%s' must be an IP address", p[1]);
3443
+	  msg (msglevel, "lladdr parm '%s' must be a MAC address", p[1]);
3444 3444
 	  goto err;
3445 3445
 	}
3446 3446
     }
... ...
@@ -317,6 +317,45 @@ ip_or_dns_addr_safe (const char *addr, const bool allow_fqdn)
317 317
     return false;
318 318
 }
319 319
 
320
+bool
321
+mac_addr_safe (const char *mac_addr)
322
+{
323
+  /* verify non-NULL */
324
+  if (!mac_addr)
325
+    return false;
326
+
327
+  /* verify length is within limits */
328
+  if (strlen (mac_addr) > 17)
329
+    return false;
330
+
331
+  /* verify that all chars are either alphanumeric or ':' and that no
332
+     alphanumeric substring is greater than 2 chars */
333
+  {
334
+    int nnum = 0;
335
+    const char *p = mac_addr;
336
+    int c;
337
+
338
+    while ((c = *p++))
339
+      {
340
+	if ( (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') )
341
+	  {
342
+	    ++nnum;
343
+	    if (nnum > 2)
344
+	      return false;
345
+	  }
346
+	else if (c == ':')
347
+	  {
348
+	    nnum = 0;
349
+	  }
350
+	else
351
+	  return false;
352
+      }
353
+  }
354
+
355
+  /* error-checking is left to script invoked in lladdr.c */
356
+  return true;
357
+}
358
+
320 359
 static void
321 360
 update_remote (const char* host,
322 361
 	       struct openvpn_sockaddr *addr,
... ...
@@ -400,6 +400,7 @@ int openvpn_inet_aton (const char *dotted_quad, struct in_addr *addr);
400 400
 /* integrity validation on pulled options */
401 401
 bool ip_addr_dotted_quad_safe (const char *dotted_quad);
402 402
 bool ip_or_dns_addr_safe (const char *addr, const bool allow_fqdn);
403
+bool mac_addr_safe (const char *mac_addr);
403 404
 
404 405
 socket_descriptor_t create_socket_tcp (void);
405 406