Browse code

Added --remote-random-hostname option.

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

james authored on 2009/08/23 03:29:20
Showing 6 changed files
... ...
@@ -1186,6 +1186,44 @@ create_temp_filename (const char *directory, const char *prefix, struct gc_arena
1186 1186
   return gen_path (directory, BSTR (&fname), gc);
1187 1187
 }
1188 1188
 
1189
+/*
1190
+ * Add a random string to first DNS label of hostname to prevent DNS caching.
1191
+ * For example, foo.bar.gov would be modified to <random-chars>.foo.bar.gov.
1192
+ * Of course, this requires explicit support in the DNS server.
1193
+ */
1194
+const char *
1195
+hostname_randomize(const char *hostname, struct gc_arena *gc)
1196
+{
1197
+  const int n_rnd_bytes = 6;
1198
+
1199
+  char *hst = string_alloc(hostname, gc);
1200
+  char *dot = strchr(hst, '.');
1201
+
1202
+  if (dot)
1203
+    {
1204
+      uint8_t rnd_bytes[n_rnd_bytes];
1205
+      const char *rnd_str;
1206
+      struct buffer hname = alloc_buf_gc (strlen(hostname)+sizeof(rnd_bytes)*2+4, gc);
1207
+
1208
+      *dot++ = '\0';
1209
+      prng_bytes (rnd_bytes, sizeof (rnd_bytes));
1210
+      rnd_str = format_hex_ex (rnd_bytes, sizeof (rnd_bytes), 40, 0, NULL, gc);
1211
+      buf_printf(&hname, "%s-0x%s.%s", hst, rnd_str, dot);
1212
+      return BSTR(&hname);
1213
+    }
1214
+  else
1215
+    return hostname;
1216
+}
1217
+
1218
+#else
1219
+
1220
+const char *
1221
+hostname_randomize(const char *hostname, struct gc_arena *gc)
1222
+{
1223
+  msg (M_WARN, "WARNING: hostname randomization disabled when crypto support is not compiled");
1224
+  return hostname;
1225
+}
1226
+
1189 1227
 #endif
1190 1228
 
1191 1229
 /*
... ...
@@ -230,6 +230,9 @@ bool delete_file (const char *filename);
230 230
 /* return true if pathname is absolute */
231 231
 bool absolute_pathname (const char *pathname);
232 232
 
233
+/* prepend a random prefix to hostname (need USE_CRYPTO) */
234
+const char *hostname_randomize(const char *hostname, struct gc_arena *gc);
235
+
233 236
 /*
234 237
  * Get and store a username/password
235 238
  */
... ...
@@ -90,6 +90,7 @@ static const char usage_message[] =
90 90
   "--local host    : Local host name or ip address. Implies --bind.\n"
91 91
   "--remote host [port] : Remote host name or ip address.\n"
92 92
   "--remote-random : If multiple --remote options specified, choose one randomly.\n"
93
+  "--remote-random-hostname : Add a random string to remote DNS name.\n"
93 94
   "--mode m        : Major mode, m = 'p2p' (default, point-to-point) or 'server'.\n"
94 95
   "--proto p       : Use protocol p for communicating with peer.\n"
95 96
   "                  p = udp (default), tcp-server, or tcp-client\n"
... ...
@@ -4420,15 +4421,27 @@ add_option (struct options *options,
4420 4420
 	}
4421 4421
       options->routes->flags |= RG_ENABLE;
4422 4422
     }
4423
+  else if (streq (p[0], "remote-random-hostname"))
4424
+    {
4425
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4426
+      options->sockflags |= SF_HOST_RANDOMIZE;
4427
+    }
4423 4428
   else if (streq (p[0], "setenv") && p[1])
4424 4429
     {
4425 4430
       VERIFY_PERMISSION (OPT_P_GENERAL);
4426
-      if (streq (p[1], "FORWARD_COMPATIBLE") && p[2] && streq (p[2], "1"))
4431
+      if (streq (p[1], "REMOTE_RANDOM_HOSTNAME"))
4432
+	{
4433
+	  options->sockflags |= SF_HOST_RANDOMIZE;
4434
+	}
4435
+      else
4427 4436
 	{
4428
-	  options->forward_compatible = true;
4429
-	  msglevel_fc = msglevel_forward_compatible (options, msglevel);
4437
+	  if (streq (p[1], "FORWARD_COMPATIBLE") && p[2] && streq (p[2], "1"))
4438
+	    {
4439
+	      options->forward_compatible = true;
4440
+	      msglevel_fc = msglevel_forward_compatible (options, msglevel);
4441
+	    }
4442
+	  setenv_str (es, p[1], p[2] ? p[2] : "");
4430 4443
 	}
4431
-      setenv_str (es, p[1], p[2] ? p[2] : "");
4432 4444
     }
4433 4445
   else if (streq (p[0], "setenv-safe") && p[1])
4434 4446
     {
... ...
@@ -32,6 +32,7 @@
32 32
 #include "plugin.h"
33 33
 #include "ps.h"
34 34
 #include "manage.h"
35
+#include "misc.h"
35 36
 
36 37
 #include "memdbg.h"
37 38
 
... ...
@@ -43,6 +44,19 @@ const int proto_overhead[] = { /* indexed by PROTO_x */
43 43
 };
44 44
 
45 45
 /*
46
+ * Convert sockflags/getaddr_flags into getaddr_flags
47
+ */
48
+static unsigned int
49
+sf2gaf(const unsigned int getaddr_flags,
50
+       const unsigned int sockflags)
51
+{
52
+  if (sockflags & SF_HOST_RANDOMIZE)
53
+    return getaddr_flags | GETADDR_RANDOMIZE;
54
+  else
55
+    return getaddr_flags;
56
+}
57
+
58
+/*
46 59
  * Functions related to the translation of DNS names to IP addresses.
47 60
  */
48 61
 
... ...
@@ -79,6 +93,10 @@ getaddr (unsigned int flags,
79 79
   int status;
80 80
   int sigrec = 0;
81 81
   int msglevel = (flags & GETADDR_FATAL) ? M_FATAL : D_RESOLVE_ERRORS;
82
+  struct gc_arena gc = gc_new ();
83
+
84
+  if (flags & GETADDR_RANDOMIZE)
85
+    hostname = hostname_randomize(hostname, &gc);
82 86
 
83 87
   if (flags & GETADDR_MSG_VIRT_OUT)
84 88
     msglevel |= M_MSG_VIRT_OUT;
... ...
@@ -225,6 +243,7 @@ getaddr (unsigned int flags,
225 225
       msg (level, "RESOLVE: signal received during DNS resolution attempt");
226 226
     }
227 227
 
228
+  gc_free (&gc);
228 229
   return (flags & GETADDR_HOST_ORDER) ? ntohl (ia.s_addr) : ia.s_addr;
229 230
 }
230 231
 
... ...
@@ -359,12 +378,13 @@ mac_addr_safe (const char *mac_addr)
359 359
 static void
360 360
 update_remote (const char* host,
361 361
 	       struct openvpn_sockaddr *addr,
362
-	       bool *changed)
362
+	       bool *changed,
363
+	       const unsigned int sockflags)
363 364
 {
364 365
   if (host && addr)
365 366
     {
366 367
       const in_addr_t new_addr = getaddr (
367
-					  GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE,
368
+					  sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags),
368 369
 					  host,
369 370
 					  1,
370 371
 					  NULL,
... ...
@@ -728,7 +748,7 @@ socket_listen_accept (socket_descriptor_t sd,
728 728
 
729 729
       if (socket_defined (new_sd))
730 730
 	{
731
-	  update_remote (remote_dynamic, &remote_verify, remote_changed);
731
+	  update_remote (remote_dynamic, &remote_verify, remote_changed, 0);
732 732
 	  if (addr_defined (&remote_verify)
733 733
 	      && !addr_match (&remote_verify, &act->dest))
734 734
 	    {
... ...
@@ -858,6 +878,7 @@ socket_connect (socket_descriptor_t *sd,
858 858
 		const int connect_retry_seconds,
859 859
 		const int connect_timeout,
860 860
 		const int connect_retry_max,
861
+		const unsigned int sockflags,
861 862
 		volatile int *signal_received)
862 863
 {
863 864
   struct gc_arena gc = gc_new ();
... ...
@@ -919,7 +940,7 @@ socket_connect (socket_descriptor_t *sd,
919 919
       *sd = create_socket_tcp ();
920 920
       if (bind_local)
921 921
         socket_bind (*sd, local, "TCP Client");
922
-      update_remote (remote_dynamic, remote, remote_changed);
922
+      update_remote (remote_dynamic, remote, remote_changed, sockflags);
923 923
     }
924 924
 
925 925
   msg (M_INFO, "TCP connection established with %s", 
... ...
@@ -1023,7 +1044,7 @@ resolve_remote (struct link_socket *sock,
1023 1023
 
1024 1024
 	  if (sock->remote_host)
1025 1025
 	    {
1026
-	      unsigned int flags = GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE;
1026
+	      unsigned int flags = sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sock->sockflags);
1027 1027
 	      int retry = 0;
1028 1028
 	      bool status = false;
1029 1029
 
... ...
@@ -1384,6 +1405,7 @@ link_socket_init_phase2 (struct link_socket *sock,
1384 1384
 			    sock->connect_retry_seconds,
1385 1385
 			    sock->connect_timeout,
1386 1386
 			    sock->connect_retry_max,
1387
+			    sock->sockflags,
1387 1388
 			    signal_received);
1388 1389
 
1389 1390
 	    if (*signal_received)
... ...
@@ -1432,6 +1454,7 @@ link_socket_init_phase2 (struct link_socket *sock,
1432 1432
 			  sock->connect_retry_seconds,
1433 1433
 			  sock->connect_timeout,
1434 1434
 			  sock->connect_retry_max,
1435
+			  sock->sockflags,
1435 1436
 			  signal_received);
1436 1437
 
1437 1438
 	  if (*signal_received)
... ...
@@ -198,6 +198,7 @@ struct link_socket
198 198
 # define SF_USE_IP_PKTINFO (1<<0)
199 199
 # define SF_TCP_NODELAY (1<<1)
200 200
 # define SF_PORT_SHARE (1<<2)
201
+# define SF_HOST_RANDOMIZE (1<<3)
201 202
   unsigned int sockflags;
202 203
 
203 204
   /* for stream sockets */
... ...
@@ -447,6 +448,7 @@ bool unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int *
447 447
 #define GETADDR_MSG_VIRT_OUT          (1<<6)
448 448
 #define GETADDR_TRY_ONCE              (1<<7)
449 449
 #define GETADDR_UPDATE_MANAGEMENT_STATE (1<<8)
450
+#define GETADDR_RANDOMIZE             (1<<9)
450 451
 
451 452
 in_addr_t getaddr (unsigned int flags,
452 453
 		   const char *hostname,
... ...
@@ -1,5 +1,5 @@
1 1
 dnl define the OpenVPN version
2
-define(PRODUCT_VERSION,[2.1_rc19])
2
+define(PRODUCT_VERSION,[2.1_rc19a])
3 3
 dnl define the TAP version
4 4
 define(PRODUCT_TAP_ID,[tap0901])
5 5
 define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])