Example #1
0
static void
ifconfig_pool_list(const struct ifconfig_pool *pool, struct status_output *out)
{
    if (pool && out)
    {
        struct gc_arena gc = gc_new();
        int i;

        for (i = 0; i < pool->size; ++i)
        {
            const struct ifconfig_pool_entry *e = &pool->list[i];
            if (e->common_name)
            {
                const in_addr_t ip = ifconfig_pool_handle_to_ip_base(pool, i);
                if (pool->ipv6)
                {
                    struct in6_addr ip6 = ifconfig_pool_handle_to_ipv6_base(pool, i);
                    status_printf(out, "%s,%s,%s",
                                  e->common_name,
                                  print_in_addr_t(ip, 0, &gc),
                                  print_in6_addr(ip6, 0, &gc));
                }
                else
                {
                    status_printf(out, "%s,%s",
                                  e->common_name,
                                  print_in_addr_t(ip, 0, &gc));
                }
            }
        }
        gc_free(&gc);
    }
}
Example #2
0
bool
send_push_reply (struct context *c)
{
  struct gc_arena gc = gc_new ();
  struct buffer buf = alloc_buf_gc (MAX_PUSH_LIST_LEN + 256, &gc);
  bool ret = false;

  buf_printf (&buf, "PUSH_REPLY");

  if (c->options.push_list && strlen (c->options.push_list->options))
    buf_printf (&buf, ",%s", c->options.push_list->options);

  if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local && c->c2.push_ifconfig_remote_netmask)
    buf_printf (&buf, ",ifconfig %s %s",
		print_in_addr_t (c->c2.push_ifconfig_local, 0, &gc),
		print_in_addr_t (c->c2.push_ifconfig_remote_netmask, 0, &gc));

  if (strlen (BSTR (&buf)) < MAX_PUSH_LIST_LEN)
    ret = send_control_channel_string (c, BSTR (&buf), D_PUSH);
  else
    msg (M_WARN, "Maximum length of --push buffer (%d) has been exceeded", MAX_PUSH_LIST_LEN);

  gc_free (&gc);
  return ret;
}
Example #3
0
File: pf.c Project: benjdag/openvpn
static void
pf_addr_test_print(const char *prefix,
                   const char *prefix2,
                   const struct context *src,
                   const struct mroute_addr *dest,
                   const bool allow,
                   const struct ipv4_subnet *rule)
{
    struct gc_arena gc = gc_new();
    if (rule)
    {
        dmsg(D_PF_DEBUG, "PF: %s/%s %s %s %s rule=[%s/%s %s]",
             prefix,
             prefix2,
             tls_common_name(src->c2.tls_multi, false),
             mroute_addr_print_ex(dest, MAPF_SHOW_ARP, &gc),
             drop_accept(allow),
             print_in_addr_t(rule->network, 0, &gc),
             print_in_addr_t(rule->netmask, 0, &gc),
             drop_accept(!rule->exclude));
    }
    else
    {
        dmsg(D_PF_DEBUG, "PF: %s/%s %s %s %s",
             prefix,
             prefix2,
             tls_common_name(src->c2.tls_multi, false),
             mroute_addr_print_ex(dest, MAPF_SHOW_ARP, &gc),
             drop_accept(allow));
    }
    gc_free(&gc);
}
Example #4
0
const char *
mroute_addr_print_ex (const struct mroute_addr *ma,
		      const unsigned int flags,
		      struct gc_arena *gc)
{
  struct buffer out = alloc_buf_gc (64, gc);
  if (ma)
    {
      struct mroute_addr maddr = *ma;

      switch (maddr.type & MR_ADDR_MASK)
	{
	case MR_ADDR_ETHER:
	  buf_printf (&out, "%s", format_hex_ex (ma->addr, 6, 0, 1, ":", gc)); 
	  break;
	case MR_ADDR_IPV4:
	  {
	    struct buffer buf;
	    in_addr_t addr;
	    int port;
	    bool status;
	    buf_set_read (&buf, maddr.addr, maddr.len);
	    addr = buf_read_u32 (&buf, &status);
	    if (status)
	      {
		if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
		  buf_printf (&out, "ARP/");
		buf_printf (&out, "%s", print_in_addr_t (addr, (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
		if (maddr.type & MR_WITH_NETBITS)
		  {
		    if (flags & MAPF_SUBNET)
		      {
			const in_addr_t netmask = netbits_to_netmask (maddr.netbits);
			buf_printf (&out, "/%s", print_in_addr_t (netmask, 0, gc));
		      }
		    else
		      buf_printf (&out, "/%d", maddr.netbits);
		  }
	      }
	    if (maddr.type & MR_WITH_PORT)
	      {
		port = buf_read_u16 (&buf);
		if (port >= 0)
		  buf_printf (&out, ":%d", port);
	      }
	  }
	  break;
	case MR_ADDR_IPV6:
	  buf_printf (&out, "IPV6"); 
	  break;
	default:
	  buf_printf (&out, "UNKNOWN"); 
	  break;
	}
      return BSTR (&out);
    }
  else
    return "[NULL]";
}
Example #5
0
static void
helper_add_route (const in_addr_t network, const in_addr_t netmask, struct options *o)
{
  rol_check_alloc (o);
  add_route_to_option_list (o->routes,
			    print_in_addr_t (network, 0, &o->gc),
			    print_in_addr_t (netmask, 0, &o->gc),
			    NULL,
			    NULL);
}
Example #6
0
static void
verify_common_subnet (const char *opt, const in_addr_t a, const in_addr_t b, const in_addr_t subnet)
{
  struct gc_arena gc = gc_new ();
  if ((a & subnet) != (b & subnet))
    msg (M_USAGE, "%s IP addresses %s and %s are not in the same %s subnet",
	 opt,
	 print_in_addr_t (a, 0, &gc),
	 print_in_addr_t (b, 0, &gc),
	 print_in_addr_t (subnet, 0, &gc));
  gc_free (&gc);
}
Example #7
0
static const char *
print_opt_route (const in_addr_t network, const in_addr_t netmask, struct gc_arena *gc)
{
  struct buffer out = alloc_buf_gc (128, gc);
  ASSERT (network);

  if (netmask)
    buf_printf (&out, "route %s %s",
		print_in_addr_t (network, 0, gc),
		print_in_addr_t (netmask, 0, gc));
  else
    buf_printf (&out, "route %s",
		print_in_addr_t (network, 0, gc));

  return BSTR (&out);
}
Example #8
0
struct ifconfig_pool *
ifconfig_pool_init(int type, in_addr_t start, in_addr_t end,
                   const bool duplicate_cn,
                   const bool ipv6_pool, const struct in6_addr ipv6_base,
                   const int ipv6_netbits )
{
    struct gc_arena gc = gc_new();
    struct ifconfig_pool *pool = NULL;

    ASSERT(start <= end && end - start < IFCONFIG_POOL_MAX);
    ALLOC_OBJ_CLEAR(pool, struct ifconfig_pool);

    pool->type = type;
    pool->duplicate_cn = duplicate_cn;

    switch (type)
    {
        case IFCONFIG_POOL_30NET:
            pool->base = start & ~3;
            pool->size = (((end | 3) + 1) - pool->base) >> 2;
            break;

        case IFCONFIG_POOL_INDIV:
            pool->base = start;
            pool->size = end - start + 1;
            break;

        default:
            ASSERT(0);
    }

    /* IPv6 pools are always "INDIV" type */
    pool->ipv6 = ipv6_pool;

    if (pool->ipv6)
    {
        pool->base_ipv6 = ipv6_base;
        pool->size_ipv6 = ipv6_netbits>96 ? ( 1<<(128-ipv6_netbits) )
                          : IFCONFIG_POOL_MAX;

        msg( D_IFCONFIG_POOL, "IFCONFIG POOL IPv6: (IPv4) size=%d, size_ipv6=%d, netbits=%d, base_ipv6=%s",
             pool->size, pool->size_ipv6, ipv6_netbits,
             print_in6_addr( pool->base_ipv6, 0, &gc ));

        /* the current code is very simple and assumes that the IPv6
         * pool is at least as big as the IPv4 pool, and we don't need
         * to do separate math etc. for IPv6
         */
        ASSERT( pool->size < pool->size_ipv6 );
    }

    ALLOC_ARRAY_CLEAR(pool->list, struct ifconfig_pool_entry, pool->size);

    msg(D_IFCONFIG_POOL, "IFCONFIG POOL: base=%s size=%d, ipv6=%d",
        print_in_addr_t(pool->base, 0, &gc),
        pool->size, pool->ipv6 );

    gc_free(&gc);
    return pool;
}
Example #9
0
static const char *
print_opt_route_gateway (const in_addr_t route_gateway, struct gc_arena *gc)
{
  struct buffer out = alloc_buf_gc (128, gc);
  ASSERT (route_gateway);
  buf_printf (&out, "route-gateway %s", print_in_addr_t (route_gateway, 0, gc));
  return BSTR (&out);
}
Example #10
0
static const char *
print_netmask (int netbits, struct gc_arena *gc)
{
  struct buffer out = alloc_buf_gc (128, gc);
  const in_addr_t netmask = netbits_to_netmask (netbits);

  buf_printf (&out, "%s (/%d)", print_in_addr_t (netmask, 0, gc), netbits);

  return BSTR (&out);
}
Example #11
0
File: pf.c Project: benjdag/openvpn
static void
pf_subnet_set_print(const struct pf_subnet_set *s, const int lev)
{
    struct gc_arena gc = gc_new();
    if (s)
    {
        struct pf_subnet *e;

        msg(lev, "  ----- struct pf_subnet_set -----");
        msg(lev, "  default_allow=%s", drop_accept(s->default_allow));

        for (e = s->list; e != NULL; e = e->next)
        {
            msg(lev, "   %s/%s %s",
                print_in_addr_t(e->rule.network, 0, &gc),
                print_in_addr_t(e->rule.netmask, 0, &gc),
                drop_accept(!e->rule.exclude));
        }
    }
    gc_free(&gc);
}
Example #12
0
void
print_client_nat_list(const struct client_nat_option_list *list, int msglevel)
{
    struct gc_arena gc = gc_new();
    int i;

    msg(msglevel, "*** CNAT list");
    if (list)
    {
        for (i = 0; i < list->n; ++i)
        {
            const struct client_nat_entry *e = &list->entries[i];
            msg(msglevel, "  CNAT[%d] t=%d %s/%s/%s",
                i,
                e->type,
                print_in_addr_t(e->network, IA_NET_ORDER, &gc),
                print_in_addr_t(e->netmask, IA_NET_ORDER, &gc),
                print_in_addr_t(e->foreign_network, IA_NET_ORDER, &gc));
        }
    }
    gc_free(&gc);
}
Example #13
0
static void
print_pkt(struct openvpn_iphdr *iph, const char *prefix, const int direction, const int msglevel)
{
    struct gc_arena gc = gc_new();

    char *dirstr = "???";
    if (direction == CN_OUTGOING)
    {
        dirstr = "OUT";
    }
    else if (direction == CN_INCOMING)
    {
        dirstr = "IN";
    }

    msg(msglevel, "** CNAT %s %s %s -> %s",
        dirstr,
        prefix,
        print_in_addr_t(iph->saddr, IA_NET_ORDER, &gc),
        print_in_addr_t(iph->daddr, IA_NET_ORDER, &gc));

    gc_free(&gc);
}
Example #14
0
/*
 * Verify start/end range
 */
bool
ifconfig_pool_verify_range(const int msglevel, const in_addr_t start, const in_addr_t end)
{
    struct gc_arena gc = gc_new();
    bool ret = true;

    if (start > end)
    {
        msg(msglevel, "--ifconfig-pool start IP [%s] is greater than end IP [%s]",
            print_in_addr_t(start, 0, &gc),
            print_in_addr_t(end, 0, &gc));
        ret = false;
    }
    if (end - start >= IFCONFIG_POOL_MAX)
    {
        msg(msglevel, "--ifconfig-pool address range is too large [%s -> %s].  Current maximum is %d addresses, as defined by IFCONFIG_POOL_MAX variable.",
            print_in_addr_t(start, 0, &gc),
            print_in_addr_t(end, 0, &gc),
            IFCONFIG_POOL_MAX);
        ret = false;
    }
    gc_free(&gc);
    return ret;
}
Example #15
0
/*
 * Process server, server-bridge, and client helper
 * directives after the parameters themselves have been
 * parsed and placed in struct options.
 */
void
helper_client_server (struct options *o)
{
  struct gc_arena gc = gc_new ();

#if P2MP
#if P2MP_SERVER

/*
   * Get tun/tap/null device type
   */
  const int dev = dev_type_enum (o->dev, o->dev_type);
  const int topology = o->topology;

  /* 
   *
   * HELPER DIRECTIVE for IPv6
   *
   * server-ipv6 2001:db8::/64
   *
   * EXPANDS TO:
   *
   * tun-ipv6
   * push "tun-ipv6"
   * ifconfig-ipv6 2001:db8::1 2001:db8::2
   * if !nopool: 
   *   ifconfig-ipv6-pool 2001:db8::1:0/64
   * 
   */
   if ( o->server_ipv6_defined )
     {
	if ( ! o->server_defined )
	  {
	    msg (M_USAGE, "--server-ipv6 must be used together with --server");
	  }
	if ( o->server_flags & SF_NOPOOL )
	  {
	    msg( M_USAGE, "--server-ipv6 is incompatible with 'nopool' option" );
	  }
	if ( o->ifconfig_ipv6_pool_defined )
	  {
	    msg( M_USAGE, "--server-ipv6 already defines an ifconfig-ipv6-pool, so you can't also specify --ifconfig-pool explicitly");
	  }

        /* local ifconfig is "base address + 1" and "+2" */
	o->ifconfig_ipv6_local = 
		print_in6_addr( add_in6_addr( o->server_network_ipv6, 1), 0, &o->gc );
	o->ifconfig_ipv6_remote = 
		print_in6_addr( add_in6_addr( o->server_network_ipv6, 2), 0, &o->gc );
	o->ifconfig_ipv6_netbits = o->server_netbits_ipv6;

	/* pool starts at "base address + 0x1000" - leave enough room */
	ASSERT( o->server_netbits_ipv6 <= 112 );	/* want 16 bits */

	o->ifconfig_ipv6_pool_defined = true;
	o->ifconfig_ipv6_pool_base = 
		add_in6_addr( o->server_network_ipv6, 0x1000 );
	o->ifconfig_ipv6_pool_netbits = o->server_netbits_ipv6;

	o->tun_ipv6 = true;

	push_option( o, "tun-ipv6", M_USAGE );
     }

  /*
   *
   * HELPER DIRECTIVE:
   *
   * server 10.8.0.0 255.255.255.0
   *
   * EXPANDS TO:
   *
   * mode server
   * tls-server
   * push "topology [topology]"
   *
   * if tun AND (topology == net30 OR topology == p2p):
   *   ifconfig 10.8.0.1 10.8.0.2
   *   if !nopool: 
   *     ifconfig-pool 10.8.0.4 10.8.0.251
   *   route 10.8.0.0 255.255.255.0
   *   if client-to-client:
   *     push "route 10.8.0.0 255.255.255.0"
   *   else if topology == net30:
   *     push "route 10.8.0.1"
   *
   * if tap OR (tun AND topology == subnet):
   *   ifconfig 10.8.0.1 255.255.255.0
   *   if !nopool: 
   *     ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0
   *   push "route-gateway 10.8.0.1"
   *   if route-gateway unset:
   *     route-gateway 10.8.0.2
   */

  if (o->server_defined)
    {
      int netbits = -2;
      bool status = false;

      if (o->client)
	msg (M_USAGE, "--server and --client cannot be used together");

      if (o->server_bridge_defined || o->server_bridge_proxy_dhcp)
	msg (M_USAGE, "--server and --server-bridge cannot be used together");

      if (o->shared_secret_file)
	msg (M_USAGE, "--server and --secret cannot be used together (you must use SSL/TLS keys)");

      if (!(o->server_flags & SF_NOPOOL) && o->ifconfig_pool_defined)
	msg (M_USAGE, "--server already defines an ifconfig-pool, so you can't also specify --ifconfig-pool explicitly");

      if (!(dev == DEV_TYPE_TAP || dev == DEV_TYPE_TUN))
	msg (M_USAGE, "--server directive only makes sense with --dev tun or --dev tap");

      status = netmask_to_netbits (o->server_network, o->server_netmask, &netbits);
      if (!status)
	msg (M_USAGE, "--server directive network/netmask combination is invalid");

      if (netbits < 0)
	msg (M_USAGE, "--server directive netmask is invalid");

      if (netbits < IFCONFIG_POOL_MIN_NETBITS)
	msg (M_USAGE, "--server directive netmask allows for too many host addresses (subnet must be %s or higher)",
	     print_netmask (IFCONFIG_POOL_MIN_NETBITS, &gc));

      if (dev == DEV_TYPE_TUN)
	{
	  int pool_end_reserve = 4;

	  if (netbits > 29)
	    msg (M_USAGE, "--server directive when used with --dev tun must define a subnet of %s or lower",
		 print_netmask (29, &gc));

	  if (netbits == 29)
	    pool_end_reserve = 0;

	  o->mode = MODE_SERVER;
	  o->tls_server = true;

	  if (topology == TOP_NET30 || topology == TOP_P2P)
	    {
	      o->ifconfig_local = print_in_addr_t (o->server_network + 1, 0, &o->gc);
	      o->ifconfig_remote_netmask = print_in_addr_t (o->server_network + 2, 0, &o->gc);

	      if (!(o->server_flags & SF_NOPOOL))
		{
		  o->ifconfig_pool_defined = true;
		  o->ifconfig_pool_start = o->server_network + 4;
		  o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - pool_end_reserve;
		  ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
		}

	      helper_add_route (o->server_network, o->server_netmask, o);
	      if (o->enable_c2c)
		push_option (o, print_opt_route (o->server_network, o->server_netmask, &o->gc), M_USAGE);
	      else if (topology == TOP_NET30)
		push_option (o, print_opt_route (o->server_network + 1, 0, &o->gc), M_USAGE);
	    }
	  else if (topology == TOP_SUBNET)
	    {
	      o->ifconfig_local = print_in_addr_t (o->server_network + 1, 0, &o->gc);
	      o->ifconfig_remote_netmask = print_in_addr_t (o->server_netmask, 0, &o->gc);

	      if (!(o->server_flags & SF_NOPOOL))
		{
		  o->ifconfig_pool_defined = true;
		  o->ifconfig_pool_start = o->server_network + 2;
		  o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 2;
		  ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
		}
	      o->ifconfig_pool_netmask = o->server_netmask;

	      push_option (o, print_opt_route_gateway (o->server_network + 1, &o->gc), M_USAGE);
	      if (!o->route_default_gateway)
		o->route_default_gateway = print_in_addr_t (o->server_network + 2, 0, &o->gc);
	    }
	  else
	    ASSERT (0);

	  push_option (o, print_opt_topology (topology, &o->gc), M_USAGE);
	}
      else if (dev == DEV_TYPE_TAP)
	{
	  if (netbits > 30)
	    msg (M_USAGE, "--server directive when used with --dev tap must define a subnet of %s or lower",
		 print_netmask (30, &gc));

	  o->mode = MODE_SERVER;
	  o->tls_server = true;
	  o->ifconfig_local = print_in_addr_t (o->server_network + 1, 0, &o->gc);
	  o->ifconfig_remote_netmask = print_in_addr_t (o->server_netmask, 0, &o->gc);

	  if (!(o->server_flags & SF_NOPOOL))
	    {
	      o->ifconfig_pool_defined = true;
	      o->ifconfig_pool_start = o->server_network + 2;
	      o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1;
	      ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
	    }
	  o->ifconfig_pool_netmask = o->server_netmask;

	  push_option (o, print_opt_route_gateway (o->server_network + 1, &o->gc), M_USAGE);
	}
      else
	{
	  ASSERT (0);
	}

      /* set push-ifconfig-constraint directive */
      if ((dev == DEV_TYPE_TAP || topology == TOP_SUBNET))
	{
	  o->push_ifconfig_constraint_defined = true;
	  o->push_ifconfig_constraint_network = o->server_network;
	  o->push_ifconfig_constraint_netmask = o->server_netmask;
	}
    }

  /*
   * HELPER DIRECTIVE:
   *
   * server-bridge 10.8.0.4 255.255.255.0 10.8.0.128 10.8.0.254
   *
   * EXPANDS TO:
   *
   * mode server
   * tls-server
   *
   * ifconfig-pool 10.8.0.128 10.8.0.254 255.255.255.0
   * push "route-gateway 10.8.0.4"
   *
   * OR
   *
   * server-bridge
   *
   * EXPANDS TO:
   *
   * mode server
   * tls-server
   *
   * if !nogw:
   *   push "route-gateway dhcp"
   */
  else if (o->server_bridge_defined | o->server_bridge_proxy_dhcp)
    {
      if (o->client)
	msg (M_USAGE, "--server-bridge and --client cannot be used together");

      if (!(o->server_flags & SF_NOPOOL) && o->ifconfig_pool_defined)
	msg (M_USAGE, "--server-bridge already defines an ifconfig-pool, so you can't also specify --ifconfig-pool explicitly");

      if (o->shared_secret_file)
	msg (M_USAGE, "--server-bridge and --secret cannot be used together (you must use SSL/TLS keys)");

      if (dev != DEV_TYPE_TAP)
	msg (M_USAGE, "--server-bridge directive only makes sense with --dev tap");

      if (o->server_bridge_defined)
	{
	  verify_common_subnet ("--server-bridge", o->server_bridge_ip, o->server_bridge_pool_start, o->server_bridge_netmask); 
	  verify_common_subnet ("--server-bridge", o->server_bridge_pool_start, o->server_bridge_pool_end, o->server_bridge_netmask); 
	  verify_common_subnet ("--server-bridge", o->server_bridge_ip, o->server_bridge_pool_end, o->server_bridge_netmask); 
	}

      o->mode = MODE_SERVER;
      o->tls_server = true;

      if (o->server_bridge_defined)
	{
	  o->ifconfig_pool_defined = true;
	  o->ifconfig_pool_start = o->server_bridge_pool_start;
	  o->ifconfig_pool_end = o->server_bridge_pool_end;
	  ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
	  o->ifconfig_pool_netmask = o->server_bridge_netmask;
	  push_option (o, print_opt_route_gateway (o->server_bridge_ip, &o->gc), M_USAGE);
	}
      else if (o->server_bridge_proxy_dhcp && !(o->server_flags & SF_NO_PUSH_ROUTE_GATEWAY))
	{
	  push_option (o, print_opt_route_gateway_dhcp (&o->gc), M_USAGE);
	}
    }
  else
#endif /* P2MP_SERVER */

  /*
   * HELPER DIRECTIVE:
   *
   * client
   *
   * EXPANDS TO:
   *
   * pull
   * tls-client
   */
  if (o->client)
    {
      if (o->key_method != 2)
	msg (M_USAGE, "--client requires --key-method 2");

      o->pull = true;
      o->tls_client = true;
    }

#endif /* P2MP */

  gc_free (&gc);
}
Example #16
0
void
ifconfig_pool_test(in_addr_t start, in_addr_t end)
{
    struct gc_arena gc = gc_new();
    struct ifconfig_pool *p = ifconfig_pool_init(IFCONFIG_POOL_30NET, start, end);
    /*struct ifconfig_pool *p = ifconfig_pool_init (IFCONFIG_POOL_INDIV, start, end);*/
    ifconfig_pool_handle array[256];
    int i;

    CLEAR(array);

    msg(M_INFO | M_NOPREFIX, "************ 1");
    for (i = 0; i < (int) SIZE(array); ++i)
    {
        char *cn;
        ifconfig_pool_handle h;
        in_addr_t local, remote;
        char buf[256];
        openvpn_snprintf(buf, sizeof(buf), "common-name-%d", i);
#ifdef DUP_CN
        cn = NULL;
#else
        cn = buf;
#endif
        h = ifconfig_pool_acquire(p, &local, &remote, NULL, cn);
        if (h < 0)
        {
            break;
        }
        msg(M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 1: l=%s r=%s cn=%s",
            print_in_addr_t(local, 0, &gc),
            print_in_addr_t(remote, 0, &gc),
            cn);
        array[i] = h;

    }

    msg(M_INFO | M_NOPREFIX, "************* 2");
    for (i = (int) SIZE(array) / 16; i < (int) SIZE(array) / 8; ++i)
    {
        msg(M_INFO, "Attempt to release %d cn=%s", array[i], p->list[i].common_name);
        if (!ifconfig_pool_release(p, array[i]))
        {
            break;
        }
        msg(M_INFO, "Succeeded");
    }

    CLEAR(array);

    msg(M_INFO | M_NOPREFIX, "**************** 3");
    for (i = 0; i < (int) SIZE(array); ++i)
    {
        char *cn;
        ifconfig_pool_handle h;
        in_addr_t local, remote;
        char buf[256];
        snprintf(buf, sizeof(buf), "common-name-%d", i+24);
#ifdef DUP_CN
        cn = NULL;
#else
        cn = buf;
#endif
        h = ifconfig_pool_acquire(p, &local, &remote, NULL, cn);
        if (h < 0)
        {
            break;
        }
        msg(M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 3: l=%s r=%s cn=%s",
            print_in_addr_t(local, 0, &gc),
            print_in_addr_t(remote, 0, &gc),
            cn);
        array[i] = h;

    }

    ifconfig_pool_free(p);
    gc_free(&gc);
}
Example #17
0
const char *
mroute_addr_print_ex(const struct mroute_addr *ma,
                     const unsigned int flags,
                     struct gc_arena *gc)
{
    struct buffer out = alloc_buf_gc(64, gc);
    if (ma)
    {
        struct mroute_addr maddr = *ma;

        switch (maddr.type & MR_ADDR_MASK)
        {
            case MR_ADDR_ETHER:
                buf_printf(&out, "%s", format_hex_ex(ma->eth_addr,
                                                     sizeof(ma->eth_addr), 0, 1, ":", gc));
                break;

            case MR_ADDR_IPV4:
            {
                if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
                {
                    buf_printf(&out, "ARP/");
                }
                buf_printf(&out, "%s", print_in_addr_t(ntohl(maddr.v4.addr),
                                                       (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
                if (maddr.type & MR_WITH_NETBITS)
                {
                    if (flags & MAPF_SUBNET)
                    {
                        const in_addr_t netmask = netbits_to_netmask(maddr.netbits);
                        buf_printf(&out, "/%s", print_in_addr_t(netmask, 0, gc));
                    }
                    else
                    {
                        buf_printf(&out, "/%d", maddr.netbits);
                    }
                }
                if (maddr.type & MR_WITH_PORT)
                {
                    buf_printf(&out, ":%d", ntohs(maddr.v4.port));
                }
            }
            break;

            case MR_ADDR_IPV6:
            {
                if (IN6_IS_ADDR_V4MAPPED( &maddr.v6.addr ) )
                {
                    buf_printf(&out, "%s", print_in_addr_t(maddr.v4mappedv6.addr,
                                                           IA_NET_ORDER, gc));
                    /* we only print port numbers for v4mapped v6 as of
                     * today, because "v6addr:port" is too ambiguous
                     */
                    if (maddr.type & MR_WITH_PORT)
                    {
                        buf_printf(&out, ":%d", ntohs(maddr.v6.port));
                    }
                }
                else
                {
                    buf_printf(&out, "%s", print_in6_addr(maddr.v6.addr, 0, gc));
                }
                if (maddr.type & MR_WITH_NETBITS)
                {
                    buf_printf(&out, "/%d", maddr.netbits);
                }
            }
            break;

            default:
                buf_printf(&out, "UNKNOWN");
                break;
        }
        return BSTR(&out);
    }
    else
    {
        return "[NULL]";
    }
}
Example #18
0
/**
 * Prepare push options, based on local options and available peer info.
 *
 * @param context       context structure storing data for VPN tunnel
 * @param gc            gc arena for allocating push options
 * @param push_list     push list to where options are added
 *
 * @return true on success, false on failure.
 */
static bool
prepare_push_reply(struct context *c, struct gc_arena *gc,
                   struct push_list *push_list)
{
    const char *optstr = NULL;
    struct tls_multi *tls_multi = c->c2.tls_multi;
    const char *const peer_info = tls_multi->peer_info;
    struct options *o = &c->options;

    /* ipv6 */
    if (c->c2.push_ifconfig_ipv6_defined && !o->push_ifconfig_ipv6_blocked)
    {
        push_option_fmt(gc, push_list, M_USAGE, "ifconfig-ipv6 %s/%d %s",
                        print_in6_addr(c->c2.push_ifconfig_ipv6_local, 0, gc),
                        c->c2.push_ifconfig_ipv6_netbits,
                        print_in6_addr(c->c2.push_ifconfig_ipv6_remote,
                                       0, gc));
    }

    /* ipv4 */
    if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local
        && c->c2.push_ifconfig_remote_netmask
        && !o->push_ifconfig_ipv4_blocked)
    {
        in_addr_t ifconfig_local = c->c2.push_ifconfig_local;
        if (c->c2.push_ifconfig_local_alias)
        {
            ifconfig_local = c->c2.push_ifconfig_local_alias;
        }
        push_option_fmt(gc, push_list, M_USAGE, "ifconfig %s %s",
                        print_in_addr_t(ifconfig_local, 0, gc),
                        print_in_addr_t(c->c2.push_ifconfig_remote_netmask,
                                        0, gc));
    }

    /* Send peer-id if client supports it */
    optstr = peer_info ? strstr(peer_info, "IV_PROTO=") : NULL;
    if (optstr)
    {
        int proto = 0;
        int r = sscanf(optstr, "IV_PROTO=%d", &proto);
        if ((r == 1) && (proto >= 2))
        {
            push_option_fmt(gc, push_list, M_USAGE, "peer-id %d",
                            tls_multi->peer_id);
            tls_multi->use_peer_id = true;
        }
    }

    /* Push cipher if client supports Negotiable Crypto Parameters */
    if (tls_peer_info_ncp_ver(peer_info) >= 2 && o->ncp_enabled)
    {
        /* if we have already created our key, we cannot *change* our own
         * cipher -> so log the fact and push the "what we have now" cipher
         * (so the client is always told what we expect it to use)
         */
        const struct tls_session *session = &tls_multi->session[TM_ACTIVE];
        if (session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized)
        {
            msg( M_INFO, "PUSH: client wants to negotiate cipher (NCP), but "
                 "server has already generated data channel keys, "
                 "re-sending previously negotiated cipher '%s'",
                 o->ciphername );
        }
        else
        {
            /* Push the first cipher from --ncp-ciphers to the client.
             * TODO: actual negotiation, instead of server dictatorship. */
            char *push_cipher = string_alloc(o->ncp_ciphers, &o->gc);
            o->ciphername = strtok(push_cipher, ":");
        }
        push_option_fmt(gc, push_list, M_USAGE, "cipher %s", o->ciphername);
    }
    else if (o->ncp_enabled)
    {
        tls_poor_mans_ncp(o, tls_multi->remote_ciphername);
    }

    /* If server uses --auth-gen-token and we have an auth token
     * to send to the client
     */
    if (false == tls_multi->auth_token_sent && NULL != tls_multi->auth_token)
    {
        push_option_fmt(gc, push_list, M_USAGE,
                        "auth-token %s", tls_multi->auth_token);
        tls_multi->auth_token_sent = true;
    }
    return true;
}
Example #19
0
bool
send_push_reply (struct context *c)
{
  struct gc_arena gc = gc_new ();
  struct buffer buf = alloc_buf_gc (PUSH_BUNDLE_SIZE, &gc);
  struct push_entry *e = c->options.push_list.head;
  bool multi_push = false;
  static char cmd[] = "PUSH_REPLY";
  const int extra = 84; /* extra space for possible trailing ifconfig and push-continuation */
  const int safe_cap = BCAP (&buf) - extra;
  bool push_sent = false;

  msg( M_INFO, "send_push_reply(): safe_cap=%d", safe_cap );

  buf_printf (&buf, "%s", cmd);

  if ( c->c2.push_ifconfig_ipv6_defined )
    {
      /* IPv6 is put into buffer first, could be lengthy */
      buf_printf( &buf, ",ifconfig-ipv6 %s/%d %s",
		    print_in6_addr( c->c2.push_ifconfig_ipv6_local, 0, &gc),
		    c->c2.push_ifconfig_ipv6_netbits,
		    print_in6_addr( c->c2.push_ifconfig_ipv6_remote, 0, &gc) );
      if (BLEN (&buf) >= safe_cap)
	{
	  msg (M_WARN, "--push ifconfig-ipv6 option is too long");
	  goto fail;
	}
    }

  while (e)
    {
      if (e->enable)
	{
	  const int l = strlen (e->option);
	  if (BLEN (&buf) + l >= safe_cap)
	    {
	      buf_printf (&buf, ",push-continuation 2");
	      {
		const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
		if (!status)
		  goto fail;
		push_sent = true;
		multi_push = true;
		buf_reset_len (&buf);
		buf_printf (&buf, "%s", cmd);
	      }
	    }
	  if (BLEN (&buf) + l >= safe_cap)
	    {
	      msg (M_WARN, "--push option is too long");
	      goto fail;
	    }
	  buf_printf (&buf, ",%s", e->option);
	}
      e = e->next;
    }

  if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local && c->c2.push_ifconfig_remote_netmask)
    {
      in_addr_t ifconfig_local = c->c2.push_ifconfig_local;
#ifdef ENABLE_CLIENT_NAT
      if (c->c2.push_ifconfig_local_alias)
	ifconfig_local = c->c2.push_ifconfig_local_alias;
#endif
      buf_printf (&buf, ",ifconfig %s %s",
		  print_in_addr_t (ifconfig_local, 0, &gc),
		  print_in_addr_t (c->c2.push_ifconfig_remote_netmask, 0, &gc));
    }
  if (multi_push)
    buf_printf (&buf, ",push-continuation 1");

  if (BLEN (&buf) > sizeof(cmd)-1)
    {
      const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
      if (!status)
        goto fail;
      push_sent = true;
    }

  /* If nothing have been pushed, send an empty push,
   * as the client is expecting a response
   */
  if (!push_sent)
    {
      bool status = false;

      buf_reset_len (&buf);
      buf_printf (&buf, "%s", cmd);
      status = send_control_channel_string (c, BSTR(&buf), D_PUSH);
      if (!status)
	goto fail;
    }

  gc_free (&gc);
  return true;

 fail:
  gc_free (&gc);
  return false;
}
Example #20
0
const char *
mroute_addr_print_ex (const struct mroute_addr *ma,
		      const unsigned int flags,
		      struct gc_arena *gc)
{
  struct buffer out = alloc_buf_gc (64, gc);
  if (ma)
    {
      struct mroute_addr maddr = *ma;

      switch (maddr.type & MR_ADDR_MASK)
	{
	case MR_ADDR_ETHER:
	  buf_printf (&out, "%s", format_hex_ex (ma->addr, 6, 0, 1, ":", gc)); 
	  break;
	case MR_ADDR_IPV4:
	  {
	    struct buffer buf;
	    in_addr_t addr;
	    int port;
	    bool status;
	    buf_set_read (&buf, maddr.addr, maddr.len);
	    addr = buf_read_u32 (&buf, &status);
	    if (status)
	      {
		if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
		  buf_printf (&out, "ARP/");
		buf_printf (&out, "%s", print_in_addr_t (addr, (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
		if (maddr.type & MR_WITH_NETBITS)
		  {
		    if (flags & MAPF_SUBNET)
		      {
			const in_addr_t netmask = netbits_to_netmask (maddr.netbits);
			buf_printf (&out, "/%s", print_in_addr_t (netmask, 0, gc));
		      }
		    else
		      buf_printf (&out, "/%d", maddr.netbits);
		  }
	      }
	    if (maddr.type & MR_WITH_PORT)
	      {
		port = buf_read_u16 (&buf);
		if (port >= 0)
		  buf_printf (&out, ":%d", port);
	      }
	  }
	  break;
	case MR_ADDR_IPV6:
#ifdef USE_PF_INET6
          {
	    struct buffer buf;
	    struct sockaddr_in6 sin6;
	    int port;
	    char buf6[INET6_ADDRSTRLEN] = "";
	    CLEAR(sin6);
	    sin6.sin6_family = AF_INET6;
	    buf_set_read (&buf, maddr.addr, maddr.len);
            if (buf_read(&buf, &sin6.sin6_addr, sizeof (sin6.sin6_addr)))
            {
              if (getnameinfo((struct sockaddr *)&sin6, sizeof (struct sockaddr_in6),
                                      buf6, sizeof (buf6), NULL, 0, NI_NUMERICHOST) != 0)
                {
                  buf_printf (&out, "MR_ADDR_IPV6 getnameinfo() err");
                  break;
		}
              buf_puts (&out, buf6);
	      if (maddr.type & MR_WITH_NETBITS)
	        buf_printf (&out, "/%d", maddr.netbits);
              if (maddr.type & MR_WITH_PORT)
                {
                  port = buf_read_u16 (&buf);
                  if (port >= 0)
                    buf_printf (&out, ":%d", port);
                }
	    }
          }
#else /* old, pre USE_PF_INET6 code */
	  buf_printf (&out, "IPV6"); 
#endif
	  break;
	default:
	  buf_printf (&out, "UNKNOWN"); 
	  break;
	}
      return BSTR (&out);
    }
  else
    return "[NULL]";
}