diff options
Diffstat (limited to 'openvpn')
| -rw-r--r-- | openvpn/.gitignore | 2 | ||||
| -rw-r--r-- | openvpn/config-version.h | 2 | ||||
| -rw-r--r-- | openvpn/doc/openvpn.8 | 4 | ||||
| -rw-r--r-- | openvpn/src/openvpn/error.h | 2 | ||||
| -rw-r--r-- | openvpn/src/openvpn/manage.c | 6 | ||||
| -rw-r--r-- | openvpn/src/openvpn/options.c | 4 | ||||
| -rw-r--r-- | openvpn/src/openvpn/ps.c | 2 | ||||
| -rw-r--r-- | openvpn/src/openvpn/route.c | 48 | ||||
| -rw-r--r-- | openvpn/src/openvpn/route.h | 1 | ||||
| -rw-r--r-- | openvpn/src/openvpn/socket.c | 185 | ||||
| -rw-r--r-- | openvpn/src/openvpn/socket.h | 6 | 
11 files changed, 155 insertions, 107 deletions
| diff --git a/openvpn/.gitignore b/openvpn/.gitignore index 3a2f3842..538c0208 100644 --- a/openvpn/.gitignore +++ b/openvpn/.gitignore @@ -55,3 +55,5 @@ tests/t_client-*-20??????-??????/  src/openvpn/openvpn  config-version.h  nbproject +test-driver +compile diff --git a/openvpn/config-version.h b/openvpn/config-version.h index f744a095..a46f5526 100644 --- a/openvpn/config-version.h +++ b/openvpn/config-version.h @@ -1,2 +1,2 @@ -#define CONFIGURE_GIT_REVISION "icsopenvpn_65-c005143096b5b53e" +#define CONFIGURE_GIT_REVISION "icsopenvpn_66-d0b066b07a0910bb"  #define CONFIGURE_GIT_FLAGS "" diff --git a/openvpn/doc/openvpn.8 b/openvpn/doc/openvpn.8 index 9eebf93e..3a58317d 100644 --- a/openvpn/doc/openvpn.8 +++ b/openvpn/doc/openvpn.8 @@ -829,8 +829,8 @@ implementation. Using  forces usage of the native Darwin tun kernel support. Use  .B \-\-dev\-node utunN  to select a specific utun instance. To force using the tun.kext (/dev/tunX) use -.B \-\-dev\-node tun -. When not specifying a +.B \-\-dev\-node tun\fR. +When not specifying a  .B \-\-dev\-node  option openvpn will first try to open utun, and fall back to tun.kext. diff --git a/openvpn/src/openvpn/error.h b/openvpn/src/openvpn/error.h index 5571bfdb..1e1f2acf 100644 --- a/openvpn/src/openvpn/error.h +++ b/openvpn/src/openvpn/error.h @@ -194,7 +194,7 @@ void error_reset (void);  void errors_to_stderr (void);  void set_suppress_timestamps (bool suppressed); -void set_parsable_output (bool parsable); +void set_machine_readable_output (bool parsable);  #define SDL_CONSTRAIN (1<<0) diff --git a/openvpn/src/openvpn/manage.c b/openvpn/src/openvpn/manage.c index 06965ad2..561c252b 100644 --- a/openvpn/src/openvpn/manage.c +++ b/openvpn/src/openvpn/manage.c @@ -1568,9 +1568,9 @@ man_listen (struct management *man)        else  #endif  	{ -	  man->connection.sd_top = create_socket_tcp (man->settings.local->ai_family); +	  man->connection.sd_top = create_socket_tcp (man->settings.local);  	  socket_bind (man->connection.sd_top, man->settings.local, -                       man->settings.local->ai_family, "MANAGEMENT", false); +		       man->settings.local->ai_family, "MANAGEMENT", false);  	}        /* @@ -1635,7 +1635,7 @@ man_connect (struct management *man)    else  #endif      { -      man->connection.sd_cli = create_socket_tcp (AF_INET); +      man->connection.sd_cli = create_socket_tcp (man->settings.local);        status = openvpn_connect (man->connection.sd_cli,  				man->settings.local->ai_addr,  				5, diff --git a/openvpn/src/openvpn/options.c b/openvpn/src/openvpn/options.c index 52c6c239..9393c0aa 100644 --- a/openvpn/src/openvpn/options.c +++ b/openvpn/src/openvpn/options.c @@ -2076,6 +2076,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne  #endif        if (options->routes && (options->routes->flags & RG_ENABLE))  	msg (M_USAGE, "--redirect-gateway cannot be used with --mode server (however --push \"redirect-gateway\" is fine)"); +      if (options->routes && ((options->routes->flags & RG_BLOCK_LOCAL) && (options->routes->flags & RG_BLOCK_LOCAL))) +	  msg (M_USAGE, "unblock-local and block-local options of redirect-gateway/redirect-private are mutatlly exclusive");        if (options->route_delay_defined)  	msg (M_USAGE, "--route-delay cannot be used with --mode server");        if (options->up_delay) @@ -5363,6 +5365,8 @@ add_option (struct options *options,  	    options->routes->flags |= RG_BYPASS_DNS;  	  else if (streq (p[j], "block-local"))  	    options->routes->flags |= RG_BLOCK_LOCAL; +	  else if (streq (p[j], "unblock-local")) +	    options->routes->flags |= RG_UNBLOCK_LOCAL;  	  else  	    {  	      msg (msglevel, "unknown --%s flag: %s", p[0], p[j]); diff --git a/openvpn/src/openvpn/ps.c b/openvpn/src/openvpn/ps.c index 901a094f..6807aac0 100644 --- a/openvpn/src/openvpn/ps.c +++ b/openvpn/src/openvpn/ps.c @@ -803,7 +803,7 @@ port_share_open (const char *host,     * Get host's IP address     */ -  status = openvpn_getaddrinfo (GETADDR_RESOLVE|GETADDR_HOST_ORDER|GETADDR_FATAL, +  status = openvpn_getaddrinfo (GETADDR_RESOLVE|GETADDR_FATAL,                                   host, port,  0, NULL, AF_INET, &ai);    ASSERT (status==0);    hostaddr = *((struct sockaddr_in*) ai->ai_addr); diff --git a/openvpn/src/openvpn/route.c b/openvpn/src/openvpn/route.c index fa8221d4..25eeb77c 100644 --- a/openvpn/src/openvpn/route.c +++ b/openvpn/src/openvpn/route.c @@ -536,6 +536,46 @@ add_block_local_item (struct route_list *rl,  }  static void +add_unblock_local (struct route_list *rl) +{ +  const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED); + +  if (rl->flags & RG_UNBLOCK_LOCAL && rl->n+1 < rl->capacity +      && (rl->rgi.flags & rgi_needed) == rgi_needed) +    { +      /* unblock access to local subnet */ +      struct route_ipv4 r; +      int i; + +      CLEAR(r); +      r.flags = RT_DEFINED; +      r.network = rl->rgi.gateway.addr & rl->rgi.gateway.netmask; +      r.netmask = rl->rgi.gateway.netmask; +      r.gateway = rl->rgi.gateway.addr; +      rl->routes[rl->n++] = r; + +      /* Additional local networks */ +      for (i = 0; i < rl->rgi.n_addrs; ++i) +	{ +	  const struct route_gateway_address *gwa = &rl->rgi.addrs[i]; + +	  /* omit the add/subnet in &rl->rgi which we processed above */ +	  if ((!((rl->rgi.gateway.addr & rl->rgi.gateway.netmask) == (gwa->addr & gwa->netmask) +		 && rl->rgi.gateway.netmask == gwa->netmask))  && rl->n+1 < rl->capacity) +	    { +	      CLEAR(r); +	      r.flags = RT_DEFINED; +	      r.network = gwa->addr & gwa->netmask; +	      r.netmask = gwa->netmask; +	      r.gateway = gwa->addr; +	      rl->routes[rl->n++] = r; +	    } +	} +    } +} + + +static void  add_block_local (struct route_list *rl)  {    const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED); @@ -546,8 +586,10 @@ add_block_local (struct route_list *rl)      {        size_t i; +#ifndef TARGET_ANDROID        /* add bypass for gateway addr */        add_bypass_address (&rl->spec.bypass, rl->rgi.gateway.addr); +#endif        /* block access to local subnet */        add_block_local_item (rl, &rl->rgi.gateway, rl->spec.remote_endpoint); @@ -564,6 +606,8 @@ add_block_local (struct route_list *rl)      }  } + +  bool  init_route_list (struct route_list *rl,  		 const struct route_option_list *opt, @@ -632,6 +676,8 @@ init_route_list (struct route_list *rl,  	}      } + +  add_unblock_local (rl);    if (rl->flags & RG_ENABLE)      {        add_block_local (rl); @@ -852,6 +898,7 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u  	}        else  	{ +#ifndef TARGET_ANDROID  	  bool local = BOOL_CAST(rl->flags & RG_LOCAL);  	  if (rl->flags & RG_AUTO_LOCAL) {  	    const int tla = rl->spec.remote_host_local; @@ -884,6 +931,7 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u  		dmsg (D_ROUTE, "ROUTE remote_host protocol differs from tunneled");  	      }  	    } +#endif  	  /* route DHCP/DNS server traffic through original default gateway */  	  add_bypass_routes (&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es); diff --git a/openvpn/src/openvpn/route.h b/openvpn/src/openvpn/route.h index fe9b4616..c5e2c1e4 100644 --- a/openvpn/src/openvpn/route.h +++ b/openvpn/src/openvpn/route.h @@ -89,6 +89,7 @@ struct route_option {  #define RG_REROUTE_GW     (1<<5)  #define RG_AUTO_LOCAL     (1<<6)  #define RG_BLOCK_LOCAL    (1<<7) +#define RG_UNBLOCK_LOCAL    (1<<8)  struct route_option_list {    unsigned int flags;  /* RG_x flags */ diff --git a/openvpn/src/openvpn/socket.c b/openvpn/src/openvpn/socket.c index 97f67563..4b86d439 100644 --- a/openvpn/src/openvpn/socket.c +++ b/openvpn/src/openvpn/socket.c @@ -766,11 +766,15 @@ link_socket_update_buffer_sizes (struct link_socket *ls, int rcvbuf, int sndbuf)   */  socket_descriptor_t -create_socket_tcp (int af) +create_socket_tcp (struct addrinfo* addrinfo)  {    socket_descriptor_t sd; -  if ((sd = socket (af, SOCK_STREAM, IPPROTO_TCP)) < 0) +  ASSERT (addrinfo); +  ASSERT (addrinfo->ai_socktype == SOCK_STREAM); +  ASSERT (addrinfo->ai_protocol == IPPROTO_TCP); + +  if ((sd = socket (addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol)) < 0)      msg (M_ERR, "Cannot create TCP socket");  #ifndef WIN32 /* using SO_REUSEADDR on Windows will cause bind to succeed on port conflicts! */ @@ -787,17 +791,21 @@ create_socket_tcp (int af)  }  static socket_descriptor_t -create_socket_udp (const int af, const unsigned int flags) +create_socket_udp (struct addrinfo* addrinfo, const unsigned int flags)  {    socket_descriptor_t sd; -  if ((sd = socket (af, SOCK_DGRAM, IPPROTO_UDP)) < 0) +  ASSERT (addrinfo); +  ASSERT (addrinfo->ai_socktype == SOCK_DGRAM); +  ASSERT (addrinfo->ai_protocol == IPPROTO_UDP); + +  if ((sd = socket (addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol)) < 0)      msg (M_ERR, "UDP: Cannot create UDP/UDP6 socket");  #if ENABLE_IP_PKTINFO    else if (flags & SF_USE_IP_PKTINFO)      {        int pad = 1; -      if(af == AF_INET) +      if(addrinfo->ai_family == AF_INET)          {  #ifdef IP_PKTINFO            if (setsockopt (sd, SOL_IP, IP_PKTINFO, @@ -811,7 +819,7 @@ create_socket_udp (const int af, const unsigned int flags)  #error ENABLE_IP_PKTINFO is set without IP_PKTINFO xor IP_RECVDSTADDR (fix syshead.h)  #endif          } -      else if (af == AF_INET6 ) +      else if (addrinfo->ai_family == AF_INET6 )          {  #ifndef IPV6_RECVPKTINFO /* Some older Darwin platforms require this */            if (setsockopt (sd, IPPROTO_IPV6, IPV6_PKTINFO, @@ -827,28 +835,48 @@ create_socket_udp (const int af, const unsigned int flags)    return sd;  } -static void -create_socket (struct link_socket *sock) +static void bind_local (struct link_socket *sock, const sa_family_t ai_family)  { -  /* create socket, use information carried over from getaddrinfo */ -  const int ai_proto = sock->info.lsa->actual.ai_protocol; -  int ai_family = sock->info.lsa->actual.ai_family; - -  ASSERT (sock->info.af == AF_UNSPEC  || sock->info.af == ai_family); +    /* bind to local address/port */ +    if (sock->bind_local) +      { +#ifdef ENABLE_SOCKS +        if (sock->socks_proxy && sock->info.proto == PROTO_UDP) +            socket_bind (sock->ctrl_sd, sock->info.lsa->bind_local, +			 ai_family, "SOCKS", false); +        else +#endif +            socket_bind (sock->sd, sock->info.lsa->bind_local, +			 ai_family, +                         "TCP/UDP", sock->info.bind_ipv6_only); +      } +} -  if (ai_proto == IPPROTO_UDP) +static void +create_socket (struct link_socket* sock, struct addrinfo* addr) +{ +  if (addr->ai_protocol == IPPROTO_UDP)      { -      sock->sd = create_socket_udp (ai_family, sock->sockflags); +      sock->sd = create_socket_udp (addr, sock->sockflags);        sock->sockflags |= SF_GETADDRINFO_DGRAM;  #ifdef ENABLE_SOCKS +      /* Assume that control socket and data socket to the socks proxy +       * are using the same IP family */        if (sock->socks_proxy) -	sock->ctrl_sd = create_socket_tcp (ai_family); +	{ +	  /* Construct a temporary addrinfo to create the socket, +	   * currently resolve two remote addresses is not supported, +	   * TODO: Rewrite the whole resolve_remote */ +	  struct addrinfo addrinfo_tmp = *addr; +	  addr->ai_protocol = IPPROTO_TCP; +	  sock->ctrl_sd = create_socket_tcp (&addrinfo_tmp); +	}  #endif      } -  else if (ai_proto == IPPROTO_TCP) +  else if (addr->ai_protocol == IPPROTO_TCP)      { -      sock->sd = create_socket_tcp (ai_family); +      sock->sd = create_socket_tcp (addr);      }    else      { @@ -859,6 +887,8 @@ create_socket (struct link_socket *sock)      /* set socket to --mark packets with given value */      socket_set_mark (sock->sd, sock->mark); + +    bind_local (sock, addr->ai_family);  }  #ifdef TARGET_ANDROID @@ -1204,21 +1234,15 @@ void set_actual_address (struct link_socket_actual* actual, struct addrinfo* ai)      else          ASSERT(0); -    /* Copy addrinfo sock parameters for socket creating */ -    actual->ai_family = ai->ai_family; -    actual->ai_protocol = ai->ai_protocol; -    actual->ai_socktype = ai->ai_socktype;  }  void -socket_connect (socket_descriptor_t *sd, -                struct link_socket_addr *lsa, +socket_connect (socket_descriptor_t* sd, +                const struct sockaddr* dest,                  const int connect_timeout,                  struct signal_info* sig_info)  {    struct gc_arena gc = gc_new (); -  const struct sockaddr *dest = &lsa->actual.dest.addr.sa; -    int status;  #ifdef CONNECT_NONBLOCK @@ -1346,23 +1370,6 @@ resolve_bind_local (struct link_socket *sock, const sa_family_t af)    gc_free (&gc);  } -static void bind_local (struct link_socket *sock) -{ -    /* bind to local address/port */ -    if (sock->bind_local) -      { -#ifdef ENABLE_SOCKS -        if (sock->socks_proxy && sock->info.proto == PROTO_UDP) -            socket_bind (sock->ctrl_sd, sock->info.lsa->bind_local, -                         sock->info.lsa->actual.ai_family, "SOCKS", false); -        else -#endif -            socket_bind (sock->sd, sock->info.lsa->bind_local, -                         sock->info.lsa->actual.ai_family, -                         "TCP/UDP", sock->info.bind_ipv6_only); -      } -} -  static void  resolve_remote (struct link_socket *sock,  		int phase, @@ -1491,30 +1498,6 @@ link_socket_new (void)  }  void -create_new_socket (struct link_socket* sock) -{ -   if (sock->bind_local) { -      resolve_bind_local (sock, sock->info.af); -  } -  resolve_remote (sock, 1, NULL, NULL); - -  /* -   * In P2P or server mode we must create the socket even when resolving -   * the remote site fails/is not specified. */ - -  if (sock->info.lsa->actual.ai_family==0 && sock->bind_local) -    { -      /* Copy sock parameters from bind addr */ -      set_actual_address (&sock->info.lsa->actual, sock->info.lsa->bind_local); -      /* clear destination set by set_actual_address */ -      CLEAR(sock->info.lsa->actual.dest); -    } -} - - - -/* bind socket if necessary */ -void  link_socket_init_phase1 (struct link_socket *sock,  			 const char *local_host,  			 const char *local_port, @@ -1655,7 +1638,10 @@ link_socket_init_phase1 (struct link_socket *sock,      }    else if (mode != LS_MODE_TCP_ACCEPT_FROM)      { -      create_new_socket (sock); +      if (sock->bind_local) { +	  resolve_bind_local (sock, sock->info.af); +      } +      resolve_remote (sock, 1, NULL, NULL);      }  } @@ -1739,11 +1725,14 @@ linksock_print_addr (struct link_socket *sock)      msg (msglevel, "%s link local: [inetd]", proto2ascii (sock->info.proto, sock->info.af, true));    else if (sock->bind_local)      { -      /* Socket is always bound on the first matching address */ +      sa_family_t ai_family = sock->info.lsa->actual.dest.addr.sa.sa_family; +      /* Socket is always bound on the first matching address, +       * For bound sockets with no remote addr this is the element of +       * the list */        struct addrinfo *cur;        for (cur = sock->info.lsa->bind_local; cur; cur=cur->ai_next)  	{ -	  if(cur->ai_family == sock->info.lsa->actual.ai_family) +	  if(!ai_family || ai_family == cur->ai_family)  	    break;  	}        ASSERT (cur); @@ -1812,8 +1801,9 @@ phase2_tcp_client (struct link_socket *sock, struct signal_info *sig_info)    const bool proxy_retry = false;  #endif    do { +    ASSERT (sock->info.lsa->current_remote->ai_protocol == IPPROTO_TCP);      socket_connect (&sock->sd, -                   sock->info.lsa, +                   sock->info.lsa->current_remote->ai_addr,                     sock->connect_timeout,                     sig_info); @@ -1848,7 +1838,7 @@ phase2_tcp_client (struct link_socket *sock, struct signal_info *sig_info)  	/* TODO (schwabe): This code assumes AF_INET for the proxy socket           * when retrying a connection */  	openvpn_close_socket (sock->sd); -	sock->sd = create_socket_tcp (AF_INET); +	sock->sd = create_socket_tcp (sock->info.lsa->current_remote);        }    } while (proxy_retry); @@ -1860,7 +1850,7 @@ static void  phase2_socks_client (struct link_socket *sock, struct signal_info *sig_info)  {      socket_connect (&sock->ctrl_sd, -		    sock->info.lsa, +		    sock->info.lsa->current_remote->ai_addr,  		    sock->connect_timeout,  		    sig_info); @@ -1932,33 +1922,34 @@ link_socket_init_phase2 (struct link_socket *sock,        /* Second chance to resolv/create socket */        resolve_remote (sock, 2, &remote_dynamic,  &sig_info->signal_received); +      /* If a valid remote has been found, create the socket with its addrinfo */ +      if (sock->info.lsa->current_remote) +	  create_socket (sock, sock->info.lsa->current_remote); +        /* If socket has not already been created create it now */        if (sock->sd == SOCKET_UNDEFINED)  	{ -          /* If we have no --remote and have still not figured out the -           * protocol family to use we will use the first of the bind */ -          if (sock->bind_local && sock->info.lsa->bind_local -              && !sock->info.lsa->actual.ai_family && !sock->remote_host) -          { -            msg (M_WARN, "Could not determine IPv4/IPv6 protocol. Using %s", -                 addr_family_name(sock->info.lsa->bind_local->ai_family)); -            set_actual_address(&sock->info.lsa->actual, sock->info.lsa->bind_local); - -          } +	  /* If we have no --remote and have still not figured out the +	   * protocol family to use we will use the first of the bind */ -	  if (sock->info.lsa->actual.ai_family) -	    { -	      create_socket (sock); -	    } -	  else +	  if (sock->bind_local  && !sock->remote_host && sock->info.lsa->bind_local)  	    { -	      msg (M_WARN, "Could not determine IPv4/IPv6 protocol"); -	      sig_info->signal_received = SIGUSR1; -	      goto done; +	      /* Warn if this is because neither v4 or v6 was specified +	       * and we should not connect a remote */ +	      if (sock->info.af == AF_UNSPEC) +		msg (M_WARN, "Could not determine IPv4/IPv6 protocol. Using %s", +		     addr_family_name(sock->info.lsa->bind_local->ai_family)); + +	      create_socket (sock, sock->info.lsa->bind_local);  	    } +	} -	  if (sock->bind_local) -	    bind_local(sock); +      /* Socket still undefined, give a warning and abort connection */ +      if (sock->sd == SOCKET_UNDEFINED) +	{ +	  msg (M_WARN, "Could not determine IPv4/IPv6 protocol"); +	  sig_info->signal_received = SIGUSR1; +	  goto done;  	}        if (sig_info && sig_info->signal_received) @@ -2798,6 +2789,7 @@ proto_remote (int proto, bool remote)  	return "TCPv4_CLIENT";    ASSERT (0); +  return ""; /* Make the compiler happy */  }  /* @@ -2933,7 +2925,12 @@ link_socket_read_udp_posix_recvmsg (struct link_socket *sock,  	  from->pi.in6.ipi6_ifindex = pkti6->ipi6_ifindex;  	  from->pi.in6.ipi6_addr = pkti6->ipi6_addr;  	} +      else if (cmsg != NULL) +	{ +	  msg(M_WARN, "CMSG received that cannot be parsed"); +	}      } +    return fromlen;  }  #endif @@ -3000,7 +2997,7 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock,    iov.iov_len = BLEN (buf);    mesg.msg_iov = &iov;    mesg.msg_iovlen = 1; -  switch (to->ai_family) +  switch (to->dest.addr.sa.sa_family)      {      case AF_INET:        { diff --git a/openvpn/src/openvpn/socket.h b/openvpn/src/openvpn/socket.h index 8d4316ba..51329534 100644 --- a/openvpn/src/openvpn/socket.h +++ b/openvpn/src/openvpn/socket.h @@ -91,10 +91,6 @@ struct cached_dns_entry {  struct link_socket_actual  {    /*int dummy;*/ /* add offset to force a bug if dest not explicitly dereferenced */ - int ai_family;	/* PF_xxx */ - int ai_socktype;	/* SOCK_xxx */ - int ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */ -    struct openvpn_sockaddr dest;  #if ENABLE_IP_PKTINFO @@ -473,7 +469,7 @@ bool ip_or_dns_addr_safe (const char *addr, const bool allow_fqdn);  bool mac_addr_safe (const char *mac_addr);  bool ipv6_addr_safe (const char *ipv6_text_addr); -socket_descriptor_t create_socket_tcp (int af); +socket_descriptor_t create_socket_tcp (struct addrinfo*);  socket_descriptor_t socket_do_accept (socket_descriptor_t sd,  				      struct link_socket_actual *act, | 
