/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: 2011-11-26 22:22:20 UTC
  • mto: (237.12.8 mandos-persistent)
  • mto: This revision was merged to the branch mainline in revision 290.
  • 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;
1468
1470
      perror_plus("seteuid");
1469
1471
    }
1470
1472
    
1471
 
    int seckey_fd = open(PATHDIR "/" SECKEY, O_RDONLY);
1472
 
    if(seckey_fd == -1){
1473
 
      perror_plus("open");
1474
 
    } else {
1475
 
      ret = (int)TEMP_FAILURE_RETRY(fstat(seckey_fd, &st));
1476
 
      if(ret == -1){
1477
 
        perror_plus("fstat");
 
1473
    if(strcmp(seckey, PATHDIR "/" SECKEY) == 0){
 
1474
      int seckey_fd = open(seckey, O_RDONLY);
 
1475
      if(seckey_fd == -1){
 
1476
        perror_plus("open");
1478
1477
      } else {
1479
 
        if(S_ISREG(st.st_mode) and st.st_uid == 0 and st.st_gid == 0){
1480
 
          ret = fchown(seckey_fd, uid, gid);
1481
 
          if(ret == -1){
1482
 
            perror_plus("fchown");
 
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
            }
1483
1487
          }
1484
1488
        }
 
1489
        TEMP_FAILURE_RETRY(close(seckey_fd));
1485
1490
      }
1486
 
      TEMP_FAILURE_RETRY(close(seckey_fd));
1487
1491
    }
1488
1492
    
1489
 
    int pubkey_fd = open(PATHDIR "/" PUBKEY, O_RDONLY);
1490
 
    if(pubkey_fd == -1){
1491
 
      perror_plus("open");
1492
 
    } else {
1493
 
      ret = (int)TEMP_FAILURE_RETRY(fstat(pubkey_fd, &st));
1494
 
      if(ret == -1){
1495
 
        perror_plus("fstat");
 
1493
    if(strcmp(pubkey, PATHDIR "/" PUBKEY) == 0){
 
1494
      int pubkey_fd = open(pubkey, O_RDONLY);
 
1495
      if(pubkey_fd == -1){
 
1496
        perror_plus("open");
1496
1497
      } else {
1497
 
        if(S_ISREG(st.st_mode) and st.st_uid == 0 and st.st_gid == 0){
1498
 
          ret = fchown(pubkey_fd, uid, gid);
1499
 
          if(ret == -1){
1500
 
            perror_plus("fchown");
 
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
            }
1501
1507
          }
1502
1508
        }
 
1509
        TEMP_FAILURE_RETRY(close(pubkey_fd));
1503
1510
      }
1504
 
      TEMP_FAILURE_RETRY(close(pubkey_fd));
1505
1511
    }
1506
1512
    
1507
1513
    /* Lower privileges */
1829
1835
    
1830
1836
    port = (uint16_t)tmpmax;
1831
1837
    *address = '\0';
1832
 
    address = connect_to;
1833
1838
    /* Colon in address indicates IPv6 */
1834
1839
    int af;
1835
 
    if(strchr(address, ':') != NULL){
 
1840
    if(strchr(connect_to, ':') != NULL){
1836
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
        }
1837
1848
    } else {
1838
1849
      af = AF_INET;
1839
1850
    }
 
1851
    address = connect_to;
1840
1852
    
1841
1853
    if(quit_now){
1842
1854
      goto end;
1843
1855
    }
1844
 
 
 
1856
    
1845
1857
    while(not quit_now){
1846
1858
      ret = start_mandos_communication(address, port, if_index, af);
1847
1859
      if(quit_now or ret == 0){
1848
1860
        break;
1849
1861
      }
1850
 
      sleep((int)retry_interval or 1);
1851
 
    };
1852
 
 
 
1862
      if(debug){
 
1863
        fprintf(stderr, "Retrying in %d seconds\n",
 
1864
                (int)retry_interval);
 
1865
      }
 
1866
      sleep((int)retry_interval);
 
1867
    }
 
1868
    
1853
1869
    if (not quit_now){
1854
1870
      exitcode = EXIT_SUCCESS;
1855
1871
    }
1992
2008
  if(tempdir_created){
1993
2009
    struct dirent **direntries = NULL;
1994
2010
    struct dirent *direntry = NULL;
1995
 
    ret = scandir(tempdir, &direntries, notdotentries, alphasort);
1996
 
    if (ret > 0){
1997
 
      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++){
1998
2015
        direntry = direntries[i];
1999
2016
        char *fullname = NULL;
2000
2017
        ret = asprintf(&fullname, "%s/%s", tempdir,
2012
2029
      }
2013
2030
    }
2014
2031
 
2015
 
    /* need to be cleaned even if ret == 0 because man page doesn't
2016
 
       specify */
 
2032
    /* need to clean even if 0 because man page doesn't specify */
2017
2033
    free(direntries);
2018
 
    if (ret == -1){
 
2034
    if (numentries == -1){
2019
2035
      perror_plus("scandir");
2020
2036
    }
2021
2037
    ret = rmdir(tempdir);