/mandos/release

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

« back to all changes in this revision

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

  • Committer: Teddy Hogeborn
  • Date: 2014-07-25 22:44:20 UTC
  • mto: (237.7.272 trunk)
  • mto: This revision was merged to the branch mainline in revision 321.
  • Revision ID: teddy@recompile.se-20140725224420-4a5ct2ptt0hsc92z
Require Python 2.7.

This is in preparation for the eventual move to Python 3, which will
happen as soon as all Python modules required by Mandos are available.
The mandos-ctl and mandos-monitor programs are already portable
between Python 2.6 and Python 3 without changes; this change will
bring the requirement up to Python 2.7.

* INSTALL (Prerequisites/Libraries/Mandos Server): Document
                                                   requirement of
                                                   Python 2.7; remove
                                                   Python-argparse
                                                   which is in the
                                                   Python 2.7 standard
                                                   library.
* debian/control (Source: mandos/Build-Depends-Indep): Depend on
                                                       exactly the
                                                       python2.7
                                                       package and all
                                                       the Python 2.7
                                                       versions of the
                                                       python modules.
  (Package: mandos/Depends): - '' - but still depend on python (<=2.7)
                            and the generic versions of the Python
                            modules; this is for mandos-ctl and
                            mandos-monitor, both of which are
                            compatible with Python 3, and use
                            #!/usr/bin/python.
* mandos: Use #!/usr/bin/python2.7 instead of #!/usr/bin/python.

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;
1508
1515
}
1509
1516
 
1510
 
#ifndef O_CLOEXEC
1511
 
/*
1512
 
 * Based on the example in the GNU LibC manual chapter 13.13 "File
1513
 
 * Descriptor Flags".
1514
 
 | [[info:libc:Descriptor%20Flags][File Descriptor Flags]] |
1515
 
 */
1516
 
__attribute__((warn_unused_result))
1517
 
static int set_cloexec_flag(int fd){
1518
 
  int ret = (int)TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD, 0));
1519
 
  /* If reading the flags failed, return error indication now. */
1520
 
  if(ret < 0){
1521
 
    return ret;
1522
 
  }
1523
 
  /* Store modified flag word in the descriptor. */
1524
 
  return (int)TEMP_FAILURE_RETRY(fcntl(fd, F_SETFD,
1525
 
                                       ret | FD_CLOEXEC));
1526
 
}
1527
 
#endif  /* not O_CLOEXEC */
1528
 
 
1529
1517
__attribute__((nonnull))
1530
1518
void run_network_hooks(const char *mode, const char *interface,
1531
1519
                       const float delay){
1532
 
  struct dirent **direntries;
 
1520
  struct dirent **direntries = NULL;
1533
1521
  if(hookdir_fd == -1){
1534
 
    hookdir_fd = open(hookdir, O_RDONLY |
1535
 
#ifdef O_CLOEXEC
1536
 
                      O_CLOEXEC
1537
 
#else  /* not O_CLOEXEC */
1538
 
                      0
1539
 
#endif  /* not O_CLOEXEC */
1540
 
                      );
 
1522
    hookdir_fd = open(hookdir, O_RDONLY);
1541
1523
    if(hookdir_fd == -1){
1542
1524
      if(errno == ENOENT){
1543
1525
        if(debug){
1549
1531
      }
1550
1532
      return;
1551
1533
    }
1552
 
#ifndef O_CLOEXEC
1553
 
    if(set_cloexec_flag(hookdir_fd) < 0){
1554
 
      perror_plus("set_cloexec_flag");
1555
 
      if((int)TEMP_FAILURE_RETRY(close(hookdir_fd)) == -1){
1556
 
        perror_plus("close");
1557
 
      } else {
1558
 
        hookdir_fd = -1;
1559
 
      }
1560
 
      return;
1561
 
    }
1562
 
#endif  /* not O_CLOEXEC */
1563
1534
  }
1564
1535
#ifdef __GLIBC__
1565
1536
#if __GLIBC_PREREQ(2, 15)
1590
1561
    if(hook_pid == 0){
1591
1562
      /* Child */
1592
1563
      /* Raise privileges */
1593
 
      if(raise_privileges_permanently() != 0){
 
1564
      errno = raise_privileges_permanently();
 
1565
      if(errno != 0){
1594
1566
        perror_plus("Failed to raise privileges");
1595
1567
        _exit(EX_NOPERM);
1596
1568
      }
1663
1635
          _exit(EX_OSERR);
1664
1636
        }
1665
1637
      }
1666
 
      if(fexecve(hookdir_fd, (char *const [])
1667
 
                 { direntry->d_name, NULL }, environ) == -1){
 
1638
      int hook_fd = openat(hookdir_fd, direntry->d_name, O_RDONLY);
 
1639
      if(hook_fd == -1){
 
1640
        perror_plus("openat");
 
1641
        _exit(EXIT_FAILURE);
 
1642
      }
 
1643
      if((int)TEMP_FAILURE_RETRY(close(hookdir_fd)) == -1){
 
1644
        perror_plus("close");
 
1645
        _exit(EXIT_FAILURE);
 
1646
      }
 
1647
      if(fexecve(hook_fd, (char *const []){ direntry->d_name, NULL },
 
1648
                 environ) == -1){
1668
1649
        perror_plus("fexecve");
1669
1650
        _exit(EXIT_FAILURE);
1670
1651
      }
1672
1653
      int status;
1673
1654
      if(TEMP_FAILURE_RETRY(waitpid(hook_pid, &status, 0)) == -1){
1674
1655
        perror_plus("waitpid");
 
1656
        free(direntry);
1675
1657
        continue;
1676
1658
      }
1677
1659
      if(WIFEXITED(status)){
1679
1661
          fprintf_plus(stderr, "Warning: network hook \"%s\" exited"
1680
1662
                       " with status %d\n", direntry->d_name,
1681
1663
                       WEXITSTATUS(status));
 
1664
          free(direntry);
1682
1665
          continue;
1683
1666
        }
1684
1667
      } else if(WIFSIGNALED(status)){
1685
1668
        fprintf_plus(stderr, "Warning: network hook \"%s\" died by"
1686
1669
                     " signal %d\n", direntry->d_name,
1687
1670
                     WTERMSIG(status));
 
1671
        free(direntry);
1688
1672
        continue;
1689
1673
      } else {
1690
1674
        fprintf_plus(stderr, "Warning: network hook \"%s\""
1691
1675
                     " crashed\n", direntry->d_name);
 
1676
        free(direntry);
1692
1677
        continue;
1693
1678
      }
1694
1679
    }
1696
1681
      fprintf_plus(stderr, "Network hook \"%s\" ran successfully\n",
1697
1682
                   direntry->d_name);
1698
1683
    }
 
1684
    free(direntry);
1699
1685
  }
 
1686
  free(direntries);
1700
1687
  if((int)TEMP_FAILURE_RETRY(close(hookdir_fd)) == -1){
1701
1688
    perror_plus("close");
1702
1689
  } else {
1759
1746
    /* Raise privileges */
1760
1747
    ret_errno = raise_privileges();
1761
1748
    if(ret_errno != 0){
 
1749
      errno = ret_errno;
1762
1750
      perror_plus("Failed to raise privileges");
1763
1751
    }
1764
1752
    
1868
1856
    /* Raise privileges */
1869
1857
    ret_errno = raise_privileges();
1870
1858
    if(ret_errno != 0){
 
1859
      errno = ret_errno;
1871
1860
      perror_plus("Failed to raise privileges");
1872
1861
    }
1873
1862
    
2280
2269
  
2281
2270
  /* If no interfaces were specified, make a list */
2282
2271
  if(mc.interfaces == NULL){
2283
 
    struct dirent **direntries;
 
2272
    struct dirent **direntries = NULL;
2284
2273
    /* Look for any good interfaces */
2285
2274
    ret = scandir(sys_class_net, &direntries, good_interface,
2286
2275
                  alphasort);
2292
2281
        if(ret_errno != 0){
2293
2282
          errno = ret_errno;
2294
2283
          perror_plus("argz_add");
 
2284
          free(direntries[i]);
2295
2285
          continue;
2296
2286
        }
2297
2287
        if(debug){
2298
2288
          fprintf_plus(stderr, "Will use interface \"%s\"\n",
2299
2289
                       direntries[i]->d_name);
2300
2290
        }
 
2291
        free(direntries[i]);
2301
2292
      }
2302
2293
      free(direntries);
2303
2294
    } else {
2304
 
      free(direntries);
 
2295
      if(ret == 0){
 
2296
        free(direntries);
 
2297
      }
2305
2298
      fprintf_plus(stderr, "Could not find a network interface\n");
2306
2299
      exitcode = EXIT_FAILURE;
2307
2300
      goto end;
2571
2564
    mc.current_server->prev->next = NULL;
2572
2565
    while(mc.current_server != NULL){
2573
2566
      server *next = mc.current_server->next;
 
2567
#ifdef __GNUC__
 
2568
#pragma GCC diagnostic push
 
2569
#pragma GCC diagnostic ignored "-Wcast-qual"
 
2570
#endif
 
2571
      free((char *)(mc.current_server->ip));
 
2572
#ifdef __GNUC__
 
2573
#pragma GCC diagnostic pop
 
2574
#endif
2574
2575
      free(mc.current_server);
2575
2576
      mc.current_server = next;
2576
2577
    }
2580
2581
  {
2581
2582
    ret_errno = raise_privileges();
2582
2583
    if(ret_errno != 0){
 
2584
      errno = ret_errno;
2583
2585
      perror_plus("Failed to raise privileges");
2584
2586
    } else {
2585
2587
      
2608
2610
    
2609
2611
    ret_errno = lower_privileges_permanently();
2610
2612
    if(ret_errno != 0){
 
2613
      errno = ret_errno;
2611
2614
      perror_plus("Failed to lower privileges permanently");
2612
2615
    }
2613
2616
  }
2618
2621
  /* Removes the GPGME temp directory and all files inside */
2619
2622
  if(tempdir != NULL){
2620
2623
    struct dirent **direntries = NULL;
2621
 
    int tempdir_fd = (int)TEMP_FAILURE_RETRY(open(tempdir, O_RDONLY));
 
2624
    int tempdir_fd = (int)TEMP_FAILURE_RETRY(open(tempdir, O_RDONLY |
 
2625
                                                  O_NOFOLLOW));
2622
2626
    if(tempdir_fd == -1){
2623
2627
      perror_plus("open");
2624
2628
    } else {
2625
 
      int numentries = scandir(tempdir, &direntries, notdotentries,
2626
 
                               alphasort);
2627
 
      if(numentries > 0){
 
2629
#ifdef __GLIBC__
 
2630
#if __GLIBC_PREREQ(2, 15)
 
2631
      int numentries = scandirat(tempdir_fd, ".", &direntries,
 
2632
                                 notdotentries, alphasort);
 
2633
#else  /* not __GLIBC_PREREQ(2, 15) */
 
2634
      int numentries = scandir(tempdir, &direntries, notdotentries,
 
2635
                               alphasort);
 
2636
#endif  /* not __GLIBC_PREREQ(2, 15) */
 
2637
#else   /* not __GLIBC__ */
 
2638
      int numentries = scandir(tempdir, &direntries, notdotentries,
 
2639
                               alphasort);
 
2640
#endif  /* not __GLIBC__ */
 
2641
      if(numentries >= 0){
2628
2642
        for(int i = 0; i < numentries; i++){
2629
2643
          ret = unlinkat(tempdir_fd, direntries[i]->d_name, 0);
2630
2644
          if(ret == -1){
2632
2646
                         " \"%s\", 0): %s\n", tempdir,
2633
2647
                         direntries[i]->d_name, strerror(errno));
2634
2648
          }
 
2649
          free(direntries[i]);
2635
2650
        }
2636
2651
        
2637
2652
        /* need to clean even if 0 because man page doesn't specify */