/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to plugins.d/mandos-client.c

  • Committer: Teddy Hogeborn
  • Date: 2015-03-10 18:03:38 UTC
  • Revision ID: teddy@recompile.se-20150310180338-pcxw6r2qmw9k6br9
Add ":!RSA" to GnuTLS priority string, to disallow non-DHE kx.

If Mandos was somehow made to use a non-ephemeral Diffie-Hellman key
exchange algorithm in the TLS handshake, any saved network traffic
could then be decrypted later if the Mandos client key was obtained.
By default, Mandos uses ephemeral DH key exchanges which does not have
this problem, but a non-ephemeral key exchange algorithm was still
enabled by default.  The simplest solution is to simply turn that off,
which ensures that Mandos will always use ephemeral DH key exchanges.

There is a "PFS" priority string specifier, but we can't use it because:

1. Security-wise, it is a mix between "NORMAL" and "SECURE128" - it
   enables a lot more algorithms than "SECURE256".

2. It is only available since GnuTLS 3.2.4.

Thanks to Andreas Fischer <af@bantuX.org> for reporting this issue.

Show diffs side-by-side

added added

removed removed

Lines of Context:
234
234
                          .af = af };
235
235
  if(new_server->ip == NULL){
236
236
    perror_plus("strdup");
 
237
    free(new_server);
237
238
    return false;
238
239
  }
239
240
  ret = clock_gettime(CLOCK_MONOTONIC, &(new_server->last_seen));
240
241
  if(ret == -1){
241
242
    perror_plus("clock_gettime");
 
243
#ifdef __GNUC__
 
244
#pragma GCC diagnostic push
 
245
#pragma GCC diagnostic ignored "-Wcast-qual"
 
246
#endif
 
247
    free((char *)(new_server->ip));
 
248
#ifdef __GNUC__
 
249
#pragma GCC diagnostic pop
 
250
#endif
 
251
    free(new_server);
242
252
    return false;
243
253
  }
244
254
  /* Special case of first server */
1066
1076
     timed out */
1067
1077
  
1068
1078
  if(quit_now){
 
1079
    avahi_s_service_resolver_free(r);
1069
1080
    return;
1070
1081
  }
1071
1082
  
1458
1469
  error_t ret_errno = 0;
1459
1470
  if(seteuid(0) == -1){
1460
1471
    ret_errno = errno;
1461
 
    perror_plus("seteuid");
1462
1472
  }
1463
1473
  errno = old_errno;
1464
1474
  return ret_errno;
1475
1485
  }
1476
1486
  if(setuid(0) == -1){
1477
1487
    ret_errno = errno;
1478
 
    perror_plus("seteuid");
1479
1488
  }
1480
1489
  errno = old_errno;
1481
1490
  return ret_errno;
1488
1497
  error_t ret_errno = 0;
1489
1498
  if(seteuid(uid) == -1){
1490
1499
    ret_errno = errno;
1491
 
    perror_plus("seteuid");
1492
1500
  }
1493
1501
  errno = old_errno;
1494
1502
  return ret_errno;
1501
1509
  error_t ret_errno = 0;
1502
1510
  if(setuid(uid) == -1){
1503
1511
    ret_errno = errno;
1504
 
    perror_plus("setuid");
1505
1512
  }
1506
1513
  errno = old_errno;
1507
1514
  return ret_errno;
1510
1517
__attribute__((nonnull))
1511
1518
void run_network_hooks(const char *mode, const char *interface,
1512
1519
                       const float delay){
1513
 
  struct dirent **direntries;
 
1520
  struct dirent **direntries = NULL;
1514
1521
  if(hookdir_fd == -1){
1515
1522
    hookdir_fd = open(hookdir, O_RDONLY);
1516
1523
    if(hookdir_fd == -1){
1554
1561
    if(hook_pid == 0){
1555
1562
      /* Child */
1556
1563
      /* Raise privileges */
1557
 
      if(raise_privileges_permanently() != 0){
 
1564
      errno = raise_privileges_permanently();
 
1565
      if(errno != 0){
1558
1566
        perror_plus("Failed to raise privileges");
1559
1567
        _exit(EX_NOPERM);
1560
1568
      }
1642
1650
        _exit(EXIT_FAILURE);
1643
1651
      }
1644
1652
    } else {
 
1653
      if(hook_pid == -1){
 
1654
        perror_plus("fork");
 
1655
        free(direntry);
 
1656
        continue;
 
1657
      }
1645
1658
      int status;
1646
1659
      if(TEMP_FAILURE_RETRY(waitpid(hook_pid, &status, 0)) == -1){
1647
1660
        perror_plus("waitpid");
 
1661
        free(direntry);
1648
1662
        continue;
1649
1663
      }
1650
1664
      if(WIFEXITED(status)){
1652
1666
          fprintf_plus(stderr, "Warning: network hook \"%s\" exited"
1653
1667
                       " with status %d\n", direntry->d_name,
1654
1668
                       WEXITSTATUS(status));
 
1669
          free(direntry);
1655
1670
          continue;
1656
1671
        }
1657
1672
      } else if(WIFSIGNALED(status)){
1658
1673
        fprintf_plus(stderr, "Warning: network hook \"%s\" died by"
1659
1674
                     " signal %d\n", direntry->d_name,
1660
1675
                     WTERMSIG(status));
 
1676
        free(direntry);
1661
1677
        continue;
1662
1678
      } else {
1663
1679
        fprintf_plus(stderr, "Warning: network hook \"%s\""
1664
1680
                     " crashed\n", direntry->d_name);
 
1681
        free(direntry);
1665
1682
        continue;
1666
1683
      }
1667
1684
    }
1669
1686
      fprintf_plus(stderr, "Network hook \"%s\" ran successfully\n",
1670
1687
                   direntry->d_name);
1671
1688
    }
 
1689
    free(direntry);
1672
1690
  }
 
1691
  free(direntries);
1673
1692
  if((int)TEMP_FAILURE_RETRY(close(hookdir_fd)) == -1){
1674
1693
    perror_plus("close");
1675
1694
  } else {
1732
1751
    /* Raise privileges */
1733
1752
    ret_errno = raise_privileges();
1734
1753
    if(ret_errno != 0){
 
1754
      errno = ret_errno;
1735
1755
      perror_plus("Failed to raise privileges");
1736
1756
    }
1737
1757
    
1841
1861
    /* Raise privileges */
1842
1862
    ret_errno = raise_privileges();
1843
1863
    if(ret_errno != 0){
 
1864
      errno = ret_errno;
1844
1865
      perror_plus("Failed to raise privileges");
1845
1866
    }
1846
1867
    
1881
1902
int main(int argc, char *argv[]){
1882
1903
  mandos_context mc = { .server = NULL, .dh_bits = 1024,
1883
1904
                        .priority = "SECURE256:!CTYPE-X.509:"
1884
 
                        "+CTYPE-OPENPGP", .current_server = NULL,
 
1905
                        "+CTYPE-OPENPGP:!RSA", .current_server = NULL,
1885
1906
                        .interfaces = NULL, .interfaces_size = 0 };
1886
1907
  AvahiSServiceBrowser *sb = NULL;
1887
1908
  error_t ret_errno;
2253
2274
  
2254
2275
  /* If no interfaces were specified, make a list */
2255
2276
  if(mc.interfaces == NULL){
2256
 
    struct dirent **direntries;
 
2277
    struct dirent **direntries = NULL;
2257
2278
    /* Look for any good interfaces */
2258
2279
    ret = scandir(sys_class_net, &direntries, good_interface,
2259
2280
                  alphasort);
2265
2286
        if(ret_errno != 0){
2266
2287
          errno = ret_errno;
2267
2288
          perror_plus("argz_add");
 
2289
          free(direntries[i]);
2268
2290
          continue;
2269
2291
        }
2270
2292
        if(debug){
2271
2293
          fprintf_plus(stderr, "Will use interface \"%s\"\n",
2272
2294
                       direntries[i]->d_name);
2273
2295
        }
 
2296
        free(direntries[i]);
2274
2297
      }
2275
2298
      free(direntries);
2276
2299
    } else {
2277
 
      free(direntries);
 
2300
      if(ret == 0){
 
2301
        free(direntries);
 
2302
      }
2278
2303
      fprintf_plus(stderr, "Could not find a network interface\n");
2279
2304
      exitcode = EXIT_FAILURE;
2280
2305
      goto end;
2544
2569
    mc.current_server->prev->next = NULL;
2545
2570
    while(mc.current_server != NULL){
2546
2571
      server *next = mc.current_server->next;
 
2572
#ifdef __GNUC__
 
2573
#pragma GCC diagnostic push
 
2574
#pragma GCC diagnostic ignored "-Wcast-qual"
 
2575
#endif
 
2576
      free((char *)(mc.current_server->ip));
 
2577
#ifdef __GNUC__
 
2578
#pragma GCC diagnostic pop
 
2579
#endif
2547
2580
      free(mc.current_server);
2548
2581
      mc.current_server = next;
2549
2582
    }
2553
2586
  {
2554
2587
    ret_errno = raise_privileges();
2555
2588
    if(ret_errno != 0){
 
2589
      errno = ret_errno;
2556
2590
      perror_plus("Failed to raise privileges");
2557
2591
    } else {
2558
2592
      
2581
2615
    
2582
2616
    ret_errno = lower_privileges_permanently();
2583
2617
    if(ret_errno != 0){
 
2618
      errno = ret_errno;
2584
2619
      perror_plus("Failed to lower privileges permanently");
2585
2620
    }
2586
2621
  }
2608
2643
      int numentries = scandir(tempdir, &direntries, notdotentries,
2609
2644
                               alphasort);
2610
2645
#endif  /* not __GLIBC__ */
2611
 
      if(numentries > 0){
 
2646
      if(numentries >= 0){
2612
2647
        for(int i = 0; i < numentries; i++){
2613
2648
          ret = unlinkat(tempdir_fd, direntries[i]->d_name, 0);
2614
2649
          if(ret == -1){
2616
2651
                         " \"%s\", 0): %s\n", tempdir,
2617
2652
                         direntries[i]->d_name, strerror(errno));
2618
2653
          }
 
2654
          free(direntries[i]);
2619
2655
        }
2620
2656
        
2621
2657
        /* need to clean even if 0 because man page doesn't specify */