/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/mandosclient.c

  • Committer: Teddy Hogeborn
  • Date: 2008-08-03 21:45:14 UTC
  • mfrom: (24.1.13 mandos)
  • Revision ID: teddy@fukt.bsnet.se-20080803214514-plvvkrpoitwsrxeg
Merge.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#define _LARGEFILE_SOURCE
33
33
#define _FILE_OFFSET_BITS 64
34
34
 
 
35
#define _GNU_SOURCE             /* TEMP_FAILURE_RETRY() */
 
36
 
35
37
#include <stdio.h>
36
38
#include <assert.h>
37
39
#include <stdlib.h>
79
81
 
80
82
bool debug = false;
81
83
 
 
84
const char mandos_protocol_version[] = "1";
 
85
 
82
86
/* Used for passing in values through all the callback functions */
83
87
typedef struct {
84
88
  AvahiSimplePoll *simple_poll;
85
89
  AvahiServer *server;
86
90
  gnutls_certificate_credentials_t cred;
87
91
  unsigned int dh_bits;
 
92
  gnutls_dh_params_t dh_params;
88
93
  const char *priority;
89
94
} mandos_context;
90
95
 
 
96
size_t adjustbuffer(char **buffer, size_t buffer_length,
 
97
                  size_t buffer_capacity){
 
98
  if (buffer_length + BUFFER_SIZE > buffer_capacity){
 
99
    *buffer = realloc(*buffer, buffer_capacity + BUFFER_SIZE);
 
100
    if (buffer == NULL){
 
101
      return 0;
 
102
    }
 
103
    buffer_capacity += BUFFER_SIZE;
 
104
  }
 
105
  return buffer_capacity;
 
106
}
 
107
 
91
108
/* 
92
109
 * Decrypt OpenPGP data using keyrings in HOMEDIR.
93
110
 * Returns -1 on error
216
233
  
217
234
  *plaintext = NULL;
218
235
  while(true){
219
 
    if (plaintext_length + BUFFER_SIZE
220
 
        > (ssize_t) plaintext_capacity){
221
 
      *plaintext = realloc(*plaintext, plaintext_capacity
222
 
                            + BUFFER_SIZE);
223
 
      if (*plaintext == NULL){
224
 
        perror("realloc");
 
236
    plaintext_capacity = adjustbuffer(plaintext, (size_t)plaintext_length,
 
237
                                      plaintext_capacity);
 
238
    if (plaintext_capacity == 0){
 
239
        perror("adjustbuffer");
225
240
        plaintext_length = -1;
226
241
        goto decrypt_end;
227
 
      }
228
 
      plaintext_capacity += BUFFER_SIZE;
229
242
    }
230
243
    
231
244
    ret = gpgme_data_read(dh_plain, *plaintext + plaintext_length,
274
287
  fprintf(stderr, "GnuTLS: %s", string);
275
288
}
276
289
 
277
 
static int initgnutls(mandos_context *mc, gnutls_session_t *session,
278
 
                      gnutls_dh_params_t *dh_params){
 
290
static int init_gnutls_global(mandos_context *mc){
279
291
  int ret;
280
292
  
281
293
  if(debug){
323
335
  }
324
336
  
325
337
  /* GnuTLS server initialization */
326
 
  ret = gnutls_dh_params_init(dh_params);
 
338
  ret = gnutls_dh_params_init(&mc->dh_params);
327
339
  if (ret != GNUTLS_E_SUCCESS) {
328
340
    fprintf (stderr, "Error in GnuTLS DH parameter initialization:"
329
341
             " %s\n", safer_gnutls_strerror(ret));
330
342
    return -1;
331
343
  }
332
 
  ret = gnutls_dh_params_generate2(*dh_params, mc->dh_bits);
 
344
  ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
333
345
  if (ret != GNUTLS_E_SUCCESS) {
334
346
    fprintf (stderr, "Error in GnuTLS prime generation: %s\n",
335
347
             safer_gnutls_strerror(ret));
336
348
    return -1;
337
349
  }
338
350
  
339
 
  gnutls_certificate_set_dh_params(mc->cred, *dh_params);
340
 
  
 
351
  gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
 
352
 
 
353
  return 0;
 
354
}
 
355
 
 
356
static int init_gnutls_session(mandos_context *mc, gnutls_session_t *session){
 
357
  int ret;
341
358
  /* GnuTLS session creation */
342
359
  ret = gnutls_init(session, GNUTLS_SERVER);
343
360
  if (ret != GNUTLS_E_SUCCESS){
388
405
  size_t buffer_length = 0;
389
406
  size_t buffer_capacity = 0;
390
407
  ssize_t decrypted_buffer_size;
391
 
  size_t written = 0;
 
408
  size_t written;
392
409
  int retval = 0;
393
410
  char interface[IF_NAMESIZE];
394
411
  gnutls_session_t session;
395
412
  gnutls_dh_params_t dh_params;
396
413
  
397
 
  ret = initgnutls (mc, &session, &dh_params);
 
414
  ret = init_gnutls_session (mc, &session);
398
415
  if (ret != 0){
399
416
    return -1;
400
417
  }
453
470
    perror("connect");
454
471
    return -1;
455
472
  }
456
 
  
 
473
 
 
474
  const char *out = mandos_protocol_version;
 
475
  written = 0;
 
476
  while (true){
 
477
    size_t out_size = strlen(out);
 
478
    ret = TEMP_FAILURE_RETRY(write(tcp_sd, out + written,
 
479
                                   out_size - written));
 
480
    if (ret == -1){
 
481
      perror("write");
 
482
      retval = -1;
 
483
      goto mandos_end;
 
484
    }
 
485
    written += (size_t)ret;
 
486
    if(written < out_size){
 
487
      continue;
 
488
    } else {
 
489
      if (out == mandos_protocol_version){
 
490
        written = 0;
 
491
        out = "\r\n";
 
492
      } else {
 
493
        break;
 
494
      }
 
495
    }
 
496
  }
 
497
 
457
498
  if(debug){
458
499
    fprintf(stderr, "Establishing TLS session with %s\n", ip);
459
500
  }
479
520
  }
480
521
 
481
522
  while(true){
482
 
    if (buffer_length + BUFFER_SIZE > buffer_capacity){
483
 
      buffer = realloc(buffer, buffer_capacity + BUFFER_SIZE);
484
 
      if (buffer == NULL){
485
 
        perror("realloc");
486
 
        retval = -1;
487
 
        goto mandos_end;
488
 
      }
489
 
      buffer_capacity += BUFFER_SIZE;
 
523
    buffer_capacity = adjustbuffer(&buffer, buffer_length, buffer_capacity);
 
524
    if (buffer_capacity == 0){
 
525
      perror("adjustbuffer");
 
526
      retval = -1;
 
527
      goto mandos_end;
490
528
    }
491
529
    
492
530
    ret = gnutls_record_recv(session, buffer+buffer_length,
532
570
                                               &decrypted_buffer,
533
571
                                               keydir);
534
572
    if (decrypted_buffer_size >= 0){
 
573
      written = 0;
535
574
      while(written < (size_t) decrypted_buffer_size){
536
575
        ret = (int)fwrite (decrypted_buffer + written, 1,
537
576
                           (size_t)decrypted_buffer_size - written,
688
727
    const char *interface = "eth0";
689
728
    struct ifreq network;
690
729
    int sd;
 
730
    uid_t uid;
 
731
    gid_t gid;
691
732
    char *connect_to = NULL;
692
733
    AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
693
734
    mandos_context mc = { .simple_poll = NULL, .server = NULL,
768
809
      perror("combinepath");
769
810
      goto end;
770
811
    }
 
812
 
 
813
    ret = init_gnutls_global(&mc);
 
814
    if (ret == -1){
 
815
      fprintf(stderr, "init_gnutls_global\n");
 
816
      goto end;
 
817
    }
 
818
 
 
819
    uid = getuid();
 
820
    gid = getgid();
 
821
 
 
822
    ret = setuid(uid);
 
823
    if (ret == -1){
 
824
      perror("setuid");
 
825
    }
 
826
    
 
827
    setgid(gid);
 
828
    if (ret == -1){
 
829
      perror("setgid");
 
830
    }
771
831
    
772
832
    if_index = (AvahiIfIndex) if_nametoindex(interface);
773
833
    if(if_index == 0){
781
841
      char *address = strrchr(connect_to, ':');
782
842
      if(address == NULL){
783
843
        fprintf(stderr, "No colon in address\n");
784
 
        exit(EXIT_FAILURE);
 
844
        exitcode = EXIT_FAILURE;
 
845
        goto end;
785
846
      }
786
847
      errno = 0;
787
848
      uint16_t port = (uint16_t) strtol(address+1, NULL, 10);
788
849
      if(errno){
789
850
        perror("Bad port number");
790
 
        exit(EXIT_FAILURE);
 
851
        exitcode = EXIT_FAILURE;
 
852
        goto end;
791
853
      }
792
854
      *address = '\0';
793
855
      address = connect_to;
794
856
      ret = start_mandos_communication(address, port, if_index, &mc);
795
857
      if(ret < 0){
796
 
        exit(EXIT_FAILURE);
 
858
        exitcode = EXIT_FAILURE;
797
859
      } else {
798
 
        exit(EXIT_SUCCESS);
 
860
        exitcode = EXIT_SUCCESS;
799
861
      }
 
862
      goto end;
800
863
    }
801
864
    
802
865
    /* If the interface is down, bring it up */