/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 plugin-runner.c

  • Committer: Teddy Hogeborn
  • Date: 2009-10-26 21:16:16 UTC
  • Revision ID: teddy@fukt.bsnet.se-20091026211616-38e9wynf4428ip2l
Merge from release branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#define _GNU_SOURCE             /* TEMP_FAILURE_RETRY(), getline(),
26
26
                                   asprintf(), O_CLOEXEC */
27
27
#include <stddef.h>             /* size_t, NULL */
28
 
#include <stdlib.h>             /* malloc(), exit(), EXIT_SUCCESS,
29
 
                                   realloc() */
 
28
#include <stdlib.h>             /* malloc(), exit(), EXIT_FAILURE,
 
29
                                   EXIT_SUCCESS, realloc() */
30
30
#include <stdbool.h>            /* bool, true, false */
31
31
#include <stdio.h>              /* perror, fileno(), fprintf(),
32
32
                                   stderr, STDOUT_FILENO */
54
54
#include <fcntl.h>              /* fcntl(), F_GETFD, F_SETFD,
55
55
                                   FD_CLOEXEC */
56
56
#include <string.h>             /* strsep, strlen(), asprintf(),
57
 
                                   strsignal(), strcmp(), strncmp() */
 
57
                                   strsignal() */
58
58
#include <errno.h>              /* errno */
59
59
#include <argp.h>               /* struct argp_option, struct
60
60
                                   argp_state, struct argp,
68
68
                                */
69
69
#include <errno.h>              /* errno, EBADF */
70
70
#include <inttypes.h>           /* intmax_t, PRIdMAX, strtoimax() */
71
 
#include <sysexits.h>           /* EX_OSERR, EX_USAGE, EX_IOERR,
72
 
                                   EX_CONFIG, EX_UNAVAILABLE, EX_OK */
 
71
#include <sysexits.h>           /* EX_OSERR, EX_USAGE */
73
72
 
74
73
#define BUFFER_SIZE 256
75
74
 
358
357
  ret = sigaddset(&sigchld_action.sa_mask, SIGCHLD);
359
358
  if(ret == -1){
360
359
    perror("sigaddset");
361
 
    exitstatus = EX_OSERR;
 
360
    exitstatus = EXIT_FAILURE;
362
361
    goto fallback;
363
362
  }
364
363
  ret = sigaction(SIGCHLD, &sigchld_action, &old_sigchld_action);
365
364
  if(ret == -1){
366
365
    perror("sigaction");
367
 
    exitstatus = EX_OSERR;
 
366
    exitstatus = EXIT_FAILURE;
368
367
    goto fallback;
369
368
  }
370
369
  
627
626
    custom_argv = malloc(sizeof(char*) * 2);
628
627
    if(custom_argv == NULL){
629
628
      perror("malloc");
630
 
      exitstatus = EX_OSERR;
 
629
      exitstatus = EXIT_FAILURE;
631
630
      goto fallback;
632
631
    }
633
632
    custom_argv[0] = argv[0];
650
649
        new_arg = strdup(p);
651
650
        if(new_arg == NULL){
652
651
          perror("strdup");
653
 
          exitstatus = EX_OSERR;
 
652
          exitstatus = EXIT_FAILURE;
654
653
          free(org_line);
655
654
          goto fallback;
656
655
        }
660
659
                              * ((unsigned int) custom_argc + 1));
661
660
        if(custom_argv == NULL){
662
661
          perror("realloc");
663
 
          exitstatus = EX_OSERR;
 
662
          exitstatus = EXIT_FAILURE;
664
663
          free(org_line);
665
664
          goto fallback;
666
665
        }
673
672
    } while(ret == EOF and errno == EINTR);
674
673
    if(ret == EOF){
675
674
      perror("fclose");
676
 
      exitstatus = EX_IOERR;
 
675
      exitstatus = EXIT_FAILURE;
677
676
      goto fallback;
678
677
    }
679
678
    free(org_line);
682
681
       not affect opening plugins */
683
682
    if(errno == EMFILE or errno == ENFILE or errno == ENOMEM){
684
683
      perror("fopen");
685
 
      exitstatus = EX_OSERR;
 
684
      exitstatus = EXIT_FAILURE;
686
685
      goto fallback;
687
686
    }
688
687
  }
772
771
    }
773
772
    if(dir_fd == -1){
774
773
      perror("Could not open plugin dir");
775
 
      exitstatus = EX_UNAVAILABLE;
 
774
      exitstatus = EXIT_FAILURE;
776
775
      goto fallback;
777
776
    }
778
777
    
782
781
    if(ret < 0){
783
782
      perror("set_cloexec_flag");
784
783
      TEMP_FAILURE_RETRY(close(dir_fd));
785
 
      exitstatus = EX_OSERR;
 
784
      exitstatus = EXIT_FAILURE;
786
785
      goto fallback;
787
786
    }
788
787
#endif  /* O_CLOEXEC */
791
790
    if(dir == NULL){
792
791
      perror("Could not open plugin dir");
793
792
      TEMP_FAILURE_RETRY(close(dir_fd));
794
 
      exitstatus = EX_OSERR;
 
793
      exitstatus = EXIT_FAILURE;
795
794
      goto fallback;
796
795
    }
797
796
  }
808
807
    if(dirst == NULL){
809
808
      if(errno == EBADF){
810
809
        perror("readdir");
811
 
        exitstatus = EX_IOERR;
 
810
        exitstatus = EXIT_FAILURE;
812
811
        goto fallback;
813
812
      }
814
813
      break;
844
843
      for(const char **suf = bad_suffixes; *suf != NULL; suf++){
845
844
        size_t suf_len = strlen(*suf);
846
845
        if((d_name_len >= suf_len)
847
 
           and (strcmp((dirst->d_name) + d_name_len-suf_len, *suf)
 
846
           and (strcmp((dirst->d_name)+d_name_len-suf_len, *suf)
848
847
                == 0)){
849
848
          if(debug){
850
849
            fprintf(stderr, "Ignoring plugin dir entry \"%s\""
938
937
    ret = (int)TEMP_FAILURE_RETRY(pipe(pipefd));
939
938
    if(ret == -1){
940
939
      perror("pipe");
941
 
      exitstatus = EX_OSERR;
 
940
      exitstatus = EXIT_FAILURE;
942
941
      goto fallback;
943
942
    }
944
943
    /* Ask OS to automatic close the pipe on exec */
945
944
    ret = set_cloexec_flag(pipefd[0]);
946
945
    if(ret < 0){
947
946
      perror("set_cloexec_flag");
948
 
      exitstatus = EX_OSERR;
 
947
      exitstatus = EXIT_FAILURE;
949
948
      goto fallback;
950
949
    }
951
950
    ret = set_cloexec_flag(pipefd[1]);
952
951
    if(ret < 0){
953
952
      perror("set_cloexec_flag");
954
 
      exitstatus = EX_OSERR;
 
953
      exitstatus = EXIT_FAILURE;
955
954
      goto fallback;
956
955
    }
957
956
    /* Block SIGCHLD until process is safely in process list */
960
959
                                              NULL));
961
960
    if(ret < 0){
962
961
      perror("sigprocmask");
963
 
      exitstatus = EX_OSERR;
 
962
      exitstatus = EXIT_FAILURE;
964
963
      goto fallback;
965
964
    }
966
965
    /* Starting a new process to be watched */
970
969
    } while(pid == -1 and errno == EINTR);
971
970
    if(pid == -1){
972
971
      perror("fork");
973
 
      exitstatus = EX_OSERR;
 
972
      exitstatus = EXIT_FAILURE;
974
973
      goto fallback;
975
974
    }
976
975
    if(pid == 0){
978
977
      ret = sigaction(SIGCHLD, &old_sigchld_action, NULL);
979
978
      if(ret < 0){
980
979
        perror("sigaction");
981
 
        _exit(EX_OSERR);
 
980
        _exit(EXIT_FAILURE);
982
981
      }
983
982
      ret = sigprocmask(SIG_UNBLOCK, &sigchld_action.sa_mask, NULL);
984
983
      if(ret < 0){
985
984
        perror("sigprocmask");
986
 
        _exit(EX_OSERR);
 
985
        _exit(EXIT_FAILURE);
987
986
      }
988
987
      
989
988
      ret = dup2(pipefd[1], STDOUT_FILENO); /* replace our stdout */
990
989
      if(ret == -1){
991
990
        perror("dup2");
992
 
        _exit(EX_OSERR);
 
991
        _exit(EXIT_FAILURE);
993
992
      }
994
993
      
995
994
      if(dirfd(dir) < 0){
1000
999
      if(p->environ[0] == NULL){
1001
1000
        if(execv(filename, p->argv) < 0){
1002
1001
          perror("execv");
1003
 
          _exit(EX_OSERR);
 
1002
          _exit(EXIT_FAILURE);
1004
1003
        }
1005
1004
      } else {
1006
1005
        if(execve(filename, p->argv, p->environ) < 0){
1007
1006
          perror("execve");
1008
 
          _exit(EX_OSERR);
 
1007
          _exit(EXIT_FAILURE);
1009
1008
        }
1010
1009
      }
1011
1010
      /* no return */
1023
1022
      if(ret < 0){
1024
1023
        perror("sigprocmask");
1025
1024
      }
1026
 
      exitstatus = EX_OSERR;
 
1025
      exitstatus = EXIT_FAILURE;
1027
1026
      goto fallback;
1028
1027
    }
1029
1028
    
1037
1036
                                              NULL));
1038
1037
    if(ret < 0){
1039
1038
      perror("sigprocmask");
1040
 
      exitstatus = EX_OSERR;
 
1039
      exitstatus = EXIT_FAILURE;
1041
1040
      goto fallback;
1042
1041
    }
1043
1042
    
1070
1069
    int select_ret = select(maxfd+1, &rfds, NULL, NULL, NULL);
1071
1070
    if(select_ret == -1 and errno != EINTR){
1072
1071
      perror("select");
1073
 
      exitstatus = EX_OSERR;
 
1072
      exitstatus = EXIT_FAILURE;
1074
1073
      goto fallback;
1075
1074
    }
1076
1075
    /* OK, now either a process completed, or something can be read
1112
1111
                                         NULL));
1113
1112
          if(ret < 0){
1114
1113
            perror("sigprocmask");
1115
 
            exitstatus = EX_OSERR;
 
1114
            exitstatus = EXIT_FAILURE;
1116
1115
            goto fallback;
1117
1116
          }
1118
1117
          
1126
1125
                                   &sigchld_action.sa_mask, NULL)));
1127
1126
          if(ret < 0){
1128
1127
            perror("sigprocmask");
1129
 
            exitstatus = EX_OSERR;
 
1128
            exitstatus = EXIT_FAILURE;
1130
1129
            goto fallback;
1131
1130
          }
1132
1131
          
1143
1142
                                       proc->buffer_length);
1144
1143
        if(not bret){
1145
1144
          perror("print_out_password");
1146
 
          exitstatus = EX_IOERR;
 
1145
          exitstatus = EXIT_FAILURE;
1147
1146
        }
1148
1147
        goto fallback;
1149
1148
      }
1162
1161
                               + (size_t) BUFFER_SIZE);
1163
1162
        if(proc->buffer == NULL){
1164
1163
          perror("malloc");
1165
 
          exitstatus = EX_OSERR;
 
1164
          exitstatus = EXIT_FAILURE;
1166
1165
          goto fallback;
1167
1166
        }
1168
1167
        proc->buffer_size += BUFFER_SIZE;
1189
1188
  
1190
1189
 fallback:
1191
1190
  
1192
 
  if(plugin_list == NULL or (exitstatus != EXIT_SUCCESS
1193
 
                             and exitstatus != EX_OK)){
 
1191
  if(plugin_list == NULL or exitstatus != EXIT_SUCCESS){
1194
1192
    /* Fallback if all plugins failed, none are found or an error
1195
1193
       occured */
1196
1194
    bool bret;
1205
1203
    bret = print_out_password(passwordbuffer, len);
1206
1204
    if(not bret){
1207
1205
      perror("print_out_password");
1208
 
      exitstatus = EX_IOERR;
 
1206
      exitstatus = EXIT_FAILURE;
1209
1207
    }
1210
1208
  }
1211
1209
  
1213
1211
  ret = sigaction(SIGCHLD, &old_sigchld_action, NULL);
1214
1212
  if(ret == -1){
1215
1213
    perror("sigaction");
1216
 
    exitstatus = EX_OSERR;
 
1214
    exitstatus = EXIT_FAILURE;
1217
1215
  }
1218
1216
  
1219
1217
  if(custom_argv != NULL){