/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: 2011-11-26 22:22:20 UTC
  • mto: (518.1.8 mandos-persistent)
  • mto: This revision was merged to the branch mainline in revision 524.
  • Revision ID: teddy@recompile.se-20111126222220-1ubwjpb5ugqnrhec
Directory with persistent state can now be changed with the "statedir"
option.  The state directory /var/lib/mandos now gets created on
installation.  Added documentation about "restore" and "statedir"
options.

* Makefile (USER, GROUP, STATEDIR): New.
  (maintainer-clean): Also remove "statedir".
  (run-server): Replaced "--no-restore" with "--statedir=statedir".
  (statedir): New.
  (install-server): Make $(STATEDIR) directory.
* debian/mandos.dirs (var/lib/mandos): Added.
* debian/mandos.postinst: Fix ownership of /var/lib/mandos.
* mandos: New --statedir option.
  (stored_state_path): Not global anymore.
  (stored_state_file): New global.
* mandos.conf: Fix whitespace.
  (restore, statedir): Added.
* mandos.conf.xml (OPTIONS, EXAMPLE): Added "restore" and "statedir".
  mandos.xml (SYNOPSIS, OPTIONS): Added "--statedir".
  (FILES): Added "/var/lib/mandos".

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 * along with this program.  If not, see
27
27
 * <http://www.gnu.org/licenses/>.
28
28
 * 
29
 
 * Contact the authors at <mandos@fukt.bsnet.se>.
 
29
 * Contact the authors at <mandos@recompile.se>.
30
30
 */
31
31
 
32
32
/* Needed by GPGME, specifically gpgme_data_seek() */
127
127
bool debug = false;
128
128
static const char mandos_protocol_version[] = "1";
129
129
const char *argp_program_version = "mandos-client " VERSION;
130
 
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
 
130
const char *argp_program_bug_address = "<mandos@recompile.se>";
131
131
static const char sys_class_net[] = "/sys/class/net";
132
132
char *connect_to = NULL;
133
133
 
187
187
  return buffer_capacity;
188
188
}
189
189
 
 
190
/* Add server to set of servers to retry periodically */
190
191
int add_server(const char *ip, uint16_t port,
191
192
                 AvahiIfIndex if_index,
192
193
                 int af){
204
205
    perror_plus("strdup");
205
206
    return -1;
206
207
  }
207
 
  /* unique case of first server */
 
208
  /* Special case of first server */
208
209
  if (mc.current_server == NULL){
209
210
    new_server->next = new_server;
210
211
    new_server->prev = new_server;
211
212
    mc.current_server = new_server;
212
 
  /* Placing the new server last in the list */
 
213
  /* Place the new server last in the list */
213
214
  } else {
214
215
    new_server->next = mc.current_server;
215
216
    new_server->prev = mc.current_server->prev;
282
283
    return false;
283
284
  }
284
285
  
285
 
    /* Set GPGME home directory for the OpenPGP engine only */
 
286
  /* Set GPGME home directory for the OpenPGP engine only */
286
287
  rc = gpgme_get_engine_info(&engine_info);
287
288
  if(rc != GPG_ERR_NO_ERROR){
288
289
    fprintf(stderr, "bad gpgme_get_engine_info: %s: %s\n",
1205
1206
  struct timespec now;
1206
1207
  struct timespec waited_time;
1207
1208
  intmax_t block_time;
1208
 
 
 
1209
  
1209
1210
  while(true){
1210
1211
    if(mc.current_server == NULL){
1211
1212
      if (debug){
1236
1237
      block_time = ((retry_interval
1237
1238
                     - ((intmax_t)waited_time.tv_sec * 1000))
1238
1239
                    - ((intmax_t)waited_time.tv_nsec / 1000000));
1239
 
 
 
1240
      
1240
1241
      if (debug){
1241
 
        fprintf(stderr, "Blocking for %ld ms\n", block_time);
 
1242
        fprintf(stderr, "Blocking for %" PRIdMAX " ms\n", block_time);
1242
1243
      }
1243
 
 
 
1244
      
1244
1245
      if(block_time <= 0){
1245
1246
        ret = start_mandos_communication(mc.current_server->ip,
1246
1247
                                         mc.current_server->port,
1411
1412
        errno = 0;
1412
1413
        retry_interval = strtod(arg, &tmp);
1413
1414
        if(errno != 0 or tmp == arg or *tmp != '\0'
1414
 
           or (retry_interval * 1000) > INT_MAX){
 
1415
           or (retry_interval * 1000) > INT_MAX
 
1416
           or retry_interval < 0){
1415
1417
          argp_error(state, "Bad retry interval");
1416
1418
        }
1417
1419
        break;
1455
1457
      goto end;
1456
1458
    }
1457
1459
  }
 
1460
    
 
1461
  {
 
1462
    /* Work around Debian bug #633582:
 
1463
       <http://bugs.debian.org/633582> */
 
1464
    struct stat st;
 
1465
    
 
1466
    /* Re-raise priviliges */
 
1467
    errno = 0;
 
1468
    ret = seteuid(0);
 
1469
    if(ret == -1){
 
1470
      perror_plus("seteuid");
 
1471
    }
 
1472
    
 
1473
    if(strcmp(seckey, PATHDIR "/" SECKEY) == 0){
 
1474
      int seckey_fd = open(seckey, O_RDONLY);
 
1475
      if(seckey_fd == -1){
 
1476
        perror_plus("open");
 
1477
      } else {
 
1478
        ret = (int)TEMP_FAILURE_RETRY(fstat(seckey_fd, &st));
 
1479
        if(ret == -1){
 
1480
          perror_plus("fstat");
 
1481
        } else {
 
1482
          if(S_ISREG(st.st_mode) and st.st_uid == 0 and st.st_gid == 0){
 
1483
            ret = fchown(seckey_fd, uid, gid);
 
1484
            if(ret == -1){
 
1485
              perror_plus("fchown");
 
1486
            }
 
1487
          }
 
1488
        }
 
1489
        TEMP_FAILURE_RETRY(close(seckey_fd));
 
1490
      }
 
1491
    }
 
1492
    
 
1493
    if(strcmp(pubkey, PATHDIR "/" PUBKEY) == 0){
 
1494
      int pubkey_fd = open(pubkey, O_RDONLY);
 
1495
      if(pubkey_fd == -1){
 
1496
        perror_plus("open");
 
1497
      } else {
 
1498
        ret = (int)TEMP_FAILURE_RETRY(fstat(pubkey_fd, &st));
 
1499
        if(ret == -1){
 
1500
          perror_plus("fstat");
 
1501
        } else {
 
1502
          if(S_ISREG(st.st_mode) and st.st_uid == 0 and st.st_gid == 0){
 
1503
            ret = fchown(pubkey_fd, uid, gid);
 
1504
            if(ret == -1){
 
1505
              perror_plus("fchown");
 
1506
            }
 
1507
          }
 
1508
        }
 
1509
        TEMP_FAILURE_RETRY(close(pubkey_fd));
 
1510
      }
 
1511
    }
 
1512
    
 
1513
    /* Lower privileges */
 
1514
    errno = 0;
 
1515
    ret = seteuid(uid);
 
1516
    if(ret == -1){
 
1517
      perror_plus("seteuid");
 
1518
    }
 
1519
  }
1458
1520
  
1459
1521
  if(not debug){
1460
1522
    avahi_set_log_function(empty_log);
1773
1835
    
1774
1836
    port = (uint16_t)tmpmax;
1775
1837
    *address = '\0';
1776
 
    address = connect_to;
1777
1838
    /* Colon in address indicates IPv6 */
1778
1839
    int af;
1779
 
    if(strchr(address, ':') != NULL){
 
1840
    if(strchr(connect_to, ':') != NULL){
1780
1841
      af = AF_INET6;
 
1842
      /* Accept [] around IPv6 address - see RFC 5952 */
 
1843
      if(connect_to[0] == '[' and address[-1] == ']')
 
1844
        {
 
1845
          connect_to++;
 
1846
          address[-1] = '\0';
 
1847
        }
1781
1848
    } else {
1782
1849
      af = AF_INET;
1783
1850
    }
 
1851
    address = connect_to;
1784
1852
    
1785
1853
    if(quit_now){
1786
1854
      goto end;
1787
1855
    }
1788
 
 
 
1856
    
1789
1857
    while(not quit_now){
1790
1858
      ret = start_mandos_communication(address, port, if_index, af);
1791
1859
      if(quit_now or ret == 0){
1792
1860
        break;
1793
1861
      }
1794
 
      sleep((int)retry_interval or 1);
1795
 
    };
1796
 
 
 
1862
      if(debug){
 
1863
        fprintf(stderr, "Retrying in %d seconds\n",
 
1864
                (int)retry_interval);
 
1865
      }
 
1866
      sleep((int)retry_interval);
 
1867
    }
 
1868
    
1797
1869
    if (not quit_now){
1798
1870
      exitcode = EXIT_SUCCESS;
1799
1871
    }
1936
2008
  if(tempdir_created){
1937
2009
    struct dirent **direntries = NULL;
1938
2010
    struct dirent *direntry = NULL;
1939
 
    ret = scandir(tempdir, &direntries, notdotentries, alphasort);
1940
 
    if (ret > 0){
1941
 
      for(int i = 0; i < ret; i++){
 
2011
    int numentries = scandir(tempdir, &direntries, notdotentries,
 
2012
                             alphasort);
 
2013
    if (numentries > 0){
 
2014
      for(int i = 0; i < numentries; i++){
1942
2015
        direntry = direntries[i];
1943
2016
        char *fullname = NULL;
1944
2017
        ret = asprintf(&fullname, "%s/%s", tempdir,
1956
2029
      }
1957
2030
    }
1958
2031
 
1959
 
    /* need to be cleaned even if ret == 0 because man page doesn't
1960
 
       specify */
 
2032
    /* need to clean even if 0 because man page doesn't specify */
1961
2033
    free(direntries);
1962
 
    if (ret == -1){
 
2034
    if (numentries == -1){
1963
2035
      perror_plus("scandir");
1964
2036
    }
1965
2037
    ret = rmdir(tempdir);