/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release

« back to all changes in this revision

Viewing changes to plugin-runner.c

  • Committer: Teddy Hogeborn
  • Date: 2008-08-16 16:58:31 UTC
  • Revision ID: teddy@fukt.bsnet.se-20080816165831-cx018vo5i9oqmgo0
* plugins.d/password-request.c (main): Include environment variables
                                       "cryptsource" and "crypttarget"
                                       in password prompt.

Show diffs side-by-side

added added

removed removed

Lines of Context:
105
105
  if (new_plugin == NULL){
106
106
    return NULL;
107
107
  }
108
 
  char *copy_name = NULL;
109
 
  if(name != NULL){
110
 
    copy_name = strdup(name);
111
 
    if(copy_name == NULL){
112
 
      return NULL;
113
 
    }
114
 
  }
115
 
  
116
 
  *new_plugin = (plugin) { .name = copy_name,
 
108
  *new_plugin = (plugin) { .name = name,
117
109
                           .argc = 1,
118
110
                           .envc = 0,
119
111
                           .disabled = false,
121
113
  
122
114
  new_plugin->argv = malloc(sizeof(char *) * 2);
123
115
  if (new_plugin->argv == NULL){
124
 
    free(copy_name);
125
116
    free(new_plugin);
126
117
    return NULL;
127
118
  }
128
 
  new_plugin->argv[0] = copy_name;
 
119
  new_plugin->argv[0] = name;
129
120
  new_plugin->argv[1] = NULL;
130
121
 
131
122
  new_plugin->environ = malloc(sizeof(char *));
132
123
  if(new_plugin->environ == NULL){
133
 
    free(copy_name);
134
124
    free(new_plugin->argv);
135
125
    free(new_plugin);
136
126
    return NULL;
252
242
    return NULL;
253
243
  }
254
244
  argv[*argc-1] = arg;
255
 
  argv[*argc] = NULL;
 
245
  argv[*argc] = NULL;   
256
246
  return argv;
257
247
}
258
248
 
259
 
static void free_plugin_list(plugin *plugin_list){
260
 
  for(plugin *next; plugin_list != NULL; plugin_list = next){
261
 
    next = plugin_list->next;
262
 
    for(char **arg = plugin_list->argv; *arg != NULL; arg++){
263
 
      free(*arg);
264
 
    }
265
 
    free(plugin_list->argv);
266
 
    for(char **env = plugin_list->environ; *env != NULL; env++){
267
 
      free(*env);
268
 
    }
269
 
    free(plugin_list->environ);
270
 
    free(plugin_list);
271
 
  }
272
 
}
273
 
 
274
249
int main(int argc, char *argv[]){
275
250
  const char *plugindir = "/lib/mandos/plugins.d";
276
251
  const char *argfile = ARGFILE;
294
269
  /* Establish a signal handler */
295
270
  sigemptyset(&sigchld_action.sa_mask);
296
271
  ret = sigaddset(&sigchld_action.sa_mask, SIGCHLD);
297
 
  if(ret == -1){
 
272
  if(ret < 0){
298
273
    perror("sigaddset");
299
 
    exitstatus = EXIT_FAILURE;
300
 
    goto fallback;
 
274
    exit(EXIT_FAILURE);
301
275
  }
302
276
  ret = sigaction(SIGCHLD, &sigchld_action, &old_sigchld_action);
303
 
  if(ret == -1){
 
277
  if(ret < 0){
304
278
    perror("sigaction");
305
 
    exitstatus = EXIT_FAILURE;
306
 
    goto fallback;
 
279
    exit(EXIT_FAILURE);
307
280
  }
308
281
  
309
282
  /* The options we understand. */
455
428
  if (ret == ARGP_ERR_UNKNOWN){
456
429
    fprintf(stderr, "Unknown error while parsing arguments\n");
457
430
    exitstatus = EXIT_FAILURE;
458
 
    goto fallback;
 
431
    goto end;
459
432
  }
460
433
 
461
434
  conffp = fopen(argfile, "r");
462
435
  if(conffp != NULL){
463
436
    char *org_line = NULL;
464
 
    char *p, *arg, *new_arg, *line;
465
437
    size_t size = 0;
466
438
    ssize_t sret;
 
439
    char *p, *arg, *new_arg, *line;
467
440
    const char whitespace_delims[] = " \r\t\f\v\n";
468
441
    const char comment_delim[] = "#";
469
442
 
484
457
        if (custom_argv == NULL){
485
458
          perror("add_to_argv");
486
459
          exitstatus = EXIT_FAILURE;
487
 
          goto fallback;
 
460
          goto end;
488
461
        }
489
462
      }
490
463
    }
495
468
    if (errno == EMFILE or errno == ENFILE or errno == ENOMEM){
496
469
      perror("fopen");
497
470
      exitstatus = EXIT_FAILURE;
498
 
      goto fallback;
 
471
      goto end;
499
472
    }
500
473
  }
501
474
 
505
478
    if (ret == ARGP_ERR_UNKNOWN){
506
479
      fprintf(stderr, "Unknown error while parsing arguments\n");
507
480
      exitstatus = EXIT_FAILURE;
508
 
      goto fallback;
 
481
      goto end;
509
482
    }
510
483
  }
511
484
  
537
510
  if(dir == NULL){
538
511
    perror("Could not open plugin dir");
539
512
    exitstatus = EXIT_FAILURE;
540
 
    goto fallback;
 
513
    goto end;
541
514
  }
542
515
  
543
516
  /* Set the FD_CLOEXEC flag on the directory, if possible */
548
521
      if(ret < 0){
549
522
        perror("set_cloexec_flag");
550
523
        exitstatus = EXIT_FAILURE;
551
 
        goto fallback;
 
524
        goto end;
552
525
      }
553
526
    }
554
527
  }
563
536
      if (errno == EBADF){
564
537
        perror("readdir");
565
538
        exitstatus = EXIT_FAILURE;
566
 
        goto fallback;
 
539
        goto end;
567
540
      }
568
541
      break;
569
542
    }
684
657
      }
685
658
    }
686
659
    
687
 
    int pipefd[2];
 
660
    int pipefd[2]; 
688
661
    ret = pipe(pipefd);
689
662
    if (ret == -1){
690
663
      perror("pipe");
691
664
      exitstatus = EXIT_FAILURE;
692
 
      goto fallback;
 
665
      goto end;
693
666
    }
694
667
    ret = set_cloexec_flag(pipefd[0]);
695
668
    if(ret < 0){
696
669
      perror("set_cloexec_flag");
697
670
      exitstatus = EXIT_FAILURE;
698
 
      goto fallback;
 
671
      goto end;
699
672
    }
700
673
    ret = set_cloexec_flag(pipefd[1]);
701
674
    if(ret < 0){
702
675
      perror("set_cloexec_flag");
703
676
      exitstatus = EXIT_FAILURE;
704
 
      goto fallback;
 
677
      goto end;
705
678
    }
706
679
    /* Block SIGCHLD until process is safely in process list */
707
680
    ret = sigprocmask (SIG_BLOCK, &sigchld_action.sa_mask, NULL);
708
681
    if(ret < 0){
709
682
      perror("sigprocmask");
710
683
      exitstatus = EXIT_FAILURE;
711
 
      goto fallback;
 
684
      goto end;
712
685
    }
713
686
    // Starting a new process to be watched
714
687
    pid_t pid = fork();
715
688
    if(pid == -1){
716
689
      perror("fork");
717
690
      exitstatus = EXIT_FAILURE;
718
 
      goto fallback;
 
691
      goto end;
719
692
    }
720
693
    if(pid == 0){
721
694
      /* this is the child process */
765
738
        perror("sigprocmask");
766
739
      }
767
740
      exitstatus = EXIT_FAILURE;
768
 
      goto fallback;
 
741
      goto end;
769
742
    }
770
743
    
771
744
    *new_process = (struct process){ .pid = pid,
779
752
    if(ret < 0){
780
753
      perror("sigprocmask");
781
754
      exitstatus = EXIT_FAILURE;
782
 
      goto fallback;
 
755
      goto end;
783
756
    }
784
757
    
785
758
    FD_SET(new_process->fd, &rfds_all);
790
763
    
791
764
  }
792
765
  
793
 
  free_plugin_list(plugin_list);
794
 
  plugin_list = NULL;
 
766
  /* Free the plugin list */
 
767
  for(plugin *next; plugin_list != NULL; plugin_list = next){
 
768
    next = plugin_list->next;
 
769
    free(plugin_list->argv);
 
770
    if(plugin_list->environ[0] != NULL){
 
771
      for(char **e = plugin_list->environ; *e != NULL; e++){
 
772
        free(*e);
 
773
      }
 
774
    }
 
775
    free(plugin_list);
 
776
  }
795
777
  
796
778
  closedir(dir);
797
779
  dir = NULL;
807
789
    if (select_ret == -1){
808
790
      perror("select");
809
791
      exitstatus = EXIT_FAILURE;
810
 
      goto fallback;
 
792
      goto end;
811
793
    }
812
794
    /* OK, now either a process completed, or something can be read
813
795
       from one of them */
839
821
          if(ret < 0){
840
822
            perror("sigprocmask");
841
823
            exitstatus = EXIT_FAILURE;
842
 
            goto fallback;
 
824
            goto end;
843
825
          }
844
826
          /* Delete this process entry from the list */
845
827
          if(process_list == proc){
874
856
          perror("print_out_password");
875
857
          exitstatus = EXIT_FAILURE;
876
858
        }
877
 
        goto fallback;
 
859
        goto end;
878
860
      }
879
861
      /* This process has not completed.  Does it have any output? */
880
862
      if(proc->eof or not FD_ISSET(proc->fd, &rfds)){
888
870
        if (proc->buffer == NULL){
889
871
          perror("malloc");
890
872
          exitstatus = EXIT_FAILURE;
891
 
          goto fallback;
 
873
          goto end;
892
874
        }
893
875
        proc->buffer_size += BUFFER_SIZE;
894
876
      }
909
891
  }
910
892
 
911
893
 
912
 
 fallback:
 
894
 end:
913
895
  
914
896
  if(process_list == NULL or exitstatus != EXIT_SUCCESS){
915
897
    /* Fallback if all plugins failed, none are found or an error occured */
920
902
    if(not bret){
921
903
      perror("print_out_password");
922
904
      exitstatus = EXIT_FAILURE;
 
905
      goto end;
923
906
    }
924
907
  }
925
908
  
926
909
  /* Restore old signal handler */
927
 
  ret = sigaction(SIGCHLD, &old_sigchld_action, NULL);
928
 
  if(ret == -1){
929
 
    perror("sigaction");
930
 
    exitstatus = EXIT_FAILURE;
931
 
  }
932
 
 
933
 
  if(custom_argv != NULL){
934
 
    for(char **arg = custom_argv; *arg != NULL; arg++){
935
 
      free(*arg);
 
910
  sigaction(SIGCHLD, &old_sigchld_action, NULL);
 
911
  
 
912
  free(custom_argv);
 
913
  
 
914
  /* Free the plugin list */
 
915
  for(plugin *next; plugin_list != NULL; plugin_list = next){
 
916
    next = plugin_list->next;
 
917
    free(plugin_list->argv);
 
918
    if(plugin_list->environ[0] != NULL){
 
919
      for(char **e = plugin_list->environ; *e != NULL; e++){
 
920
        free(*e);
 
921
      }
936
922
    }
937
 
    free(custom_argv);
 
923
    free(plugin_list->environ);
 
924
    free(plugin_list);
938
925
  }
939
 
  free_plugin_list(plugin_list);
940
926
  
941
927
  if(dir != NULL){
942
928
    closedir(dir);