/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:
36
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
 
                                   getopt_long, getenv() */
 
39
                                   getopt_long */
40
40
#include <stdio.h>              /* fprintf(), stderr, getline(),
41
41
                                   stdin, feof(), perror(), fputc(),
42
42
                                   stdout, getopt_long */
73
73
    struct argp_option options[] = {
74
74
      { .name = "prefix", .key = 'p',
75
75
        .arg = "PREFIX", .flags = 0,
76
 
        .doc = "Prefix shown before the prompt", .group = 2 },
 
76
        .doc = "Prefix used before the passprompt", .group = 2 },
77
77
      { .name = "debug", .key = 128,
78
78
        .doc = "Debug mode", .group = 3 },
79
79
      { .name = NULL }
102
102
  
103
103
    struct argp argp = { .options = options, .parser = parse_opt,
104
104
                         .args_doc = "",
105
 
                         .doc = "Mandos password-prompt -- Read and"
106
 
                         " output a password" };
 
105
                         .doc = "Mandos Passprompt -- Provides a passprompt" };
107
106
    ret = argp_parse (&argp, argc, argv, 0, 0, NULL);
108
107
    if (ret == ARGP_ERR_UNKNOWN){
109
108
      fprintf(stderr, "Unknown error while parsing arguments\n");
119
118
  }
120
119
  
121
120
  if (tcgetattr(STDIN_FILENO, &t_old) != 0){
122
 
    perror("tcgetattr");
123
121
    return EXIT_FAILURE;
124
122
  }
125
123
  
181
179
  }
182
180
  while(true){
183
181
    if (quit_now){
184
 
      if(debug){
185
 
        fprintf(stderr, "Interrupted by signal, exiting.\n");
186
 
      }
187
182
      status = EXIT_FAILURE;
188
183
      break;
189
184
    }
190
185
 
191
186
    if(prefix){
192
 
      fprintf(stderr, "%s ", prefix);
193
 
    }
194
 
    {
195
 
      const char *cryptsource = getenv("cryptsource");
196
 
      const char *crypttarget = getenv("crypttarget");
197
 
      const char *const prompt
198
 
        = "Enter passphrase to unlock the disk";
199
 
      if(cryptsource == NULL){
200
 
        if(crypttarget == NULL){
201
 
          fprintf(stderr, "%s: ", prompt);
202
 
        } else {
203
 
          fprintf(stderr, "%s (%s): ", prompt, crypttarget);
204
 
        }
205
 
      } else {
206
 
        if(crypttarget == NULL){
207
 
          fprintf(stderr, "%s %s: ", prompt, cryptsource);
208
 
        } else {
209
 
          fprintf(stderr, "%s %s (%s): ", prompt, cryptsource,
210
 
                  crypttarget);
211
 
        }
212
 
      }
213
 
    }
 
187
      fprintf(stderr, "%s Password: ", prefix);
 
188
    } else {
 
189
      fprintf(stderr, "Password: ");
 
190
    }      
214
191
    ret = getline(&buffer, &n, stdin);
215
192
    if (ret > 0){
 
193
      fprintf(stdout, "%s", buffer);
216
194
      status = EXIT_SUCCESS;
217
 
      /* Make n = data size instead of allocated buffer size */
218
 
      n = (size_t)ret;
219
 
      /* Strip final newline */
220
 
      if(n>0 and buffer[n-1] == '\n'){
221
 
        buffer[n-1] = '\0';     /* not strictly necessary */
222
 
        n--;
223
 
      }
224
 
      size_t written = 0;
225
 
      while(written < n){
226
 
        ret = write(STDOUT_FILENO, buffer + written, n - written);
227
 
        if(ret < 0){
228
 
          perror("write");
229
 
          status = EXIT_FAILURE;
230
 
          break;
231
 
        }
232
 
        written += (size_t)ret;
233
 
      }
234
195
      break;
235
196
    }
236
197
    if (ret < 0){
243
204
    /* if(ret == 0), then the only sensible thing to do is to retry to
244
205
       read from stdin */
245
206
    fputc('\n', stderr);
246
 
    if(debug and not quit_now){
247
 
      /* If quit_now is true, we were interrupted by a signal, and
248
 
         will print that later, so no need to show this too. */
249
 
      fprintf(stderr, "getline() returned 0, retrying.\n");
250
 
    }
251
207
  }
252
 
 
253
 
  free(buffer);
254
208
  
255
209
  if (debug){
256
210
    fprintf(stderr, "Restoring terminal attributes\n");
260
214
  }
261
215
  
262
216
  if (debug){
263
 
    fprintf(stderr, "%s is exiting with status %d\n", argv[0],
264
 
            status);
265
 
  }
266
 
  if(status == EXIT_SUCCESS){
267
 
    fputc('\n', stderr);
 
217
    fprintf(stderr, "%s is exiting\n", argv[0]);
268
218
  }
269
219
  
270
220
  return status;