Browse code

Added additional warnings to flag common gotchas:

* Warn when ethernet bridging that the IP address of the
bridge adapter is probably not the same address that
the LAN adapter was set to previously.

* When running as a server, warn if the LAN network address is
the all-popular 192.168.[0|1].x, since this condition commonly
leads to subnet conflicts down the road.

* Primarily on the client, check for subnet conflicts between
the local LAN and the VPN subnet.

Added a 'netmask' parameter to get_default_gateway, to return
the netmask of the adapter containing the default gateway.
Only implemented on Windows so far. Other platforms will
return 255.255.255.0. Currently the netmask information is
only used to warn about subnet conflicts.


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

james authored on 2008/08/05 13:44:31
Showing 5 changed files
... ...
@@ -1957,6 +1957,9 @@ do_option_warnings (struct context *c)
1957 1957
     msg (M_WARN, "WARNING: using --pull/--client and --ifconfig together is probably not what you want");
1958 1958
 
1959 1959
 #if P2MP_SERVER
1960
+  if (o->server_bridge_defined | o->server_bridge_proxy_dhcp)
1961
+    msg (M_WARN, "NOTE: when bridging your LAN adapter with the TAP adapter, note that the new bridge adapter will often take on its own IP address that is different from what the LAN adapter was previously set to");
1962
+
1960 1963
   if (o->mode == MODE_SERVER)
1961 1964
     {
1962 1965
       if (o->duplicate_cn && o->client_config_dir)
... ...
@@ -1976,6 +1979,8 @@ do_option_warnings (struct context *c)
1976 1976
     msg (M_WARN, "WARNING: You have disabled Crypto IVs (--no-iv) which may make " PACKAGE_NAME " less secure");
1977 1977
 
1978 1978
 #ifdef USE_SSL
1979
+  if (o->tls_server)
1980
+    warn_on_use_of_common_subnets ();
1979 1981
   if (o->tls_client
1980 1982
       && !o->tls_verify
1981 1983
       && !o->tls_remote
... ...
@@ -39,7 +39,6 @@
39 39
 #include "memdbg.h"
40 40
 
41 41
 static void delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
42
-static bool get_default_gateway (in_addr_t *ret);
43 42
 static void get_bypass_addresses (struct route_bypass *rb, const unsigned int flags);
44 43
 
45 44
 #ifdef ENABLE_DEBUG
... ...
@@ -372,11 +371,11 @@ init_route_list (struct route_list *rl,
372 372
       rl->spec.default_metric_defined = true;
373 373
     }
374 374
 
375
-  rl->spec.net_gateway_defined = get_default_gateway (&rl->spec.net_gateway);
375
+  rl->spec.net_gateway_defined = get_default_gateway (&rl->spec.net_gateway, NULL);
376 376
   if (rl->spec.net_gateway_defined)
377 377
     {
378 378
       setenv_route_addr (es, "net_gateway", rl->spec.net_gateway, -1);
379
-      dmsg (D_ROUTE_DEBUG, "ROUTE DEBUG: default_gateway=%s", print_in_addr_t (rl->spec.net_gateway, 0, &gc));
379
+      dmsg (D_ROUTE, "ROUTE default_gateway=%s", print_in_addr_t (rl->spec.net_gateway, 0, &gc));
380 380
     }
381 381
   else
382 382
     {
... ...
@@ -666,9 +665,11 @@ add_routes (struct route_list *rl, const struct tuntap *tt, unsigned int flags,
666 666
       
667 667
       for (i = 0; i < rl->n; ++i)
668 668
 	{
669
+	  struct route *r = &rl->routes[i];
670
+	  check_subnet_conflict (r->network, r->netmask, "route");
669 671
 	  if (flags & ROUTE_DELETE_FIRST)
670
-	    delete_route (&rl->routes[i], tt, flags, es);
671
-	  add_route (&rl->routes[i], tt, flags, es);
672
+	    delete_route (r, tt, flags, es);
673
+	  add_route (r, tt, flags, es);
672 674
 	}
673 675
       rl->routes_added = true;
674 676
     }
... ...
@@ -1142,7 +1143,7 @@ test_route (const IP_ADAPTER_INFO *adapters,
1142 1142
 	    DWORD *index)
1143 1143
 {
1144 1144
   int count = 0;
1145
-  DWORD i = adapter_index_of_ip (adapters, gateway, &count);
1145
+  DWORD i = adapter_index_of_ip (adapters, gateway, &count, NULL);
1146 1146
   if (index)
1147 1147
     *index = i;
1148 1148
   return count;
... ...
@@ -1251,18 +1252,24 @@ get_default_gateway_row (const MIB_IPFORWARDTABLE *routes)
1251 1251
   return ret;
1252 1252
 }
1253 1253
 
1254
-static bool
1255
-get_default_gateway (in_addr_t *ret)
1254
+bool
1255
+get_default_gateway (in_addr_t *gw, in_addr_t *netmask)
1256 1256
 {
1257 1257
   struct gc_arena gc = gc_new ();
1258 1258
   bool ret_bool = false;
1259 1259
 
1260
+  const IP_ADAPTER_INFO *adapters = get_adapter_info_list (&gc);
1260 1261
   const MIB_IPFORWARDTABLE *routes = get_windows_routing_table (&gc);
1261 1262
   const MIB_IPFORWARDROW *row = get_default_gateway_row (routes);
1262 1263
 
1263 1264
   if (row)
1264 1265
     {
1265
-      *ret = ntohl (row->dwForwardNextHop);
1266
+      *gw = ntohl (row->dwForwardNextHop);
1267
+      if (netmask)
1268
+	{
1269
+	  if (adapter_index_of_ip (adapters, *gw, NULL, netmask) == ~0)
1270
+	    *netmask = ~0;
1271
+	}
1266 1272
       ret_bool = true;
1267 1273
     }
1268 1274
 
... ...
@@ -1467,8 +1474,8 @@ show_routes (int msglev)
1467 1467
 
1468 1468
 #elif defined(TARGET_LINUX)
1469 1469
 
1470
-static bool
1471
-get_default_gateway (in_addr_t *gateway)
1470
+bool
1471
+get_default_gateway (in_addr_t *gateway, in_addr_t *netmask)
1472 1472
 {
1473 1473
   struct gc_arena gc = gc_new ();
1474 1474
   bool ret = false;
... ...
@@ -1521,6 +1528,10 @@ get_default_gateway (in_addr_t *gateway)
1521 1521
       if (best_gw)
1522 1522
 	{
1523 1523
 	  *gateway = best_gw;
1524
+	  if (netmask)
1525
+	    {
1526
+	      *netmask = 0xFFFFFF00; // FIXME -- get the real netmask of the adapter containing the default gateway
1527
+	    }
1524 1528
 	  ret = true;
1525 1529
 	}
1526 1530
 
... ...
@@ -1595,8 +1606,8 @@ struct {
1595 1595
 #define ROUNDUP(a) \
1596 1596
         ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
1597 1597
 
1598
-static bool
1599
-get_default_gateway (in_addr_t *ret)
1598
+bool
1599
+get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
1600 1600
 {
1601 1601
   struct gc_arena gc = gc_new ();
1602 1602
   int s, seq, l, pid, rtm_addrs, i;
... ...
@@ -1676,11 +1687,16 @@ get_default_gateway (in_addr_t *ret)
1676 1676
   if (gate != NULL )
1677 1677
     {
1678 1678
       *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
1679
-#if 1
1679
+#if 0
1680 1680
       msg (M_INFO, "gw %s",
1681 1681
 	   print_in_addr_t ((in_addr_t) *ret, 0, &gc));
1682 1682
 #endif
1683 1683
 
1684
+      if (netmask)
1685
+	{
1686
+	  *netmask = 0xFFFFFF00; // FIXME -- get the real netmask of the adapter containing the default gateway
1687
+	}
1688
+
1684 1689
       gc_free (&gc);
1685 1690
       return true;
1686 1691
     }
... ...
@@ -1752,8 +1768,8 @@ struct {
1752 1752
 #define ROUNDUP(a) \
1753 1753
         ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
1754 1754
 
1755
-static bool
1756
-get_default_gateway (in_addr_t *ret)
1755
+bool
1756
+get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
1757 1757
 {
1758 1758
   struct gc_arena gc = gc_new ();
1759 1759
   int s, seq, l, pid, rtm_addrs, i;
... ...
@@ -1833,11 +1849,16 @@ get_default_gateway (in_addr_t *ret)
1833 1833
   if (gate != NULL )
1834 1834
     {
1835 1835
       *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
1836
-#if 1
1836
+#if 0
1837 1837
       msg (M_INFO, "gw %s",
1838 1838
 	   print_in_addr_t ((in_addr_t) *ret, 0, &gc));
1839 1839
 #endif
1840 1840
 
1841
+      if (netmask)
1842
+	{
1843
+	  *netmask = 0xFFFFFF00; // FIXME -- get the real netmask of the adapter containing the default gateway
1844
+	}
1845
+
1841 1846
       gc_free (&gc);
1842 1847
       return true;
1843 1848
     }
... ...
@@ -1908,8 +1929,8 @@ struct {
1908 1908
 #define ROUNDUP(a) \
1909 1909
         ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
1910 1910
 
1911
-static bool
1912
-get_default_gateway (in_addr_t *ret)
1911
+bool
1912
+get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
1913 1913
 {
1914 1914
   struct gc_arena gc = gc_new ();
1915 1915
   int s, seq, l, rtm_addrs, i;
... ...
@@ -1990,11 +2011,16 @@ get_default_gateway (in_addr_t *ret)
1990 1990
   if (gate != NULL )
1991 1991
     {
1992 1992
       *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
1993
-#if 1
1993
+#if 0
1994 1994
       msg (M_INFO, "gw %s",
1995 1995
 	   print_in_addr_t ((in_addr_t) *ret, 0, &gc));
1996 1996
 #endif
1997 1997
 
1998
+      if (netmask)
1999
+	{
2000
+	  *netmask = 0xFFFFFF00; // FIXME -- get the real netmask of the adapter containing the default gateway
2001
+	}
2002
+
1998 2003
       gc_free (&gc);
1999 2004
       return true;
2000 2005
     }
... ...
@@ -2007,8 +2033,8 @@ get_default_gateway (in_addr_t *ret)
2007 2007
 
2008 2008
 #else
2009 2009
 
2010
-static bool
2011
-get_default_gateway (in_addr_t *ret)
2010
+bool
2011
+get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
2012 2012
 {
2013 2013
   return false;
2014 2014
 }
... ...
@@ -2126,7 +2152,7 @@ get_default_gateway_mac_addr (unsigned char *macaddr)
2126 2126
   in_addr_t gwip = 0;
2127 2127
   bool ret = false;
2128 2128
 
2129
-  if (!get_default_gateway (&gwip))
2129
+  if (!get_default_gateway (&gwip, NULL))
2130 2130
     {
2131 2131
       msg (M_WARN, "GDGMA: get_default_gateway failed");
2132 2132
       goto err;
... ...
@@ -2223,13 +2249,13 @@ get_default_gateway_mac_addr (unsigned char *macaddr)
2223 2223
   DWORD a_index;
2224 2224
   const IP_ADAPTER_INFO *ai;
2225 2225
 
2226
-  if (!get_default_gateway (&gwip))
2226
+  if (!get_default_gateway (&gwip, NULL))
2227 2227
     {
2228 2228
       msg (M_WARN, "GDGMA: get_default_gateway failed");
2229 2229
       goto err;
2230 2230
     }
2231 2231
 
2232
-  a_index = adapter_index_of_ip (adapters, gwip, NULL);
2232
+  a_index = adapter_index_of_ip (adapters, gwip, NULL, NULL);
2233 2233
   ai = get_adapter (adapters, a_index);
2234 2234
 
2235 2235
   if (!ai)
... ...
@@ -156,6 +156,8 @@ void setenv_routes (struct env_set *es, const struct route_list *rl);
156 156
 
157 157
 bool is_special_addr (const char *addr_str);
158 158
 
159
+bool get_default_gateway (in_addr_t *ip, in_addr_t *netmask);
160
+
159 161
 #if AUTO_USERID
160 162
 bool get_default_gateway_mac_addr (unsigned char *macaddr);
161 163
 #endif
... ...
@@ -278,6 +278,58 @@ check_addr_clash (const char *name,
278 278
 }
279 279
 
280 280
 /*
281
+ * Issue a warning if ip/netmask (on the virtual IP network) conflicts with
282
+ * the settings on the local LAN.  This is designed to flag issues where
283
+ * (for example) the OpenVPN server LAN is running on 192.168.1.x, but then
284
+ * an OpenVPN client tries to connect from a public location that is also running
285
+ * off of a router set to 192.168.1.x.
286
+ */
287
+void
288
+check_subnet_conflict (const in_addr_t ip,
289
+		       const in_addr_t netmask,
290
+		       const char *prefix)
291
+{
292
+  struct gc_arena gc = gc_new ();
293
+  in_addr_t lan_gw = 0;
294
+  in_addr_t lan_netmask = 0;
295
+
296
+  if (get_default_gateway (&lan_gw, &lan_netmask))
297
+    {
298
+      const in_addr_t lan_network = lan_gw & lan_netmask; 
299
+      const in_addr_t network = ip & netmask;
300
+
301
+      /* do the two subnets defined by network/netmask and lan_network/lan_netmask intersect? */
302
+      if ((network & lan_netmask) == lan_network
303
+	  || (lan_network & netmask) == network)
304
+	{
305
+	  msg (M_WARN, "WARNING: potential %s subnet conflict between local LAN [%s/%s] and remote VPN [%s/%s]",
306
+	       prefix,
307
+	       print_in_addr_t (lan_network, 0, &gc),
308
+	       print_in_addr_t (lan_netmask, 0, &gc),
309
+	       print_in_addr_t (network, 0, &gc),
310
+	       print_in_addr_t (netmask, 0, &gc));
311
+	}
312
+    }
313
+  gc_free (&gc);
314
+}
315
+
316
+void
317
+warn_on_use_of_common_subnets (void)
318
+{
319
+  struct gc_arena gc = gc_new ();
320
+  in_addr_t lan_gw = 0;
321
+  in_addr_t lan_netmask = 0;
322
+
323
+  if (get_default_gateway (&lan_gw, &lan_netmask))
324
+    {
325
+      const in_addr_t lan_network = lan_gw & lan_netmask; 
326
+      if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
327
+	msg (M_WARN, "NOTE: your local LAN uses the extremely common subnet address 192.168.0.x or 192.168.1.x.  Be aware that this might create routing conflicts if you connect to the VPN server from public locations such as internet cafes that use the same subnet.");
328
+    }
329
+  gc_free (&gc);
330
+}
331
+
332
+/*
281 333
  * Complain if --dev tap and --ifconfig is used on an OS for which
282 334
  * we don't have a custom tap ifconfig template below.
283 335
  */
... ...
@@ -462,6 +514,11 @@ init_tun (const char *dev,       /* --dev option */
462 462
 			    remote_public,
463 463
 			    tt->local,
464 464
 			    tt->remote_netmask);
465
+
466
+	  if (tt->type == DEV_TYPE_TAP || (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET))
467
+	    check_subnet_conflict (tt->local, tt->remote_netmask, "TUN/TAP adapter");
468
+	  else if (tt->type == DEV_TYPE_TUN)
469
+	    check_subnet_conflict (tt->local, ~0, "TUN/TAP adapter");
465 470
 	}
466 471
 
467 472
       /*
... ...
@@ -2856,7 +2913,10 @@ is_ip_in_adapter_subnet (const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_
2856 2856
 }
2857 2857
 
2858 2858
 DWORD
2859
-adapter_index_of_ip (const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count)
2859
+adapter_index_of_ip (const IP_ADAPTER_INFO *list,
2860
+		     const in_addr_t ip,
2861
+		     int *count,
2862
+		     in_addr_t *netmask)
2860 2863
 {
2861 2864
   struct gc_arena gc = gc_new ();
2862 2865
   DWORD ret = ~0;
... ...
@@ -2898,6 +2958,9 @@ adapter_index_of_ip (const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count
2898 2898
   if (ret == ~0 && count)
2899 2899
     *count = 0;
2900 2900
 
2901
+  if (netmask)
2902
+    *netmask = highest_netmask;
2903
+
2901 2904
   gc_free (&gc);
2902 2905
   return ret;
2903 2906
 }
... ...
@@ -241,6 +241,12 @@ const char *ifconfig_options_string (const struct tuntap* tt, bool remote, bool
241 241
 
242 242
 bool is_tun_p2p (const struct tuntap *tt);
243 243
 
244
+void check_subnet_conflict (const in_addr_t ip,
245
+			    const in_addr_t netmask,
246
+			    const char *prefix);
247
+
248
+void warn_on_use_of_common_subnets (void);
249
+
244 250
 /*
245 251
  * Inline functions
246 252
  */
... ...
@@ -313,7 +319,11 @@ const IP_ADAPTER_INFO *get_adapter (const IP_ADAPTER_INFO *ai, DWORD index);
313 313
 
314 314
 bool is_adapter_up (const struct tuntap *tt, const IP_ADAPTER_INFO *list);
315 315
 bool is_ip_in_adapter_subnet (const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask);
316
-DWORD adapter_index_of_ip (const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count);
316
+
317
+DWORD adapter_index_of_ip (const IP_ADAPTER_INFO *list,
318
+			   const in_addr_t ip,
319
+			   int *count,
320
+			   in_addr_t *netmask);
317 321
 
318 322
 void show_tap_win32_adapters (int msglev, int warnlev);
319 323
 void show_adapters (int msglev);