diff options
author | james <james@e7ae566f-a301-0410-adde-c780ea21d3b5> | 2009-08-22 18:29:20 +0000 |
---|---|---|
committer | james <james@e7ae566f-a301-0410-adde-c780ea21d3b5> | 2009-08-22 18:29:20 +0000 |
commit | 8e9666d57550398eabd619b34d90ec69d69eb218 (patch) | |
tree | 9b4e7f4693a085cafc910534844434aac8ba104e | |
parent | Fixed ifconfig command for "topology subnet" on FreeBSD (Stefan Bethke). (diff) | |
download | openvpn-8e9666d57550398eabd619b34d90ec69d69eb218.tar.xz |
Added --remote-random-hostname option.
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@4843 e7ae566f-a301-0410-adde-c780ea21d3b5
-rw-r--r-- | misc.c | 38 | ||||
-rw-r--r-- | misc.h | 3 | ||||
-rw-r--r-- | options.c | 21 | ||||
-rw-r--r-- | socket.c | 33 | ||||
-rw-r--r-- | socket.h | 2 | ||||
-rw-r--r-- | version.m4 | 2 |
6 files changed, 89 insertions, 10 deletions
@@ -1186,6 +1186,44 @@ create_temp_filename (const char *directory, const char *prefix, struct gc_arena return gen_path (directory, BSTR (&fname), gc); } +/* + * Add a random string to first DNS label of hostname to prevent DNS caching. + * For example, foo.bar.gov would be modified to <random-chars>.foo.bar.gov. + * Of course, this requires explicit support in the DNS server. + */ +const char * +hostname_randomize(const char *hostname, struct gc_arena *gc) +{ + const int n_rnd_bytes = 6; + + char *hst = string_alloc(hostname, gc); + char *dot = strchr(hst, '.'); + + if (dot) + { + uint8_t rnd_bytes[n_rnd_bytes]; + const char *rnd_str; + struct buffer hname = alloc_buf_gc (strlen(hostname)+sizeof(rnd_bytes)*2+4, gc); + + *dot++ = '\0'; + prng_bytes (rnd_bytes, sizeof (rnd_bytes)); + rnd_str = format_hex_ex (rnd_bytes, sizeof (rnd_bytes), 40, 0, NULL, gc); + buf_printf(&hname, "%s-0x%s.%s", hst, rnd_str, dot); + return BSTR(&hname); + } + else + return hostname; +} + +#else + +const char * +hostname_randomize(const char *hostname, struct gc_arena *gc) +{ + msg (M_WARN, "WARNING: hostname randomization disabled when crypto support is not compiled"); + return hostname; +} + #endif /* @@ -230,6 +230,9 @@ bool delete_file (const char *filename); /* return true if pathname is absolute */ bool absolute_pathname (const char *pathname); +/* prepend a random prefix to hostname (need USE_CRYPTO) */ +const char *hostname_randomize(const char *hostname, struct gc_arena *gc); + /* * Get and store a username/password */ @@ -90,6 +90,7 @@ static const char usage_message[] = "--local host : Local host name or ip address. Implies --bind.\n" "--remote host [port] : Remote host name or ip address.\n" "--remote-random : If multiple --remote options specified, choose one randomly.\n" + "--remote-random-hostname : Add a random string to remote DNS name.\n" "--mode m : Major mode, m = 'p2p' (default, point-to-point) or 'server'.\n" "--proto p : Use protocol p for communicating with peer.\n" " p = udp (default), tcp-server, or tcp-client\n" @@ -4420,15 +4421,27 @@ add_option (struct options *options, } options->routes->flags |= RG_ENABLE; } + else if (streq (p[0], "remote-random-hostname")) + { + VERIFY_PERMISSION (OPT_P_GENERAL); + options->sockflags |= SF_HOST_RANDOMIZE; + } else if (streq (p[0], "setenv") && p[1]) { VERIFY_PERMISSION (OPT_P_GENERAL); - if (streq (p[1], "FORWARD_COMPATIBLE") && p[2] && streq (p[2], "1")) + if (streq (p[1], "REMOTE_RANDOM_HOSTNAME")) + { + options->sockflags |= SF_HOST_RANDOMIZE; + } + else { - options->forward_compatible = true; - msglevel_fc = msglevel_forward_compatible (options, msglevel); + if (streq (p[1], "FORWARD_COMPATIBLE") && p[2] && streq (p[2], "1")) + { + options->forward_compatible = true; + msglevel_fc = msglevel_forward_compatible (options, msglevel); + } + setenv_str (es, p[1], p[2] ? p[2] : ""); } - setenv_str (es, p[1], p[2] ? p[2] : ""); } else if (streq (p[0], "setenv-safe") && p[1]) { @@ -32,6 +32,7 @@ #include "plugin.h" #include "ps.h" #include "manage.h" +#include "misc.h" #include "memdbg.h" @@ -43,6 +44,19 @@ const int proto_overhead[] = { /* indexed by PROTO_x */ }; /* + * Convert sockflags/getaddr_flags into getaddr_flags + */ +static unsigned int +sf2gaf(const unsigned int getaddr_flags, + const unsigned int sockflags) +{ + if (sockflags & SF_HOST_RANDOMIZE) + return getaddr_flags | GETADDR_RANDOMIZE; + else + return getaddr_flags; +} + +/* * Functions related to the translation of DNS names to IP addresses. */ @@ -79,6 +93,10 @@ getaddr (unsigned int flags, int status; int sigrec = 0; int msglevel = (flags & GETADDR_FATAL) ? M_FATAL : D_RESOLVE_ERRORS; + struct gc_arena gc = gc_new (); + + if (flags & GETADDR_RANDOMIZE) + hostname = hostname_randomize(hostname, &gc); if (flags & GETADDR_MSG_VIRT_OUT) msglevel |= M_MSG_VIRT_OUT; @@ -225,6 +243,7 @@ getaddr (unsigned int flags, msg (level, "RESOLVE: signal received during DNS resolution attempt"); } + gc_free (&gc); return (flags & GETADDR_HOST_ORDER) ? ntohl (ia.s_addr) : ia.s_addr; } @@ -359,12 +378,13 @@ mac_addr_safe (const char *mac_addr) static void update_remote (const char* host, struct openvpn_sockaddr *addr, - bool *changed) + bool *changed, + const unsigned int sockflags) { if (host && addr) { const in_addr_t new_addr = getaddr ( - GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, + sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags), host, 1, NULL, @@ -728,7 +748,7 @@ socket_listen_accept (socket_descriptor_t sd, if (socket_defined (new_sd)) { - update_remote (remote_dynamic, &remote_verify, remote_changed); + update_remote (remote_dynamic, &remote_verify, remote_changed, 0); if (addr_defined (&remote_verify) && !addr_match (&remote_verify, &act->dest)) { @@ -858,6 +878,7 @@ socket_connect (socket_descriptor_t *sd, const int connect_retry_seconds, const int connect_timeout, const int connect_retry_max, + const unsigned int sockflags, volatile int *signal_received) { struct gc_arena gc = gc_new (); @@ -919,7 +940,7 @@ socket_connect (socket_descriptor_t *sd, *sd = create_socket_tcp (); if (bind_local) socket_bind (*sd, local, "TCP Client"); - update_remote (remote_dynamic, remote, remote_changed); + update_remote (remote_dynamic, remote, remote_changed, sockflags); } msg (M_INFO, "TCP connection established with %s", @@ -1023,7 +1044,7 @@ resolve_remote (struct link_socket *sock, if (sock->remote_host) { - unsigned int flags = GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE; + unsigned int flags = sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sock->sockflags); int retry = 0; bool status = false; @@ -1384,6 +1405,7 @@ link_socket_init_phase2 (struct link_socket *sock, sock->connect_retry_seconds, sock->connect_timeout, sock->connect_retry_max, + sock->sockflags, signal_received); if (*signal_received) @@ -1432,6 +1454,7 @@ link_socket_init_phase2 (struct link_socket *sock, sock->connect_retry_seconds, sock->connect_timeout, sock->connect_retry_max, + sock->sockflags, signal_received); if (*signal_received) @@ -198,6 +198,7 @@ struct link_socket # define SF_USE_IP_PKTINFO (1<<0) # define SF_TCP_NODELAY (1<<1) # define SF_PORT_SHARE (1<<2) +# define SF_HOST_RANDOMIZE (1<<3) unsigned int sockflags; /* for stream sockets */ @@ -447,6 +448,7 @@ bool unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int * #define GETADDR_MSG_VIRT_OUT (1<<6) #define GETADDR_TRY_ONCE (1<<7) #define GETADDR_UPDATE_MANAGEMENT_STATE (1<<8) +#define GETADDR_RANDOMIZE (1<<9) in_addr_t getaddr (unsigned int flags, const char *hostname, @@ -1,5 +1,5 @@ dnl define the OpenVPN version -define(PRODUCT_VERSION,[2.1_rc19]) +define(PRODUCT_VERSION,[2.1_rc19a]) dnl define the TAP version define(PRODUCT_TAP_ID,[tap0901]) define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9]) |