/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: 2015-07-05 21:38:01 UTC
  • mto: This revision was merged to the branch mainline in revision 759.
  • Revision ID: teddy@recompile.se-20150705213801-pi8vk0ovlumuj826
plugin-helpers/mandos-client-iprouteadddel.c: Fix #include lines.
(main): Fix minor typo in error message.

Show diffs side-by-side

added added

removed removed

Lines of Context:
493
493
  return plaintext_length;
494
494
}
495
495
 
496
 
__attribute__((warn_unused_result, const))
497
 
static const char *safe_string(const char *str){
498
 
  if(str == NULL)
499
 
    return "(unknown)";
500
 
  return str;
501
 
}
502
 
 
503
496
__attribute__((warn_unused_result))
504
497
static const char *safer_gnutls_strerror(int value){
505
498
  const char *ret = gnutls_strerror(value);
506
 
  return safe_string(ret);
 
499
  if(ret == NULL)
 
500
    ret = "(unknown)";
 
501
  return ret;
507
502
}
508
503
 
509
504
/* GnuTLS log function callback */
518
513
                              const char *seckeyfilename,
519
514
                              mandos_context *mc){
520
515
  int ret;
521
 
  unsigned int uret;
522
516
  
523
517
  if(debug){
524
518
    fprintf_plus(stderr, "Initializing GnuTLS\n");
575
569
                 safer_gnutls_strerror(ret));
576
570
    goto globalfail;
577
571
  }
578
 
  if(mc->dh_bits == 0){
579
 
    /* Find out the optimal number of DH bits */
580
 
    /* Try to read the private key file */
581
 
    gnutls_datum_t buffer = { .data = NULL, .size = 0 };
582
 
    {
583
 
      int secfile = open(seckeyfilename, O_RDONLY);
584
 
      size_t buffer_capacity = 0;
585
 
      while(true){
586
 
        buffer_capacity = incbuffer((char **)&buffer.data,
587
 
                                    (size_t)buffer.size,
588
 
                                    (size_t)buffer_capacity);
589
 
        if(buffer_capacity == 0){
590
 
          perror_plus("incbuffer");
591
 
          free(buffer.data);
592
 
          buffer.data = NULL;
593
 
          break;
594
 
        }
595
 
        ssize_t bytes_read = read(secfile, buffer.data + buffer.size,
596
 
                                  BUFFER_SIZE);
597
 
        /* EOF */
598
 
        if(bytes_read == 0){
599
 
          break;
600
 
        }
601
 
        /* check bytes_read for failure */
602
 
        if(bytes_read < 0){
603
 
          perror_plus("read");
604
 
          free(buffer.data);
605
 
          buffer.data = NULL;
606
 
          break;
607
 
        }
608
 
        buffer.size += (unsigned int)bytes_read;
609
 
      }
610
 
      close(secfile);
611
 
    }
612
 
    /* If successful, use buffer to parse private key */
613
 
    gnutls_sec_param_t sec_param = GNUTLS_SEC_PARAM_ULTRA;
614
 
    if(buffer.data != NULL){
615
 
      {
616
 
        gnutls_openpgp_privkey_t privkey = NULL;
617
 
        ret = gnutls_openpgp_privkey_init(&privkey);
618
 
        if(ret != GNUTLS_E_SUCCESS){
619
 
          fprintf_plus(stderr, "Error initializing OpenPGP key"
620
 
                       " structure: %s", safer_gnutls_strerror(ret));
621
 
          free(buffer.data);
622
 
          buffer.data = NULL;
623
 
        } else {
624
 
          ret = gnutls_openpgp_privkey_import(privkey, &buffer,
625
 
                                            GNUTLS_OPENPGP_FMT_BASE64,
626
 
                                              "", 0);
627
 
          if(ret != GNUTLS_E_SUCCESS){
628
 
            fprintf_plus(stderr, "Error importing OpenPGP key : %s",
629
 
                         safer_gnutls_strerror(ret));
630
 
            privkey = NULL;
631
 
          }
632
 
          free(buffer.data);
633
 
          buffer.data = NULL;
634
 
          if(privkey != NULL){
635
 
            /* Use private key to suggest an appropriate sec_param */
636
 
            sec_param = gnutls_openpgp_privkey_sec_param(privkey);
637
 
            gnutls_openpgp_privkey_deinit(privkey);
638
 
            if(debug){
639
 
              fprintf_plus(stderr, "This OpenPGP key implies using a"
640
 
                           " GnuTLS security parameter \"%s\".\n",
641
 
                           safe_string(gnutls_sec_param_get_name
642
 
                                       (sec_param)));
643
 
            }
644
 
          }
645
 
        }
646
 
      }
647
 
      if(sec_param == GNUTLS_SEC_PARAM_UNKNOWN){
648
 
        /* Err on the side of caution */
649
 
        sec_param = GNUTLS_SEC_PARAM_ULTRA;
650
 
        if(debug){
651
 
          fprintf_plus(stderr, "Falling back to security parameter"
652
 
                       " \"%s\"\n",
653
 
                       safe_string(gnutls_sec_param_get_name
654
 
                                   (sec_param)));
655
 
        }
656
 
      }
657
 
    }
658
 
    uret = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, sec_param);
659
 
    if(uret != 0){
660
 
      mc->dh_bits = uret;
661
 
      if(debug){
662
 
        fprintf_plus(stderr, "A \"%s\" GnuTLS security parameter"
663
 
                     " implies %u DH bits; using that.\n",
664
 
                     safe_string(gnutls_sec_param_get_name
665
 
                                 (sec_param)),
666
 
                     mc->dh_bits);
667
 
      }
668
 
    } else {
669
 
      fprintf_plus(stderr, "Failed to get implied number of DH"
670
 
                   " bits for security parameter \"%s\"): %s\n",
671
 
                   safe_string(gnutls_sec_param_get_name(sec_param)),
672
 
                   safer_gnutls_strerror(ret));
673
 
      goto globalfail;
674
 
    }
675
 
  } else if(debug){
676
 
    fprintf_plus(stderr, "DH bits explicitly set to %u\n",
677
 
                 mc->dh_bits);
678
 
  }
679
572
  ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
680
573
  if(ret != GNUTLS_E_SUCCESS){
681
 
    fprintf_plus(stderr, "Error in GnuTLS prime generation (%u bits):"
682
 
                 " %s\n", mc->dh_bits, safer_gnutls_strerror(ret));
 
574
    fprintf_plus(stderr, "Error in GnuTLS prime generation: %s\n",
 
575
                 safer_gnutls_strerror(ret));
683
576
    goto globalfail;
684
577
  }
685
578
  
809
702
  return ret_errno;
810
703
}
811
704
 
812
 
/* Helper function to add_local_route() and delete_local_route() */
 
705
/* Helper function to add_local_route() and remove_local_route() */
813
706
__attribute__((nonnull, warn_unused_result))
814
 
static bool add_delete_local_route(const bool add,
 
707
static bool add_remove_local_route(const bool add,
815
708
                                   const char *address,
816
709
                                   AvahiIfIndex if_index){
817
710
  int ret;
818
711
  char helper[] = "mandos-client-iprouteadddel";
819
712
  char add_arg[] = "add";
820
713
  char delete_arg[] = "delete";
821
 
  char debug_flag[] = "--debug";
822
714
  char *pluginhelperdir = getenv("MANDOSPLUGINHELPERDIR");
823
715
  if(pluginhelperdir == NULL){
824
716
    if(debug){
900
792
#endif
901
793
    if(fexecve(helper_fd, (char *const [])
902
794
               { helper, add ? add_arg : delete_arg, (char *)address,
903
 
                   interface, debug ? debug_flag : NULL, NULL },
904
 
               environ) == -1){
 
795
                   interface, NULL }, environ) == -1){
905
796
#ifdef __GNUC__
906
797
#pragma GCC diagnostic pop
907
798
#endif
959
850
__attribute__((nonnull, warn_unused_result))
960
851
static bool add_local_route(const char *address,
961
852
                            AvahiIfIndex if_index){
962
 
  if(debug){
963
 
    fprintf_plus(stderr, "Adding route to %s\n", address);
964
 
  }
965
 
  return add_delete_local_route(true, address, if_index);
 
853
  return add_remove_local_route(true, address, if_index);
966
854
}
967
855
 
968
856
__attribute__((nonnull, warn_unused_result))
969
 
static bool delete_local_route(const char *address,
 
857
static bool remove_local_route(const char *address,
970
858
                               AvahiIfIndex if_index){
971
 
  if(debug){
972
 
    fprintf_plus(stderr, "Removing route to %s\n", address);
973
 
  }
974
 
  return add_delete_local_route(false, address, if_index);
 
859
  return add_remove_local_route(false, address, if_index);
975
860
}
976
861
 
977
862
/* Called when a Mandos server is found */
1180
1065
           http://lists.freedesktop.org/archives/avahi/2010-February/001833.html
1181
1066
           https://bugs.debian.org/587961
1182
1067
        */
1183
 
        if(debug){
1184
 
          fprintf_plus(stderr, "Mandos server unreachable, trying"
1185
 
                       " direct route\n");
1186
 
        }
1187
1068
        int e = errno;
1188
1069
        route_added = add_local_route(ip, if_index);
1189
1070
        if(route_added){
1393
1274
 mandos_end:
1394
1275
  {
1395
1276
    if(route_added){
1396
 
      if(not delete_local_route(ip, if_index)){
1397
 
        fprintf_plus(stderr, "Failed to delete local route to %s on"
 
1277
      if(not remove_local_route(ip, if_index)){
 
1278
        fprintf_plus(stderr, "Failed to remove local route to %s on"
1398
1279
                     " interface %d", ip, if_index);
1399
1280
      }
1400
1281
    }
2222
2103
}
2223
2104
 
2224
2105
int main(int argc, char *argv[]){
2225
 
  mandos_context mc = { .server = NULL, .dh_bits = 0,
 
2106
  mandos_context mc = { .server = NULL, .dh_bits = 1024,
2226
2107
                        .priority = "SECURE256:!CTYPE-X.509:"
2227
 
                        "+CTYPE-OPENPGP:!RSA", .current_server = NULL,
 
2108
                        "+CTYPE-OPENPGP", .current_server = NULL,
2228
2109
                        .interfaces = NULL, .interfaces_size = 0 };
2229
2110
  AvahiSServiceBrowser *sb = NULL;
2230
2111
  error_t ret_errno;