/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

merge

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