/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/password-request.c

  • Committer: Teddy Hogeborn
  • Date: 2008-08-16 03:29:08 UTC
  • Revision ID: teddy@fukt.bsnet.se-20080816032908-ihw7c05r2mnyk389
Add feature to specify custom environment variables for plugins.

* plugin-runner.c (plugin): New members "environ" and "envc" to
                            contain possible custom environment.
  (getplugin): Return NULL on failure instead of doing exit(); all
               callers changed.
  (add_to_char_array): New helper function for "add_argument" and
                       "add_environment".
  (addargument): Renamed to "add_argument".  Return bool.  Call
                 "add_to_char_array" to actually do things.
  (add_environment): New; analogous to "add_argument".
  (addcustomargument): Renamed to "add_to_argv" to avoid confusion
                       with "add_argument".
  (main): New options "--global-envs" and "--envs-for" to specify
          custom environment for plugins.  Print environment for
          plugins in debug mode.  Use asprintf instead of strcpy and
          strcat.  Use execve() for plugins with custom environments.
          Free environment for plugin when freeing plugin list.

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() */
 
35
#define _GNU_SOURCE             /* TEMP_FAILURE_RETRY(), asprintf() */
36
36
 
37
 
#include <stdio.h>              /* fprintf(), stderr, fwrite(), stdout,
38
 
                                   ferror() */
 
37
#include <stdio.h>              /* fprintf(), stderr, fwrite(),
 
38
                                   stdout, ferror() */
39
39
#include <stdint.h>             /* uint16_t, uint32_t */
40
40
#include <stddef.h>             /* NULL, size_t, ssize_t */
41
41
#include <stdlib.h>             /* free(), EXIT_SUCCESS, EXIT_FAILURE,
42
42
                                   srand() */
43
43
#include <stdbool.h>            /* bool, true */
44
44
#include <string.h>             /* memset(), strcmp(), strlen(),
45
 
                                   strerror(), memcpy(), strcpy() */
 
45
                                   strerror(), asprintf(), strcpy() */
46
46
#include <sys/ioctl.h>          /* ioctl */
47
 
#include <net/if.h>             /* ifreq, SIOCGIFFLAGS, SIOCSIFFLAGS,
48
 
                                   IFF_UP */
49
47
#include <sys/types.h>          /* socket(), inet_pton(), sockaddr,
50
48
                                   sockaddr_in6, PF_INET6,
51
49
                                   SOCK_STREAM, INET6_ADDRSTRLEN,
83
81
#include <avahi-common/error.h>
84
82
 
85
83
/* GnuTLS */
86
 
#include <gnutls/gnutls.h>      /* All GnuTLS types, constants and functions
 
84
#include <gnutls/gnutls.h>      /* All GnuTLS types, constants and
 
85
                                   functions:
87
86
                                   gnutls_*
88
87
                                   init_gnutls_session(),
89
88
                                   GNUTLS_* */
91
90
                                   GNUTLS_OPENPGP_FMT_BASE64 */
92
91
 
93
92
/* GPGME */
94
 
#include <gpgme.h>              /* All GPGME types, constants and functions
 
93
#include <gpgme.h>              /* All GPGME types, constants and
 
94
                                   functions:
95
95
                                   gpgme_*
96
96
                                   GPGME_PROTOCOL_OpenPGP,
97
97
                                   GPG_ERR_NO_* */
315
315
}
316
316
 
317
317
static int init_gnutls_global(mandos_context *mc,
318
 
                              const char *pubkeyfile,
319
 
                              const char *seckeyfile){
 
318
                              const char *pubkeyfilename,
 
319
                              const char *seckeyfilename){
320
320
  int ret;
321
321
  
322
322
  if(debug){
349
349
  
350
350
  if(debug){
351
351
    fprintf(stderr, "Attempting to use OpenPGP certificate %s"
352
 
            " and keyfile %s as GnuTLS credentials\n", pubkeyfile,
353
 
            seckeyfile);
 
352
            " and keyfile %s as GnuTLS credentials\n", pubkeyfilename,
 
353
            seckeyfilename);
354
354
  }
355
355
  
356
356
  ret = gnutls_certificate_set_openpgp_key_file
357
 
    (mc->cred, pubkeyfile, seckeyfile, GNUTLS_OPENPGP_FMT_BASE64);
 
357
    (mc->cred, pubkeyfilename, seckeyfilename,
 
358
     GNUTLS_OPENPGP_FMT_BASE64);
358
359
  if (ret != GNUTLS_E_SUCCESS) {
359
360
    fprintf(stderr,
360
361
            "Error[%d] while reading the OpenPGP key pair ('%s',"
361
 
            " '%s')\n", ret, pubkeyfile, seckeyfile);
 
362
            " '%s')\n", ret, pubkeyfilename, seckeyfilename);
362
363
    fprintf(stdout, "The GnuTLS error is: %s\n",
363
364
            safer_gnutls_strerror(ret));
364
365
    goto globalfail;
474
475
    fprintf(stderr, "Binding to interface %s\n", interface);
475
476
  }
476
477
  
477
 
  memset(&to,0,sizeof(to));     /* Spurious warning */
 
478
  memset(&to, 0, sizeof(to));   /* Spurious warning */
478
479
  to.in6.sin6_family = AF_INET6;
479
480
  /* It would be nice to have a way to detect if we were passed an
480
481
     IPv4 address here.   Now we assume an IPv6 address. */
487
488
    fprintf(stderr, "Bad address: %s\n", ip);
488
489
    return -1;
489
490
  }
490
 
  to.in6.sin6_port = htons(port);       /* Spurious warning */
 
491
  to.in6.sin6_port = htons(port); /* Spurious warning */
491
492
  
492
493
  to.in6.sin6_scope_id = (uint32_t)if_index;
493
494
  
684
685
      }
685
686
      int ret = start_mandos_communication(ip, port, interface, mc);
686
687
      if (ret == 0){
687
 
        exit(EXIT_SUCCESS);
 
688
        avahi_simple_poll_quit(mc->simple_poll);
688
689
      }
689
690
    }
690
691
  }
744
745
 
745
746
/* Combines file name and path and returns the malloced new
746
747
   string. some sane checks could/should be added */
747
 
static const char *combinepath(const char *first, const char *second){
748
 
  size_t f_len = strlen(first);
749
 
  size_t s_len = strlen(second);
750
 
  char *tmp = malloc(f_len + s_len + 2);
751
 
  if (tmp == NULL){
 
748
static char *combinepath(const char *first, const char *second){
 
749
  char *tmp;
 
750
  int ret = asprintf(&tmp, "%s/%s", first, second);
 
751
  if(ret < 0){
752
752
    return NULL;
753
753
  }
754
 
  if(f_len > 0){
755
 
    memcpy(tmp, first, f_len);  /* Spurious warning */
756
 
  }
757
 
  tmp[f_len] = '/';
758
 
  if(s_len > 0){
759
 
    memcpy(tmp + f_len + 1, second, s_len); /* Spurious warning */
760
 
  }
761
 
  tmp[f_len + 1 + s_len] = '\0';
762
754
  return tmp;
763
755
}
764
756
 
775
767
    gid_t gid;
776
768
    char *connect_to = NULL;
777
769
    AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
778
 
    const char *pubkeyfile = "pubkey.txt";
779
 
    const char *seckeyfile = "seckey.txt";
 
770
    char *pubkeyfilename = NULL;
 
771
    char *seckeyfilename = NULL;
 
772
    const char *pubkeyname = "pubkey.txt";
 
773
    const char *seckeyname = "seckey.txt";
780
774
    mandos_context mc = { .simple_poll = NULL, .server = NULL,
781
775
                          .dh_bits = 1024, .priority = "SECURE256"};
782
776
    bool gnutls_initalized = false;
834
828
          keydir = arg;
835
829
          break;
836
830
        case 's':
837
 
          seckeyfile = arg;
 
831
          seckeyname = arg;
838
832
          break;
839
833
        case 'p':
840
 
          pubkeyfile = arg;
 
834
          pubkeyname = arg;
841
835
          break;
842
836
        case 129:
843
837
          errno = 0;
852
846
          break;
853
847
        case ARGP_KEY_ARG:
854
848
          argp_usage (state);
 
849
        case ARGP_KEY_END:
855
850
          break;
856
 
          case ARGP_KEY_END:
857
 
            break;
858
851
        default:
859
852
          return ARGP_ERR_UNKNOWN;
860
853
        }
867
860
                           " passwords from mandos server" };
868
861
      ret = argp_parse (&argp, argc, argv, 0, 0, NULL);
869
862
      if (ret == ARGP_ERR_UNKNOWN){
870
 
        fprintf(stderr, "Unkown error while parsing arguments\n");
 
863
        fprintf(stderr, "Unknown error while parsing arguments\n");
871
864
        exitcode = EXIT_FAILURE;
872
865
        goto end;
873
866
      }
874
867
    }
875
868
      
876
 
    pubkeyfile = combinepath(keydir, pubkeyfile);
877
 
    if (pubkeyfile == NULL){
 
869
    pubkeyfilename = combinepath(keydir, pubkeyname);
 
870
    if (pubkeyfilename == NULL){
878
871
      perror("combinepath");
879
872
      exitcode = EXIT_FAILURE;
880
873
      goto end;
881
874
    }
882
875
    
883
 
    seckeyfile = combinepath(keydir, seckeyfile);
884
 
    if (seckeyfile == NULL){
 
876
    seckeyfilename = combinepath(keydir, seckeyname);
 
877
    if (seckeyfilename == NULL){
885
878
      perror("combinepath");
 
879
      exitcode = EXIT_FAILURE;
886
880
      goto end;
887
881
    }
888
882
 
889
 
    ret = init_gnutls_global(&mc, pubkeyfile, seckeyfile);
 
883
    ret = init_gnutls_global(&mc, pubkeyfilename, seckeyfilename);
890
884
    if (ret == -1){
891
 
      fprintf(stderr, "init_gnutls_global\n");
 
885
      fprintf(stderr, "init_gnutls_global failed\n");
 
886
      exitcode = EXIT_FAILURE;
892
887
      goto end;
893
888
    } else {
894
889
      gnutls_initalized = true;
895
890
    }
896
 
 
 
891
    
 
892
    /* If the interface is down, bring it up */
 
893
    {
 
894
      sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
 
895
      if(sd < 0) {
 
896
        perror("socket");
 
897
        exitcode = EXIT_FAILURE;
 
898
        goto end;
 
899
      }
 
900
      strcpy(network.ifr_name, interface); /* Spurious warning */
 
901
      ret = ioctl(sd, SIOCGIFFLAGS, &network);
 
902
      if(ret == -1){
 
903
        perror("ioctl SIOCGIFFLAGS");
 
904
        exitcode = EXIT_FAILURE;
 
905
        goto end;
 
906
      }
 
907
      if((network.ifr_flags & IFF_UP) == 0){
 
908
        network.ifr_flags |= IFF_UP;
 
909
        ret = ioctl(sd, SIOCSIFFLAGS, &network);
 
910
        if(ret == -1){
 
911
          perror("ioctl SIOCSIFFLAGS");
 
912
          exitcode = EXIT_FAILURE;
 
913
          goto end;
 
914
        }
 
915
      }
 
916
      close(sd);
 
917
    }
 
918
    
897
919
    uid = getuid();
898
920
    gid = getgid();
899
 
 
 
921
    
900
922
    ret = setuid(uid);
901
923
    if (ret == -1){
902
924
      perror("setuid");
940
962
      goto end;
941
963
    }
942
964
    
943
 
    /* If the interface is down, bring it up */
944
 
    {
945
 
      sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
946
 
      if(sd < 0) {
947
 
        perror("socket");
948
 
        exitcode = EXIT_FAILURE;
949
 
        goto end;
950
 
      }
951
 
      strcpy(network.ifr_name, interface); /* Spurious warning */
952
 
      ret = ioctl(sd, SIOCGIFFLAGS, &network);
953
 
      if(ret == -1){
954
 
        perror("ioctl SIOCGIFFLAGS");
955
 
        exitcode = EXIT_FAILURE;
956
 
        goto end;
957
 
      }
958
 
      if((network.ifr_flags & IFF_UP) == 0){
959
 
        network.ifr_flags |= IFF_UP;
960
 
        ret = ioctl(sd, SIOCSIFFLAGS, &network);
961
 
        if(ret == -1){
962
 
          perror("ioctl SIOCSIFFLAGS");
963
 
          exitcode = EXIT_FAILURE;
964
 
          goto end;
965
 
        }
966
 
      }
967
 
      close(sd);
968
 
    }
969
 
    
970
965
    if (not debug){
971
966
      avahi_set_log_function(empty_log);
972
967
    }
1044
1039
 
1045
1040
    if (mc.simple_poll != NULL)
1046
1041
        avahi_simple_poll_free(mc.simple_poll);
1047
 
    free(pubkeyfile);
1048
 
    free(seckeyfile);
 
1042
    free(pubkeyfilename);
 
1043
    free(seckeyfilename);
1049
1044
 
1050
1045
    if (gnutls_initalized){
1051
1046
      gnutls_certificate_free_credentials(mc.cred);