~ubuntu-branches/ubuntu/oneiric/openvpn/oneiric

« back to all changes in this revision

Viewing changes to multi.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2011-06-16 18:33:37 UTC
  • mfrom: (1.1.17 upstream) (10.2.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110616183337-fv50u3kmiabewjq0
Tags: 2.2.0-2ubuntu1
* Merge from debian unstable.  Remaining changes:
 + debian/openvpn.init.d:
    - Do not use start-stop-daemon and </dev/null to avoid blocking boot.
    - Show per-VPN result messages.
    - Add "--script-security 2" by default for backwards compatabliity.
  + debian/control: Add lsb-base >= 3.2-14 to allow status_of_proc()
  + debian/update-resolv-conf: Support multiple domains.
  + fix bug where '--script-security 2' would be passed for all
    daemons after the first. (LP: #794916

Show diffs side-by-side

added added

removed removed

Lines of Context:
109
109
                   mroute_addr_print (addr, &gc));
110
110
      if (mi)
111
111
        argv_printf_cat (&argv, "%s", tls_common_name (mi->context.c2.tls_multi, false));
112
 
      if (!openvpn_execve_check (&argv, es, S_SCRIPT, "WARNING: learn-address command failed"))
 
112
      if (!openvpn_run_script (&argv, es, 0, "--learn-address"))
113
113
        ret = false;
114
114
      argv_reset (&argv);
115
115
    }
146
146
    }
147
147
 
148
148
  dmsg (D_MULTI_DEBUG, "MULTI: REAP range %d -> %d", start_bucket, end_bucket);
149
 
  hash_iterator_init_range (m->vhash, &hi, true, start_bucket, end_bucket);
 
149
  hash_iterator_init_range (m->vhash, &hi, start_bucket, end_bucket);
150
150
  while ((he = hash_iterator_next (&hi)) != NULL)
151
151
    {
152
152
      struct multi_route *r = (struct multi_route *) he->value;
316
316
   */
317
317
  if (t->options.ifconfig_pool_defined)
318
318
    {
319
 
      if (dev == DEV_TYPE_TAP)
320
 
        {
321
 
          m->ifconfig_pool = ifconfig_pool_init (IFCONFIG_POOL_INDIV,
322
 
                                                 t->options.ifconfig_pool_start,
323
 
                                                 t->options.ifconfig_pool_end,
324
 
                                                 t->options.duplicate_cn);
325
 
        }
326
 
      else if (dev == DEV_TYPE_TUN)
327
 
        {
328
 
          m->ifconfig_pool = ifconfig_pool_init (
329
 
            (t->options.topology == TOP_NET30) ? IFCONFIG_POOL_30NET : IFCONFIG_POOL_INDIV,
330
 
            t->options.ifconfig_pool_start,
331
 
            t->options.ifconfig_pool_end,
332
 
            t->options.duplicate_cn);
333
 
        }
334
 
      else
335
 
        {
336
 
          ASSERT (0);
337
 
        }
 
319
      int pool_type = IFCONFIG_POOL_INDIV;
 
320
 
 
321
      if ( dev == DEV_TYPE_TUN && t->options.topology == TOP_NET30 )
 
322
        pool_type = IFCONFIG_POOL_30NET;
 
323
 
 
324
      m->ifconfig_pool = ifconfig_pool_init (pool_type,
 
325
                                 t->options.ifconfig_pool_start,
 
326
                                 t->options.ifconfig_pool_end,
 
327
                                 t->options.duplicate_cn,
 
328
                                 t->options.ifconfig_ipv6_pool_defined,
 
329
                                 t->options.ifconfig_ipv6_pool_base,
 
330
                                 t->options.ifconfig_ipv6_pool_netbits );
338
331
 
339
332
      /* reload pool data from file */
340
333
      if (t->c1.ifconfig_pool_persist)
429
422
                   struct multi_instance *mi)
430
423
{
431
424
  const struct iroute *ir;
 
425
  const struct iroute_ipv6 *ir6;
432
426
  if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN)
433
427
    {
434
428
      for (ir = mi->context.options.iroutes; ir != NULL; ir = ir->next)
435
429
        mroute_helper_del_iroute (m->route_helper, ir);
 
430
 
 
431
      for ( ir6 = mi->context.options.iroutes_ipv6; ir6 != NULL; ir6 = ir6->next )
 
432
        mroute_helper_del_iroute6 (m->route_helper, ir6);
436
433
    }
437
434
}
438
435
 
480
477
          struct argv argv = argv_new ();
481
478
          setenv_str (mi->context.c2.es, "script_type", "client-disconnect");
482
479
          argv_printf (&argv, "%sc", mi->context.options.client_disconnect_script);
483
 
          openvpn_execve_check (&argv, mi->context.c2.es, S_SCRIPT, "client-disconnect command failed");
 
480
          openvpn_run_script (&argv, mi->context.c2.es, 0, "--client-disconnect");
484
481
          argv_reset (&argv);
485
482
        }
486
483
#ifdef MANAGEMENT_DEF_AUTH
587
584
          struct hash_iterator hi;
588
585
          struct hash_element *he;
589
586
 
590
 
          hash_iterator_init (m->iter, &hi, true);
 
587
          hash_iterator_init (m->iter, &hi);
591
588
          while ((he = hash_iterator_next (&hi)))
592
589
            {
593
590
              struct multi_instance *mi = (struct multi_instance *) he->value;
633
630
 
634
631
  ALLOC_OBJ_CLEAR (mi, struct multi_instance);
635
632
 
636
 
  mutex_init (&mi->mutex);
637
633
  mi->gc = gc_new ();
638
634
  multi_instance_inc_refcount (mi);
639
635
  mi->vaddr_handle = -1;
724
720
          status_printf (so, "OpenVPN CLIENT LIST");
725
721
          status_printf (so, "Updated,%s", time_string (0, 0, false, &gc_top));
726
722
          status_printf (so, "Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since");
727
 
          hash_iterator_init (m->hash, &hi, true);
 
723
          hash_iterator_init (m->hash, &hi);
728
724
          while ((he = hash_iterator_next (&hi)))
729
725
            {
730
726
              struct gc_arena gc = gc_new ();
745
741
 
746
742
          status_printf (so, "ROUTING TABLE");
747
743
          status_printf (so, "Virtual Address,Common Name,Real Address,Last Ref");
748
 
          hash_iterator_init (m->vhash, &hi, true);
 
744
          hash_iterator_init (m->vhash, &hi);
749
745
          while ((he = hash_iterator_next (&hi)))
750
746
            {
751
747
              struct gc_arena gc = gc_new ();
788
784
          status_printf (so, "TIME%c%s%c%u", sep, time_string (now, 0, false, &gc_top), sep, (unsigned int)now);
789
785
          status_printf (so, "HEADER%cCLIENT_LIST%cCommon Name%cReal Address%cVirtual Address%cBytes Received%cBytes Sent%cConnected Since%cConnected Since (time_t)",
790
786
                         sep, sep, sep, sep, sep, sep, sep, sep);
791
 
          hash_iterator_init (m->hash, &hi, true);
 
787
          hash_iterator_init (m->hash, &hi);
792
788
          while ((he = hash_iterator_next (&hi)))
793
789
            {
794
790
              struct gc_arena gc = gc_new ();
811
807
 
812
808
          status_printf (so, "HEADER%cROUTING_TABLE%cVirtual Address%cCommon Name%cReal Address%cLast Ref%cLast Ref (time_t)",
813
809
                         sep, sep, sep, sep, sep, sep);
814
 
          hash_iterator_init (m->vhash, &hi, true);
 
810
          hash_iterator_init (m->vhash, &hi);
815
811
          while ((he = hash_iterator_next (&hi)))
816
812
            {
817
813
              struct gc_arena gc = gc_new ();
850
846
#ifdef PACKET_TRUNCATION_CHECK
851
847
      {
852
848
        status_printf (so, "HEADER,ERRORS,Common Name,TUN Read Trunc,TUN Write Trunc,Pre-encrypt Trunc,Post-decrypt Trunc");
853
 
        hash_iterator_init (m->hash, &hi, true);
 
849
        hash_iterator_init (m->hash, &hi);
854
850
        while ((he = hash_iterator_next (&hi)))
855
851
            {
856
852
              struct gc_arena gc = gc_new ();
896
892
  struct multi_route *oldroute = NULL;
897
893
  struct multi_instance *owner = NULL;
898
894
 
899
 
  hash_bucket_lock (bucket);
900
 
 
901
895
  /* if route currently exists, get the instance which owns it */
902
896
  he = hash_lookup_fast (m->vhash, bucket, addr, hv);
903
897
  if (he)
967
961
      gc_free (&gc);
968
962
    }
969
963
 
970
 
  hash_bucket_unlock (bucket);
971
964
  return owner;
972
965
}
973
966
 
1001
994
      struct mroute_addr tryaddr;
1002
995
      int i;
1003
996
 
1004
 
      mroute_helper_lock (rh);
1005
 
 
1006
997
      /* cycle through each CIDR length */
1007
998
      for (i = 0; i < rh->n_net_len; ++i)
1008
999
        {
1023
1014
              break;
1024
1015
            }
1025
1016
        }
1026
 
      
1027
 
      mroute_helper_unlock (rh);
1028
1017
    }
1029
1018
  
1030
1019
#ifdef ENABLE_DEBUG
1086
1075
  }
1087
1076
}
1088
1077
 
 
1078
static struct multi_instance *
 
1079
multi_learn_in6_addr  (struct multi_context *m,
 
1080
                       struct multi_instance *mi,
 
1081
                       struct in6_addr a6,
 
1082
                       int netbits, /* -1 if host route, otherwise # of network bits in address */
 
1083
                       bool primary)
 
1084
{
 
1085
  struct mroute_addr addr;
 
1086
 
 
1087
  addr.len = 16;
 
1088
  addr.type = MR_ADDR_IPV6;
 
1089
  addr.netbits = 0;
 
1090
  memcpy( &addr.addr, &a6, sizeof(a6) );
 
1091
 
 
1092
  if (netbits >= 0)
 
1093
    {
 
1094
      addr.type |= MR_WITH_NETBITS;
 
1095
      addr.netbits = (uint8_t) netbits;
 
1096
      mroute_addr_mask_host_bits( &addr );
 
1097
    }
 
1098
 
 
1099
  {
 
1100
    struct multi_instance *owner = multi_learn_addr (m, mi, &addr, 0);
 
1101
#ifdef MANAGEMENT_DEF_AUTH
 
1102
    if (management && owner)
 
1103
      management_learn_addr (management, &mi->context.c2.mda_context, &addr, primary);
 
1104
#endif
 
1105
    return owner;
 
1106
  }
 
1107
}
 
1108
 
1089
1109
/*
1090
1110
 * A new client has connected, add routes (server -> client)
1091
1111
 * to internal routing table.
1096
1116
{
1097
1117
  struct gc_arena gc = gc_new ();
1098
1118
  const struct iroute *ir;
 
1119
  const struct iroute_ipv6 *ir6;
1099
1120
  if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN)
1100
1121
    {
1101
1122
      mi->did_iroutes = true;
1115
1136
      
1116
1137
          multi_learn_in_addr_t (m, mi, ir->network, ir->netbits, false);
1117
1138
        }
 
1139
      for ( ir6 = mi->context.options.iroutes_ipv6; ir6 != NULL; ir6 = ir6->next )
 
1140
        {
 
1141
          if (ir6->netbits >= 0)
 
1142
            msg (D_MULTI_LOW, "MULTI: internal route %s/%d -> %s",
 
1143
                 print_in6_addr (ir6->network, 0, &gc),
 
1144
                 ir6->netbits,
 
1145
                 multi_instance_string (mi, false, &gc));
 
1146
          else
 
1147
            msg (D_MULTI_LOW, "MULTI: internal route %s -> %s",
 
1148
                 print_in6_addr (ir6->network, 0, &gc),
 
1149
                 multi_instance_string (mi, false, &gc));
 
1150
 
 
1151
          mroute_helper_add_iroute6 (m->route_helper, ir6);
 
1152
      
 
1153
          multi_learn_in6_addr (m, mi, ir6->network, ir6->netbits, false);
 
1154
        }
1118
1155
    }
1119
1156
  gc_free (&gc);
1120
1157
}
1135
1172
          struct hash_element *he;
1136
1173
          int count = 0;
1137
1174
 
1138
 
          hash_iterator_init (m->iter, &hi, true);
 
1175
          hash_iterator_init (m->iter, &hi);
1139
1176
          while ((he = hash_iterator_next (&hi)))
1140
1177
            {
1141
1178
              struct multi_instance *mi = (struct multi_instance *) he->value;
1200
1237
      mi->context.c2.push_ifconfig_defined = true;
1201
1238
      mi->context.c2.push_ifconfig_local = mi->context.options.push_ifconfig_local;
1202
1239
      mi->context.c2.push_ifconfig_remote_netmask = mi->context.options.push_ifconfig_remote_netmask;
 
1240
 
 
1241
      /* the current implementation does not allow "static IPv4, pool IPv6",
 
1242
       * (see below) so issue a warning if that happens - don't break the
 
1243
       * session, though, as we don't even know if this client WANTS IPv6
 
1244
       */
 
1245
      if ( mi->context.c1.tuntap->ipv6 &&
 
1246
           mi->context.options.ifconfig_ipv6_pool_defined &&
 
1247
           ! mi->context.options.push_ifconfig_ipv6_defined )
 
1248
        {
 
1249
          msg( M_INFO, "MULTI_sva: WARNING: if --ifconfig-push is used for IPv4, automatic IPv6 assignment from --ifconfig-ipv6-pool does not work.  Use --ifconfig-ipv6-push for IPv6 then." );
 
1250
        }
1203
1251
    }
1204
1252
  else if (m->ifconfig_pool && mi->vaddr_handle < 0) /* otherwise, choose a pool address */
1205
1253
    {
1206
1254
      in_addr_t local=0, remote=0;
 
1255
      struct in6_addr remote_ipv6;
1207
1256
      const char *cn = NULL;
1208
1257
 
1209
1258
      if (!mi->context.options.duplicate_cn)
1210
1259
        cn = tls_common_name (mi->context.c2.tls_multi, true);
1211
1260
 
1212
 
      mi->vaddr_handle = ifconfig_pool_acquire (m->ifconfig_pool, &local, &remote, cn);
 
1261
      mi->vaddr_handle = ifconfig_pool_acquire (m->ifconfig_pool, &local, &remote, &remote_ipv6, cn);
1213
1262
      if (mi->vaddr_handle >= 0)
1214
1263
        {
1215
1264
          const int tunnel_type = TUNNEL_TYPE (mi->context.c1.tuntap);
1216
1265
          const int tunnel_topology = TUNNEL_TOPOLOGY (mi->context.c1.tuntap);
1217
1266
 
 
1267
          msg( M_INFO, "MULTI_sva: pool returned IPv4=%s, IPv6=%s", 
 
1268
                    print_in_addr_t( remote, 0, &gc ),
 
1269
                    print_in6_addr( remote_ipv6, 0, &gc ) );
 
1270
 
1218
1271
          /* set push_ifconfig_remote_netmask from pool ifconfig address(es) */
1219
1272
          mi->context.c2.push_ifconfig_local = remote;
1220
1273
          if (tunnel_type == DEV_TYPE_TAP || (tunnel_type == DEV_TYPE_TUN && tunnel_topology == TOP_SUBNET))
1236
1289
          else
1237
1290
            msg (D_MULTI_ERRORS, "MULTI: no --ifconfig-pool netmask parameter is available to push to %s",
1238
1291
                 multi_instance_string (mi, false, &gc));
 
1292
 
 
1293
          if ( mi->context.options.ifconfig_ipv6_pool_defined )
 
1294
            {
 
1295
              mi->context.c2.push_ifconfig_ipv6_local = remote_ipv6;
 
1296
              mi->context.c2.push_ifconfig_ipv6_remote = 
 
1297
                    mi->context.c1.tuntap->local_ipv6;
 
1298
              mi->context.c2.push_ifconfig_ipv6_netbits = 
 
1299
                    mi->context.options.ifconfig_ipv6_pool_netbits;
 
1300
              mi->context.c2.push_ifconfig_ipv6_defined = true;
 
1301
            }
1239
1302
        }
1240
1303
      else
1241
1304
        {
1242
1305
          msg (D_MULTI_ERRORS, "MULTI: no free --ifconfig-pool addresses are available");
1243
1306
        }
1244
1307
    }
 
1308
 
 
1309
  /* IPv6 push_ifconfig is a bit problematic - since IPv6 shares the 
 
1310
   * pool handling with IPv4, the combination "static IPv4, dynamic IPv6"
 
1311
   * will fail (because no pool will be allocated in this case).
 
1312
   * OTOH, this doesn't make too much sense in reality - and the other
 
1313
   * way round ("dynamic IPv4, static IPv6") or "both static" makes sense
 
1314
   * -> and so it's implemented right now
 
1315
   */
 
1316
  if ( mi->context.c1.tuntap->ipv6 &&
 
1317
       mi->context.options.push_ifconfig_ipv6_defined )
 
1318
    {
 
1319
      mi->context.c2.push_ifconfig_ipv6_local = 
 
1320
            mi->context.options.push_ifconfig_ipv6_local;
 
1321
      mi->context.c2.push_ifconfig_ipv6_remote = 
 
1322
            mi->context.options.push_ifconfig_ipv6_remote;
 
1323
      mi->context.c2.push_ifconfig_ipv6_netbits = 
 
1324
            mi->context.options.push_ifconfig_ipv6_netbits;
 
1325
      mi->context.c2.push_ifconfig_ipv6_defined = true;
 
1326
 
 
1327
      msg( M_INFO, "MULTI_sva: push_ifconfig_ipv6 %s/%d", 
 
1328
            print_in6_addr( mi->context.c2.push_ifconfig_ipv6_local, 0, &gc ),
 
1329
            mi->context.c2.push_ifconfig_ipv6_netbits );
 
1330
    }
 
1331
 
1245
1332
  gc_free (&gc);
1246
1333
}
1247
1334
 
1280
1367
                            SA_SET_IF_NONZERO);
1281
1368
        }
1282
1369
    }
 
1370
 
 
1371
    /* TODO: I'm not exactly sure what these environment variables are
 
1372
     *       used for, but if we have them for IPv4, we should also have
 
1373
     *       them for IPv6, no?
 
1374
     */
1283
1375
}
1284
1376
 
1285
1377
/*
1594
1686
                       mi->context.options.client_connect_script,
1595
1687
                       dc_file);
1596
1688
 
1597
 
          if (openvpn_execve_check (&argv, mi->context.c2.es, S_SCRIPT, "client-connect command failed"))
 
1689
          if (openvpn_run_script (&argv, mi->context.c2.es, 0, "--client-connect"))
1598
1690
            {
1599
1691
              multi_client_connect_post (m, mi, dc_file, option_permissions_mask, &option_types_found);
1600
1692
              ++cc_succeeded_count;
1669
1761
                       print_in_addr_t (mi->context.c2.push_ifconfig_local, 0, &gc));
1670
1762
                }
1671
1763
 
 
1764
              if (mi->context.c2.push_ifconfig_ipv6_defined)
 
1765
                {
 
1766
                  multi_learn_in6_addr (m, mi, mi->context.c2.push_ifconfig_ipv6_local, -1, true);
 
1767
                  /* TODO: find out where addresses are "unlearned"!! */
 
1768
                  msg (D_MULTI_LOW, "MULTI: primary virtual IPv6 for %s: %s",
 
1769
                       multi_instance_string (mi, false, &gc),
 
1770
                       print_in6_addr (mi->context.c2.push_ifconfig_ipv6_local, 0, &gc));
 
1771
                }
 
1772
 
1672
1773
              /* add routes locally, pointing to new client, if
1673
1774
                 --iroute options have been specified */
1674
1775
              multi_add_iroutes (m, mi);
1781
1882
      printf ("BCAST len=%d\n", BLEN (buf));
1782
1883
#endif
1783
1884
      mb = mbuf_alloc_buf (buf);
1784
 
      hash_iterator_init (m->iter, &hi, true);
 
1885
      hash_iterator_init (m->iter, &hi);
1785
1886
 
1786
1887
      while ((he = hash_iterator_next (&hi)))
1787
1888
        {
2249
2350
{
2250
2351
  struct mbuf_item item;
2251
2352
 
2252
 
  if (mbuf_extract_item (ms, &item, true)) /* cleartext IP packet */
 
2353
  if (mbuf_extract_item (ms, &item)) /* cleartext IP packet */
2253
2354
    {
2254
2355
      unsigned int pipv4_flags = PIPV4_PASSTOS;
2255
2356
 
2475
2576
  struct hash_element *he;
2476
2577
  int count = 0;
2477
2578
 
2478
 
  hash_iterator_init (m->iter, &hi, true);
 
2579
  hash_iterator_init (m->iter, &hi);
2479
2580
  while ((he = hash_iterator_next (&hi)))
2480
2581
    {
2481
2582
      struct multi_instance *mi = (struct multi_instance *) he->value;
2509
2610
  saddr.addr.in4.sin_port = htons (port);
2510
2611
  if (mroute_extract_openvpn_sockaddr (&maddr, &saddr, true))
2511
2612
    {
2512
 
      hash_iterator_init (m->iter, &hi, true);
 
2613
      hash_iterator_init (m->iter, &hi);
2513
2614
      while ((he = hash_iterator_next (&hi)))
2514
2615
        {
2515
2616
          struct multi_instance *mi = (struct multi_instance *) he->value;