/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-07-13 02:24:39 UTC
  • mfrom: (24.1.174 mandos)
  • Revision ID: teddy@fukt.bsnet.se-20110713022439-wbv6kghshdsc2x24
Merge from Björn.

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@recompile.se>.
 
29
 * Contact the authors at <mandos@fukt.bsnet.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@recompile.se>";
 
130
const char *argp_program_bug_address = "<mandos@fukt.bsnet.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 */
191
190
int add_server(const char *ip, uint16_t port,
192
191
                 AvahiIfIndex if_index,
193
192
                 int af){
205
204
    perror_plus("strdup");
206
205
    return -1;
207
206
  }
208
 
  /* Special case of first server */
 
207
  /* unique case of first server */
209
208
  if (mc.current_server == NULL){
210
209
    new_server->next = new_server;
211
210
    new_server->prev = new_server;
212
211
    mc.current_server = new_server;
213
 
  /* Place the new server last in the list */
 
212
  /* Placing the new server last in the list */
214
213
  } else {
215
214
    new_server->next = mc.current_server;
216
215
    new_server->prev = mc.current_server->prev;
283
282
    return false;
284
283
  }
285
284
  
286
 
  /* Set GPGME home directory for the OpenPGP engine only */
 
285
    /* Set GPGME home directory for the OpenPGP engine only */
287
286
  rc = gpgme_get_engine_info(&engine_info);
288
287
  if(rc != GPG_ERR_NO_ERROR){
289
288
    fprintf(stderr, "bad gpgme_get_engine_info: %s: %s\n",
1206
1205
  struct timespec now;
1207
1206
  struct timespec waited_time;
1208
1207
  intmax_t block_time;
1209
 
  
 
1208
 
1210
1209
  while(true){
1211
1210
    if(mc.current_server == NULL){
1212
1211
      if (debug){
1237
1236
      block_time = ((retry_interval
1238
1237
                     - ((intmax_t)waited_time.tv_sec * 1000))
1239
1238
                    - ((intmax_t)waited_time.tv_nsec / 1000000));
1240
 
      
 
1239
 
1241
1240
      if (debug){
1242
 
        fprintf(stderr, "Blocking for %" PRIdMAX " ms\n", block_time);
 
1241
        fprintf(stderr, "Blocking for %ld ms\n", block_time);
1243
1242
      }
1244
 
      
 
1243
 
1245
1244
      if(block_time <= 0){
1246
1245
        ret = start_mandos_communication(mc.current_server->ip,
1247
1246
                                         mc.current_server->port,
1412
1411
        errno = 0;
1413
1412
        retry_interval = strtod(arg, &tmp);
1414
1413
        if(errno != 0 or tmp == arg or *tmp != '\0'
1415
 
           or (retry_interval * 1000) > INT_MAX
1416
 
           or retry_interval < 0){
 
1414
           or (retry_interval * 1000) > INT_MAX){
1417
1415
          argp_error(state, "Bad retry interval");
1418
1416
        }
1419
1417
        break;
1457
1455
      goto end;
1458
1456
    }
1459
1457
  }
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
 
  }
1520
1458
  
1521
1459
  if(not debug){
1522
1460
    avahi_set_log_function(empty_log);
1835
1773
    
1836
1774
    port = (uint16_t)tmpmax;
1837
1775
    *address = '\0';
 
1776
    address = connect_to;
1838
1777
    /* Colon in address indicates IPv6 */
1839
1778
    int af;
1840
 
    if(strchr(connect_to, ':') != NULL){
 
1779
    if(strchr(address, ':') != NULL){
1841
1780
      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
 
        }
1848
1781
    } else {
1849
1782
      af = AF_INET;
1850
1783
    }
1851
 
    address = connect_to;
1852
1784
    
1853
1785
    if(quit_now){
1854
1786
      goto end;
1855
1787
    }
1856
 
    
 
1788
 
1857
1789
    while(not quit_now){
1858
1790
      ret = start_mandos_communication(address, port, if_index, af);
1859
1791
      if(quit_now or ret == 0){
1860
1792
        break;
1861
1793
      }
1862
 
      if(debug){
1863
 
        fprintf(stderr, "Retrying in %d seconds\n",
1864
 
                (int)retry_interval);
1865
 
      }
1866
 
      sleep((int)retry_interval);
1867
 
    }
1868
 
    
 
1794
      sleep((int)retry_interval or 1);
 
1795
    };
 
1796
 
1869
1797
    if (not quit_now){
1870
1798
      exitcode = EXIT_SUCCESS;
1871
1799
    }
2008
1936
  if(tempdir_created){
2009
1937
    struct dirent **direntries = NULL;
2010
1938
    struct dirent *direntry = NULL;
2011
 
    int numentries = scandir(tempdir, &direntries, notdotentries,
2012
 
                             alphasort);
2013
 
    if (numentries > 0){
2014
 
      for(int i = 0; i < numentries; i++){
 
1939
    ret = scandir(tempdir, &direntries, notdotentries, alphasort);
 
1940
    if (ret > 0){
 
1941
      for(int i = 0; i < ret; i++){
2015
1942
        direntry = direntries[i];
2016
1943
        char *fullname = NULL;
2017
1944
        ret = asprintf(&fullname, "%s/%s", tempdir,
2029
1956
      }
2030
1957
    }
2031
1958
 
2032
 
    /* need to clean even if 0 because man page doesn't specify */
 
1959
    /* need to be cleaned even if ret == 0 because man page doesn't
 
1960
       specify */
2033
1961
    free(direntries);
2034
 
    if (numentries == -1){
 
1962
    if (ret == -1){
2035
1963
      perror_plus("scandir");
2036
1964
    }
2037
1965
    ret = rmdir(tempdir);