/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-prompt.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:
33
33
                                   sigaction, sigemptyset(),
34
34
                                   sigaction(), sigaddset(), SIGINT,
35
35
                                   SIGQUIT, SIGHUP, SIGTERM */
36
 
#include <stddef.h>             /* NULL, size_t */
 
36
#include <stddef.h>             /* NULL, size_t, ssize_t */
37
37
#include <sys/types.h>          /* ssize_t */
38
38
#include <stdlib.h>             /* EXIT_SUCCESS, EXIT_FAILURE,
39
39
                                   getopt_long */
44
44
#include <iso646.h>             /* or, not */
45
45
#include <stdbool.h>            /* bool, false, true */
46
46
#include <string.h>             /* strlen, rindex, strncmp, strcmp */
47
 
#include <getopt.h>             /* getopt_long */
 
47
#include <argp.h>               /* struct argp_option, struct
 
48
                                   argp_state, struct argp,
 
49
                                   argp_parse(), error_t,
 
50
                                   ARGP_KEY_ARG, ARGP_KEY_END,
 
51
                                   ARGP_ERR_UNKNOWN */
48
52
 
49
53
volatile bool quit_now = false;
50
54
bool debug = false;
 
55
const char *argp_program_version = "password-prompt 1.0";
 
56
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
51
57
 
52
58
static void termination_handler(__attribute__((unused))int signum){
53
59
  quit_now = true;
63
69
  struct sigaction old_action,
64
70
    new_action = { .sa_handler = termination_handler,
65
71
                   .sa_flags = 0 };
66
 
 
67
 
  while (true){
68
 
    static struct option long_options[] = {
69
 
      {"debug", no_argument, (int *)&debug, 1},
70
 
      {"prefix", required_argument, 0, 'p'},
71
 
      {0, 0, 0, 0} };
72
 
 
73
 
    int option_index = 0;
74
 
    ret = getopt_long (argc, argv, "p:", long_options, &option_index);
75
 
 
76
 
    if (ret == -1){
77
 
      break;
 
72
  {
 
73
    struct argp_option options[] = {
 
74
      { .name = "prefix", .key = 'p',
 
75
        .arg = "PREFIX", .flags = 0,
 
76
        .doc = "Prefix used before the passprompt", .group = 2 },
 
77
      { .name = "debug", .key = 128,
 
78
        .doc = "Debug mode", .group = 3 },
 
79
      { .name = NULL }
 
80
    };
 
81
  
 
82
    error_t parse_opt (int key, char *arg, struct argp_state *state) {
 
83
      /* Get the INPUT argument from `argp_parse', which we know is a
 
84
         pointer to our plugin list pointer. */
 
85
      switch (key) {
 
86
      case 'p':
 
87
        prefix = arg;
 
88
        break;
 
89
      case 128:
 
90
        debug = true;
 
91
        break;
 
92
      case ARGP_KEY_ARG:
 
93
        argp_usage (state);
 
94
        break;
 
95
      case ARGP_KEY_END:
 
96
        break;
 
97
      default:
 
98
        return ARGP_ERR_UNKNOWN;
 
99
      }
 
100
      return 0;
78
101
    }
79
 
      
80
 
    switch(ret){
81
 
    case 0:
82
 
      break;
83
 
    case 'p':
84
 
      prefix = optarg;
85
 
      break;
86
 
    default:
87
 
      fprintf(stderr, "bad arguments\n");
88
 
      exit(EXIT_FAILURE);
 
102
  
 
103
    struct argp argp = { .options = options, .parser = parse_opt,
 
104
                         .args_doc = "",
 
105
                         .doc = "Mandos Passprompt -- Provides a passprompt" };
 
106
    ret = argp_parse (&argp, argc, argv, 0, 0, NULL);
 
107
    if (ret == ARGP_ERR_UNKNOWN){
 
108
      fprintf(stderr, "Unknown error while parsing arguments\n");
 
109
      return EXIT_FAILURE;
89
110
    }
90
111
  }
91
 
      
 
112
    
92
113
  if (debug){
93
114
    fprintf(stderr, "Starting %s\n", argv[0]);
94
115
  }
104
125
  sigaddset(&new_action.sa_mask, SIGINT);
105
126
  sigaddset(&new_action.sa_mask, SIGHUP);
106
127
  sigaddset(&new_action.sa_mask, SIGTERM);
107
 
  sigaction(SIGINT, NULL, &old_action);
108
 
  if (old_action.sa_handler != SIG_IGN)
109
 
    sigaction(SIGINT, &new_action, NULL);
110
 
  sigaction(SIGHUP, NULL, &old_action);
111
 
  if (old_action.sa_handler != SIG_IGN)
112
 
    sigaction(SIGHUP, &new_action, NULL);
113
 
  sigaction(SIGTERM, NULL, &old_action);
114
 
  if (old_action.sa_handler != SIG_IGN)
115
 
    sigaction(SIGTERM, &new_action, NULL);
116
 
 
 
128
  ret = sigaction(SIGINT, NULL, &old_action);
 
129
  if(ret == -1){
 
130
    perror("sigaction");
 
131
    return EXIT_FAILURE;
 
132
  }
 
133
  if (old_action.sa_handler != SIG_IGN){
 
134
    ret = sigaction(SIGINT, &new_action, NULL);
 
135
    if(ret == -1){
 
136
      perror("sigaction");
 
137
      return EXIT_FAILURE;
 
138
    }
 
139
  }
 
140
  ret = sigaction(SIGHUP, NULL, &old_action);
 
141
  if(ret == -1){
 
142
    perror("sigaction");
 
143
    return EXIT_FAILURE;
 
144
  }
 
145
  if (old_action.sa_handler != SIG_IGN){
 
146
    ret = sigaction(SIGHUP, &new_action, NULL);
 
147
    if(ret == -1){
 
148
      perror("sigaction");
 
149
      return EXIT_FAILURE;
 
150
    }
 
151
  }
 
152
  ret = sigaction(SIGTERM, NULL, &old_action);
 
153
  if(ret == -1){
 
154
    perror("sigaction");
 
155
    return EXIT_FAILURE;
 
156
  }
 
157
  if (old_action.sa_handler != SIG_IGN){
 
158
    ret = sigaction(SIGTERM, &new_action, NULL);
 
159
    if(ret == -1){
 
160
      perror("sigaction");
 
161
      return EXIT_FAILURE;
 
162
    }
 
163
  }
 
164
  
117
165
  
118
166
  if (debug){
119
167
    fprintf(stderr, "Removing echo flag from terminal attributes\n");
146
194
      status = EXIT_SUCCESS;
147
195
      break;
148
196
    }
149
 
    // ret == 0 makes no other sence than to retry to read from stdin
150
197
    if (ret < 0){
151
198
      if (errno != EINTR and not feof(stdin)){
152
199
        perror("getline");
154
201
        break;
155
202
      }
156
203
    }
 
204
    /* if(ret == 0), then the only sensible thing to do is to retry to
 
205
       read from stdin */
157
206
    fputc('\n', stderr);
158
207
  }
159
 
 
 
208
  
160
209
  if (debug){
161
210
    fprintf(stderr, "Restoring terminal attributes\n");
162
211
  }
163
212
  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_old) != 0){
164
213
    perror("tcsetattr+echo");
165
214
  }
166
 
 
 
215
  
167
216
  if (debug){
168
217
    fprintf(stderr, "%s is exiting\n", argv[0]);
169
218
  }