/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

First version of a somewhat complete D-Bus server interface.  Also
change user/group name to "_mandos".

* debian/mandos.postinst: Rename old "mandos" user and group to
                          "_mandos"; create "_mandos" user and group
                          if none exist.
* debian/mandos-client.postinst: - '' -

* initramfs-tools-hook: Try "_mandos" before "mandos" as user and
                        group name.

* mandos (_datetime_to_dbus_struct): New; was previously local.
  (Client.started): Renamed to "last_started".  All users changed.
  (Client.started): New; boolean.
  (Client.dbus_object_path): New.
  (Client.check_command): Renamed to "checker_command".  All users
                          changed.
  (Client.__init__): Set and use "self.dbus_object_path".  Set
                     "self.started".
  (Client.start): Update "self.started".  Emit "self.PropertyChanged"
                  signals for both "started" and "last_started".
  (Client.stop): Update "self.started".  Emit "self.PropertyChanged"
                 signal for "started".
  (Client.checker_callback): Take additional "command" argument.  All
                             callers changed. Emit
                             "self.PropertyChanged" signal.
  (Client.bump_timeout): Emit "self.PropertyChanged" signal for
                         "last_checked_ok".
  (Client.start_checker): Emit "self.PropertyChanged" signal for
                          "checker_running".
  (Client.stop_checker): Emit "self.PropertyChanged" signal for
                         "checker_running".
  (Client.still_valid): Bug fix: use "getattr(self, started, False)"
                        instead of "self.started" in case this client
                        object is so new that the "started" attribute
                        has not been created yet.
  (Client.IntervalChanged, Client.CheckerIsRunning, Client.GetChecker,
  Client.GetCreated, Client.GetFingerprint, Client.GetHost,
  Client.GetInterval, Client.GetName, Client.GetStarted,
  Client.GetTimeout, Client.StateChanged, Client.TimeoutChanged):
  Removed; all callers changed.
  (Client.CheckerCompleted): Add "condition" and "command" arguments.
                             All callers changed.
  (Client.GetAllProperties, Client.PropertyChanged): New.
  (Client.StillValid): Renamed to "IsStillValid".
  (Client.StartChecker): Changed to its own function to avoid the
                         return value from "Client.start_checker()".
  (Client.Stop): Changed to its own function to avoid the return value
                 from "Client.stop()".
  (main): Try "_mandos" before "mandos" as user and group name.
          Removed inner function "remove_from_clients".  New inner
          class "MandosServer".

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
/*
3
3
 * Mandos plugin runner - Run Mandos plugins
4
4
 *
5
 
 * Copyright © 2007-2008 Teddy Hogeborn & Björn Påhlsson
 
5
 * Copyright © 2008 Teddy Hogeborn
 
6
 * Copyright © 2008 Björn Påhlsson
6
7
 * 
7
8
 * This program is free software: you can redistribute it and/or
8
9
 * modify it under the terms of the GNU General Public License as
27
28
#include <stdlib.h>             /* malloc(), exit(), EXIT_FAILURE,
28
29
                                   EXIT_SUCCESS, realloc() */
29
30
#include <stdbool.h>            /* bool, true, false */
30
 
#include <stdio.h>              /* perror, popen(), fileno(),
31
 
                                   fprintf(), stderr, STDOUT_FILENO */
 
31
#include <stdio.h>              /* perror, fileno(), fprintf(),
 
32
                                   stderr, STDOUT_FILENO */
32
33
#include <sys/types.h>          /* DIR, opendir(), stat(), struct
33
34
                                   stat, waitpid(), WIFEXITED(),
34
35
                                   WEXITSTATUS(), wait(), pid_t,
46
47
                                   fcntl(), setuid(), setgid(),
47
48
                                   F_GETFD, F_SETFD, FD_CLOEXEC,
48
49
                                   access(), pipe(), fork(), close()
49
 
                                   dup2, STDOUT_FILENO, _exit(),
 
50
                                   dup2(), STDOUT_FILENO, _exit(),
50
51
                                   execv(), write(), read(),
51
52
                                   close() */
52
53
#include <fcntl.h>              /* fcntl(), F_GETFD, F_SETFD,
69
70
#define PDIR "/lib/mandos/plugins.d"
70
71
#define AFILE "/conf/conf.d/mandos/plugin-runner.conf"
71
72
 
72
 
const char *argp_program_version = "plugin-runner 1.0";
 
73
const char *argp_program_version = "plugin-runner " VERSION;
73
74
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
74
75
 
75
76
typedef struct plugin{
700
701
      
701
702
      const char const *bad_suffixes[] = { "~", "#", ".dpkg-new",
702
703
                                           ".dpkg-old",
 
704
                                           ".dpkg-bak",
703
705
                                           ".dpkg-divert", NULL };
704
706
      for(const char **pre = bad_prefixes; *pre != NULL; pre++){
705
707
        size_t pre_len = strlen(*pre);
846
848
        perror("sigaction");
847
849
        _exit(EXIT_FAILURE);
848
850
      }
849
 
      ret = sigprocmask (SIG_UNBLOCK, &sigchld_action.sa_mask, NULL);
 
851
      ret = sigprocmask(SIG_UNBLOCK, &sigchld_action.sa_mask, NULL);
850
852
      if(ret < 0){
851
853
        perror("sigprocmask");
852
854
        _exit(EXIT_FAILURE);
853
855
      }
854
 
 
 
856
      
855
857
      ret = dup2(pipefd[1], STDOUT_FILENO); /* replace our stdout */
856
858
      if(ret == -1){
857
859
        perror("dup2");
907
909
    if (maxfd < new_plugin->fd){
908
910
      maxfd = new_plugin->fd;
909
911
    }
910
 
    
911
912
  }
912
913
  
913
914
  closedir(dir);
914
915
  dir = NULL;
915
 
 
 
916
  
916
917
  for(plugin *p = plugin_list; p != NULL; p = p->next){
917
918
    if(p->pid != 0){
918
919
      break;
923
924
      free_plugin_list();
924
925
    }
925
926
  }
926
 
 
 
927
  
927
928
  /* Main loop while running plugins exist */
928
929
  while(plugin_list){
929
930
    fd_set rfds = rfds_all;
969
970
            goto fallback;
970
971
          }
971
972
          
 
973
          plugin *next_plugin = proc->next;
 
974
          free_plugin(proc);
 
975
          proc = next_plugin;
 
976
          
972
977
          /* We are done modifying process list, so unblock signal */
973
978
          ret = sigprocmask (SIG_UNBLOCK, &sigchld_action.sa_mask,
974
979
                             NULL);
982
987
            break;
983
988
          }
984
989
          
985
 
          plugin *next_plugin = proc->next;
986
 
          free_plugin(proc);
987
 
          proc = next_plugin;
988
990
          continue;
989
991
        }
990
992
        
991
993
        /* This process exited nicely, so print its buffer */
992
 
 
 
994
        
993
995
        bool bret = print_out_password(proc->buffer,
994
996
                                       proc->buffer_length);
995
997
        if(not bret){
1061
1063
    perror("sigaction");
1062
1064
    exitstatus = EXIT_FAILURE;
1063
1065
  }
1064
 
 
 
1066
  
1065
1067
  if(custom_argv != NULL){
1066
1068
    for(char **arg = custom_argv+1; *arg != NULL; arg++){
1067
1069
      free(*arg);
1073
1075
    closedir(dir);
1074
1076
  }
1075
1077
  
1076
 
  /* Free the process list and kill the processes */
 
1078
  /* Kill the processes */
1077
1079
  for(plugin *p = plugin_list; p != NULL; p = p->next){
1078
1080
    if(p->pid != 0){
1079
1081
      close(p->fd);
1092
1094
  if(errno != ECHILD){
1093
1095
    perror("wait");
1094
1096
  }
1095
 
 
 
1097
  
1096
1098
  free_plugin_list();
1097
1099
  
1098
1100
  free(plugindir);