/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
 
      size_t written = 0;
220
 
      while(written < n){
221
 
        ret = write(STDOUT_FILENO, buffer + written, n - written);
222
 
        if(ret < 0){
223
 
          perror("write");
224
 
          status = EXIT_FAILURE;
225
 
          break;
226
 
        }
227
 
        written += (size_t)ret;
228
 
      }
229
195
      break;
230
196
    }
231
197
    if (ret < 0){
238
204
    /* if(ret == 0), then the only sensible thing to do is to retry to
239
205
       read from stdin */
240
206
    fputc('\n', stderr);
241
 
    if(debug and not quit_now){
242
 
      /* If quit_now is true, we were interrupted by a signal, and
243
 
         will print that later, so no need to show this too. */
244
 
      fprintf(stderr, "getline() returned 0, retrying.\n");
245
 
    }
246
207
  }
247
208
  
248
209
  if (debug){
253
214
  }
254
215
  
255
216
  if (debug){
256
 
    fprintf(stderr, "%s is exiting with status %d\n", argv[0],
257
 
            status);
 
217
    fprintf(stderr, "%s is exiting\n", argv[0]);
258
218
  }
259
219
  
260
220
  return status;