/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

* plugins.d/mandos-client.c (runnable_hook): Bug fix: stat using the
                                             full path.
  (mail): Take new "--network-hook-dir" option.

Show diffs side-by-side

added added

removed removed

Lines of Context:
110
110
                                   init_gnutls_session(),
111
111
                                   GNUTLS_* */
112
112
#include <gnutls/openpgp.h>
113
 
                         /* gnutls_certificate_set_openpgp_key_file(),
114
 
                            GNUTLS_OPENPGP_FMT_BASE64 */
 
113
                          /* gnutls_certificate_set_openpgp_key_file(),
 
114
                                   GNUTLS_OPENPGP_FMT_BASE64 */
115
115
 
116
116
/* GPGME */
117
117
#include <gpgme.h>              /* All GPGME types, constants and
174
174
  perror(print_text);
175
175
}
176
176
 
177
 
int fprintf_plus(FILE *stream, const char *format, ...){
178
 
  va_list ap;
179
 
  va_start (ap, format);
180
 
  
181
 
  TEMP_FAILURE_RETRY(fprintf(stream, "Mandos plugin %s: ", program_invocation_short_name));
182
 
  return TEMP_FAILURE_RETRY(vfprintf(stream, format, ap));
183
 
}
184
 
 
185
177
/*
186
178
 * Make additional room in "buffer" for at least BUFFER_SIZE more
187
179
 * bytes. "buffer_capacity" is how much is currently allocated,
188
180
 * "buffer_length" is how much is already used.
189
181
 */
190
182
size_t incbuffer(char **buffer, size_t buffer_length,
191
 
                 size_t buffer_capacity){
 
183
                  size_t buffer_capacity){
192
184
  if(buffer_length + BUFFER_SIZE > buffer_capacity){
193
185
    *buffer = realloc(*buffer, buffer_capacity + BUFFER_SIZE);
194
186
    if(buffer == NULL){
200
192
}
201
193
 
202
194
/* Add server to set of servers to retry periodically */
203
 
int add_server(const char *ip, uint16_t port, AvahiIfIndex if_index,
204
 
               int af){
 
195
int add_server(const char *ip, uint16_t port,
 
196
                 AvahiIfIndex if_index,
 
197
                 int af){
205
198
  int ret;
206
199
  server *new_server = malloc(sizeof(server));
207
200
  if(new_server == NULL){
209
202
    return -1;
210
203
  }
211
204
  *new_server = (server){ .ip = strdup(ip),
212
 
                          .port = port,
213
 
                          .if_index = if_index,
214
 
                          .af = af };
 
205
                         .port = port,
 
206
                         .if_index = if_index,
 
207
                         .af = af };
215
208
  if(new_server->ip == NULL){
216
209
    perror_plus("strdup");
217
210
    return -1;
239
232
/* 
240
233
 * Initialize GPGME.
241
234
 */
242
 
static bool init_gpgme(const char *seckey, const char *pubkey,
243
 
                       const char *tempdir){
 
235
static bool init_gpgme(const char *seckey,
 
236
                       const char *pubkey, const char *tempdir){
244
237
  gpgme_error_t rc;
245
238
  gpgme_engine_info_t engine_info;
246
239
  
433
426
  *plaintext = NULL;
434
427
  while(true){
435
428
    plaintext_capacity = incbuffer(plaintext,
436
 
                                   (size_t)plaintext_length,
437
 
                                   plaintext_capacity);
 
429
                                      (size_t)plaintext_length,
 
430
                                      plaintext_capacity);
438
431
    if(plaintext_capacity == 0){
439
 
      perror_plus("incbuffer");
440
 
      plaintext_length = -1;
441
 
      goto decrypt_end;
 
432
        perror_plus("incbuffer");
 
433
        plaintext_length = -1;
 
434
        goto decrypt_end;
442
435
    }
443
436
    
444
437
    ret = gpgme_data_read(dh_plain, *plaintext + plaintext_length,
724
717
    
725
718
    if(IN6_IS_ADDR_LINKLOCAL /* Spurious warnings from */
726
719
       (&to.in6.sin6_addr)){ /* -Wstrict-aliasing=2 or lower and
727
 
                                -Wunreachable-code*/
 
720
                              -Wunreachable-code*/
728
721
      if(if_index == AVAHI_IF_UNSPEC){
729
722
        fprintf(stderr, "Mandos plugin mandos-client: "
730
723
                "An IPv6 link-local address is incomplete"
809
802
  while(true){
810
803
    size_t out_size = strlen(out);
811
804
    ret = (int)TEMP_FAILURE_RETRY(write(tcp_sd, out + written,
812
 
                                        out_size - written));
 
805
                                   out_size - written));
813
806
    if(ret == -1){
814
807
      int e = errno;
815
808
      perror_plus("write");
885
878
    }
886
879
    
887
880
    buffer_capacity = incbuffer(&buffer, buffer_length,
888
 
                                buffer_capacity);
 
881
                                   buffer_capacity);
889
882
    if(buffer_capacity == 0){
890
883
      int e = errno;
891
884
      perror_plus("incbuffer");
958
951
  
959
952
  if(buffer_length > 0){
960
953
    ssize_t decrypted_buffer_size;
961
 
    decrypted_buffer_size = pgp_packet_decrypt(buffer, buffer_length,
 
954
    decrypted_buffer_size = pgp_packet_decrypt(buffer,
 
955
                                               buffer_length,
962
956
                                               &decrypted_buffer);
963
957
    if(decrypted_buffer_size >= 0){
964
958
      
1288
1282
/* Is this directory entry a runnable program? */
1289
1283
int runnable_hook(const struct dirent *direntry){
1290
1284
  int ret;
1291
 
  size_t sret;
1292
1285
  struct stat st;
1293
1286
  
1294
1287
  if((direntry->d_name)[0] == '\0'){
1296
1289
    return 0;
1297
1290
  }
1298
1291
  
1299
 
  sret = strspn(direntry->d_name, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1300
 
                "abcdefghijklmnopqrstuvwxyz"
1301
 
                "0123456789"
1302
 
                "_-");
1303
 
  if((direntry->d_name)[sret] != '\0'){
1304
 
    /* Contains non-allowed characters */
1305
 
    if(debug){
1306
 
      fprintf(stderr, "Mandos plugin mandos-client: "
1307
 
              "Ignoring hook \"%s\" with bad name\n",
1308
 
              direntry->d_name);
1309
 
    }
1310
 
    return 0;
1311
 
  }
 
1292
  /* Save pointer to last character */
 
1293
  char *end = strchr(direntry->d_name, '\0')-1;
 
1294
  
 
1295
  if(*end == '~'){
 
1296
    /* Backup name~ */
 
1297
    return 0;
 
1298
  }
 
1299
  
 
1300
  if(((direntry->d_name)[0] == '#')
 
1301
     and (*end == '#')){
 
1302
    /* Temporary #name# */
 
1303
    return 0;
 
1304
  }
 
1305
  
 
1306
  /* XXX more rules here */
1312
1307
  
1313
1308
  char *fullname = NULL;
1314
 
  ret = asprintf(&fullname, "%s/%s", hookdir, direntry->d_name);
 
1309
  ret = asprintf(&fullname, "%s/%s", hookdir,
 
1310
                 direntry->d_name);
1315
1311
  if(ret < 0){
1316
1312
    perror_plus("asprintf");
1317
1313
    return 0;
1320
1316
  ret = stat(fullname, &st);
1321
1317
  if(ret == -1){
1322
1318
    if(debug){
1323
 
      perror_plus("Could not stat hook");
 
1319
      perror_plus("Could not stat plugin");
1324
1320
    }
1325
1321
    return 0;
1326
1322
  }
1327
1323
  if(not (S_ISREG(st.st_mode))){
1328
1324
    /* Not a regular file */
1329
 
    if(debug){
1330
 
      fprintf(stderr, "Mandos plugin mandos-client: "
1331
 
              "Ignoring hook \"%s\" - not a file\n",
1332
 
              direntry->d_name);
1333
 
    }
1334
1325
    return 0;
1335
1326
  }
1336
1327
  if(not (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))){
1337
1328
    /* Not executable */
1338
 
    if(debug){
1339
 
      fprintf(stderr, "Mandos plugin mandos-client: "
1340
 
              "Ignoring hook \"%s\" - not executable\n",
1341
 
              direntry->d_name);
1342
 
    }
1343
1329
    return 0;
1344
1330
  }
1345
1331
  return 1;
1696
1682
          dup2(devnull, STDIN_FILENO);
1697
1683
          close(devnull);
1698
1684
          dup2(STDERR_FILENO, STDOUT_FILENO);
1699
 
          ret = setenv("MANDOSNETHOOKDIR", hookdir, 1);
1700
 
          if(ret == -1){
1701
 
            perror_plus("setenv");
1702
 
            exit(1);
1703
 
          }
1704
1685
          ret = setenv("DEVICE", interface, 1);
1705
1686
          if(ret == -1){
1706
1687
            perror_plus("setenv");