/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: 2011-12-31 20:07:11 UTC
  • mfrom: (535.1.9 wireless-network-hook)
  • Revision ID: teddy@recompile.se-20111231200711-6dli3r8drftem57r
Merge new wireless network hook.  Fix bridge network hook to use
hardware addresses instead of interface names.  Implement and document
new "CONNECT" environment variable for network hooks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
/*
3
3
 * Password-prompt - Read a password from the terminal and print it
4
4
 * 
5
 
 * Copyright © 2008-2019 Teddy Hogeborn
6
 
 * Copyright © 2008-2019 Björn Påhlsson
7
 
 * 
8
 
 * This file is part of Mandos.
9
 
 * 
10
 
 * Mandos is free software: you can redistribute it and/or modify it
11
 
 * under the terms of the GNU General Public License as published by
12
 
 * the Free Software Foundation, either version 3 of the License, or
13
 
 * (at your option) any later version.
14
 
 * 
15
 
 * Mandos is distributed in the hope that it will be useful, but
 
5
 * Copyright © 2008-2011 Teddy Hogeborn
 
6
 * Copyright © 2008-2011 Björn Påhlsson
 
7
 * 
 
8
 * This program is free software: you can redistribute it and/or
 
9
 * modify it under the terms of the GNU General Public License as
 
10
 * published by the Free Software Foundation, either version 3 of the
 
11
 * License, or (at your option) any later version.
 
12
 * 
 
13
 * This program is distributed in the hope that it will be useful, but
16
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
17
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
16
 * General Public License for more details.
19
17
 * 
20
18
 * You should have received a copy of the GNU General Public License
21
 
 * along with Mandos.  If not, see <http://www.gnu.org/licenses/>.
 
19
 * along with this program.  If not, see
 
20
 * <http://www.gnu.org/licenses/>.
22
21
 * 
23
22
 * Contact the authors at <mandos@recompile.se>.
24
23
 */
27
26
 
28
27
#include <termios.h>            /* struct termios, tcsetattr(),
29
28
                                   TCSAFLUSH, tcgetattr(), ECHO */
30
 
#include <unistd.h>             /* access(), struct termios,
31
 
                                   tcsetattr(), STDIN_FILENO,
32
 
                                   TCSAFLUSH, tcgetattr(), ECHO,
33
 
                                   readlink() */
 
29
#include <unistd.h>             /* struct termios, tcsetattr(),
 
30
                                   STDIN_FILENO, TCSAFLUSH,
 
31
                                   tcgetattr(), ECHO, readlink() */
34
32
#include <signal.h>             /* sig_atomic_t, raise(), struct
35
33
                                   sigaction, sigemptyset(),
36
34
                                   sigaction(), sigaddset(), SIGINT,
74
72
/* Needed for conflict resolution */
75
73
const char plymouth_name[] = "plymouthd";
76
74
 
 
75
__attribute__((format (gnu_printf, 2, 3), nonnull(1)))
 
76
int fprintf_plus(FILE *stream, const char *format, ...){
 
77
  va_list ap;
 
78
  va_start (ap, format);
 
79
  
 
80
  TEMP_FAILURE_RETRY(fprintf(stream, "Mandos plugin %s: ",
 
81
                             program_invocation_short_name));
 
82
  return TEMP_FAILURE_RETRY(vfprintf(stream, format, ap));
 
83
}
 
84
 
77
85
/* Function to use when printing errors */
78
86
__attribute__((format (gnu_printf, 3, 4)))
79
87
void error_plus(int status, int errnum, const char *formatstring,
84
92
  
85
93
  va_start(ap, formatstring);
86
94
  ret = vasprintf(&text, formatstring, ap);
87
 
  if(ret == -1){
 
95
  if (ret == -1){
88
96
    fprintf(stderr, "Mandos plugin %s: ",
89
97
            program_invocation_short_name);
90
98
    vfprintf(stderr, formatstring, ap);
111
119
     from the terminal.  Password-prompt will exit if it detects
112
120
     plymouth since plymouth performs the same functionality.
113
121
   */
114
 
  if(access("/run/plymouth/pid", R_OK) == 0){
115
 
    return true;
116
 
  }
117
 
  
118
122
  __attribute__((nonnull))
119
123
  int is_plymouth(const struct dirent *proc_entry){
120
124
    int ret;
218
222
  struct dirent **direntries = NULL;
219
223
  int ret;
220
224
  ret = scandir("/proc", &direntries, is_plymouth, alphasort);
221
 
  if(ret == -1){
 
225
  if (ret == -1){
222
226
    error_plus(1, errno, "scandir");
223
227
  }
224
 
  {
225
 
    int i = ret;
226
 
    while(i--){
227
 
      free(direntries[i]);
228
 
    }
229
 
  }
230
228
  free(direntries);
231
229
  return ret > 0;
232
230
}
239
237
  struct termios t_new, t_old;
240
238
  char *buffer = NULL;
241
239
  char *prefix = NULL;
242
 
  char *prompt = NULL;
243
240
  int status = EXIT_SUCCESS;
244
241
  struct sigaction old_action,
245
242
    new_action = { .sa_handler = termination_handler,
249
246
      { .name = "prefix", .key = 'p',
250
247
        .arg = "PREFIX", .flags = 0,
251
248
        .doc = "Prefix shown before the prompt", .group = 2 },
252
 
      { .name = "prompt", .key = 129,
253
 
        .arg = "PROMPT", .flags = 0,
254
 
        .doc = "The prompt to show", .group = 2 },
255
249
      { .name = "debug", .key = 128,
256
250
        .doc = "Debug mode", .group = 3 },
257
251
      /*
270
264
    error_t parse_opt (int key, char *arg, struct argp_state *state){
271
265
      errno = 0;
272
266
      switch (key){
273
 
      case 'p':                 /* --prefix */
 
267
      case 'p':
274
268
        prefix = arg;
275
269
        break;
276
 
      case 128:                 /* --debug */
 
270
      case 128:
277
271
        debug = true;
278
272
        break;
279
 
      case 129:                 /* --prompt */
280
 
        prompt = arg;
281
 
        break;
282
273
        /*
283
274
         * These reproduce what we would get without ARGP_NO_HELP
284
275
         */
286
277
        argp_state_help(state, state->out_stream,
287
278
                        (ARGP_HELP_STD_HELP | ARGP_HELP_EXIT_ERR)
288
279
                        & ~(unsigned int)ARGP_HELP_EXIT_OK);
289
 
        __builtin_unreachable();
290
280
      case -3:                  /* --usage */
291
281
        argp_state_help(state, state->out_stream,
292
282
                        ARGP_HELP_USAGE | ARGP_HELP_EXIT_ERR);
293
 
        __builtin_unreachable();
294
283
      case 'V':                 /* --version */
295
284
        fprintf(state->out_stream, "%s\n", argp_program_version);
296
285
        exit(argp_err_exit_status);
324
313
    fprintf(stderr, "Starting %s\n", argv[0]);
325
314
  }
326
315
 
327
 
  if(conflict_detection()){
 
316
  if (conflict_detection()){
328
317
    if(debug){
329
318
      fprintf(stderr, "Stopping %s because of conflict\n", argv[0]);
330
319
    }
439
428
    if(prefix){
440
429
      fprintf(stderr, "%s ", prefix);
441
430
    }
442
 
    if(prompt != NULL){
443
 
      fprintf(stderr, "%s: ", prompt);
444
 
    } else {
 
431
    {
445
432
      const char *cryptsource = getenv("CRYPTTAB_SOURCE");
446
433
      const char *crypttarget = getenv("CRYPTTAB_NAME");
447
434
      /* Before cryptsetup 1.1.0~rc2 */
522
509
    }
523
510
    if(sret < 0){
524
511
      int e = errno;
525
 
      if(errno != EINTR){
526
 
        if(not feof(stdin)){
527
 
          error_plus(0, errno, "getline");
528
 
          switch(e){
529
 
          case EBADF:
530
 
            status = EX_UNAVAILABLE;
531
 
            break;
532
 
          case EIO:
533
 
          case EINVAL:
534
 
          default:
535
 
            status = EX_IOERR;
536
 
            break;
537
 
          }
538
 
          break;
539
 
        } else {
540
 
          clearerr(stdin);
 
512
      if(errno != EINTR and not feof(stdin)){
 
513
        error_plus(0, errno, "getline");
 
514
        switch(e){
 
515
        case EBADF:
 
516
          status = EX_UNAVAILABLE;
 
517
          break;
 
518
        case EIO:
 
519
        case EINVAL:
 
520
        default:
 
521
          status = EX_IOERR;
 
522
          break;
541
523
        }
 
524
        break;
542
525
      }
543
526
    }
544
527
    /* if(sret == 0), then the only sensible thing to do is to retry