/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:
72
72
/* Needed for conflict resolution */
73
73
const char plymouth_name[] = "plymouthd";
74
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
 
75
85
/* Function to use when printing errors */
 
86
__attribute__((format (gnu_printf, 3, 4)))
76
87
void error_plus(int status, int errnum, const char *formatstring,
77
88
                ...){
78
89
  va_list ap;
85
96
    fprintf(stderr, "Mandos plugin %s: ",
86
97
            program_invocation_short_name);
87
98
    vfprintf(stderr, formatstring, ap);
88
 
    fprintf(stderr, ": ");
89
 
    fprintf(stderr, "%s\n", strerror(errnum));
 
99
    fprintf(stderr, ": %s\n", strerror(errnum));
90
100
    error(status, errno, "vasprintf while printing error");
91
101
    return;
92
102
  }
109
119
     from the terminal.  Password-prompt will exit if it detects
110
120
     plymouth since plymouth performs the same functionality.
111
121
   */
 
122
  __attribute__((nonnull))
112
123
  int is_plymouth(const struct dirent *proc_entry){
113
124
    int ret;
114
125
    int cl_fd;
115
126
    {
116
 
      uintmax_t maxvalue;
 
127
      uintmax_t proc_id;
117
128
      char *tmp;
118
129
      errno = 0;
119
 
      maxvalue = strtoumax(proc_entry->d_name, &tmp, 10);
 
130
      proc_id = strtoumax(proc_entry->d_name, &tmp, 10);
120
131
      
121
132
      if(errno != 0 or *tmp != '\0'
122
 
         or maxvalue != (uintmax_t)((pid_t)maxvalue)){
 
133
         or proc_id != (uintmax_t)((pid_t)proc_id)){
123
134
        return 0;
124
135
      }
125
136
    }
128
139
    ret = asprintf(&cmdline_filename, "/proc/%s/cmdline",
129
140
                   proc_entry->d_name);
130
141
    if(ret == -1){
131
 
      error(0, errno, "asprintf");
 
142
      error_plus(0, errno, "asprintf");
132
143
      return 0;
133
144
    }
134
145
    
137
148
    free(cmdline_filename);
138
149
    if(cl_fd == -1){
139
150
      if(errno != ENOENT){
140
 
        error(0, errno, "open");
 
151
        error_plus(0, errno, "open");
141
152
      }
142
153
      return 0;
143
154
    }
154
165
        if(cmdline_len + blocksize + 1 > cmdline_allocated){
155
166
          tmp = realloc(cmdline, cmdline_allocated + blocksize + 1);
156
167
          if(tmp == NULL){
157
 
            error(0, errno, "realloc");
 
168
            error_plus(0, errno, "realloc");
158
169
            free(cmdline);
159
170
            close(cl_fd);
160
171
            return 0;
167
178
        sret = read(cl_fd, cmdline + cmdline_len,
168
179
                    cmdline_allocated - cmdline_len);
169
180
        if(sret == -1){
170
 
          error(0, errno, "read");
 
181
          error_plus(0, errno, "read");
171
182
          free(cmdline);
172
183
          close(cl_fd);
173
184
          return 0;
176
187
      } while(sret != 0);
177
188
      ret = close(cl_fd);
178
189
      if(ret == -1){
179
 
        error(0, errno, "close");
 
190
        error_plus(0, errno, "close");
180
191
        free(cmdline);
181
192
        return 0;
182
193
      }
212
223
  int ret;
213
224
  ret = scandir("/proc", &direntries, is_plymouth, alphasort);
214
225
  if (ret == -1){
215
 
    error(1, errno, "scandir");
 
226
    error_plus(1, errno, "scandir");
216
227
  }
217
228
  free(direntries);
218
229
  return ret > 0;
249
260
      { .name = NULL }
250
261
    };
251
262
    
 
263
    __attribute__((nonnull(3)))
252
264
    error_t parse_opt (int key, char *arg, struct argp_state *state){
253
265
      errno = 0;
254
266
      switch (key){
290
302
    case ENOMEM:
291
303
    default:
292
304
      errno = ret;
293
 
      error(0, errno, "argp_parse");
 
305
      error_plus(0, errno, "argp_parse");
294
306
      return EX_OSERR;
295
307
    case EINVAL:
296
308
      return EX_USAGE;
314
326
  
315
327
  if(tcgetattr(STDIN_FILENO, &t_old) != 0){
316
328
    int e = errno;
317
 
    error(0, errno, "tcgetattr");
 
329
    error_plus(0, errno, "tcgetattr");
318
330
    switch(e){
319
331
    case EBADF:
320
332
    case ENOTTY:
327
339
  sigemptyset(&new_action.sa_mask);
328
340
  ret = sigaddset(&new_action.sa_mask, SIGINT);
329
341
  if(ret == -1){
330
 
    error(0, errno, "sigaddset");
 
342
    error_plus(0, errno, "sigaddset");
331
343
    return EX_OSERR;
332
344
  }
333
345
  ret = sigaddset(&new_action.sa_mask, SIGHUP);
334
346
  if(ret == -1){
335
 
    error(0, errno, "sigaddset");
 
347
    error_plus(0, errno, "sigaddset");
336
348
    return EX_OSERR;
337
349
  }
338
350
  ret = sigaddset(&new_action.sa_mask, SIGTERM);
339
351
  if(ret == -1){
340
 
    error(0, errno, "sigaddset");
 
352
    error_plus(0, errno, "sigaddset");
341
353
    return EX_OSERR;
342
354
  }
343
355
  /* Need to check if the handler is SIG_IGN before handling:
346
358
  */
347
359
  ret = sigaction(SIGINT, NULL, &old_action);
348
360
  if(ret == -1){
349
 
    error(0, errno, "sigaction");
 
361
    error_plus(0, errno, "sigaction");
350
362
    return EX_OSERR;
351
363
  }
352
364
  if(old_action.sa_handler != SIG_IGN){
353
365
    ret = sigaction(SIGINT, &new_action, NULL);
354
366
    if(ret == -1){
355
 
      error(0, errno, "sigaction");
 
367
      error_plus(0, errno, "sigaction");
356
368
      return EX_OSERR;
357
369
    }
358
370
  }
359
371
  ret = sigaction(SIGHUP, NULL, &old_action);
360
372
  if(ret == -1){
361
 
    error(0, errno, "sigaction");
 
373
    error_plus(0, errno, "sigaction");
362
374
    return EX_OSERR;
363
375
  }
364
376
  if(old_action.sa_handler != SIG_IGN){
365
377
    ret = sigaction(SIGHUP, &new_action, NULL);
366
378
    if(ret == -1){
367
 
      error(0, errno, "sigaction");
 
379
      error_plus(0, errno, "sigaction");
368
380
      return EX_OSERR;
369
381
    }
370
382
  }
371
383
  ret = sigaction(SIGTERM, NULL, &old_action);
372
384
  if(ret == -1){
373
 
    error(0, errno, "sigaction");
 
385
    error_plus(0, errno, "sigaction");
374
386
    return EX_OSERR;
375
387
  }
376
388
  if(old_action.sa_handler != SIG_IGN){
377
389
    ret = sigaction(SIGTERM, &new_action, NULL);
378
390
    if(ret == -1){
379
 
      error(0, errno, "sigaction");
 
391
      error_plus(0, errno, "sigaction");
380
392
      return EX_OSERR;
381
393
    }
382
394
  }
390
402
  t_new.c_lflag &= ~(tcflag_t)ECHO;
391
403
  if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_new) != 0){
392
404
    int e = errno;
393
 
    error(0, errno, "tcsetattr-echo");
 
405
    error_plus(0, errno, "tcsetattr-echo");
394
406
    switch(e){
395
407
    case EBADF:
396
408
    case ENOTTY:
460
472
        sret = write(STDOUT_FILENO, buffer + written, n - written);
461
473
        if(sret < 0){
462
474
          int e = errno;
463
 
          error(0, errno, "write");
 
475
          error_plus(0, errno, "write");
464
476
          switch(e){
465
477
          case EBADF:
466
478
          case EFAULT:
482
494
      sret = close(STDOUT_FILENO);
483
495
      if(sret == -1){
484
496
        int e = errno;
485
 
        error(0, errno, "close");
 
497
        error_plus(0, errno, "close");
486
498
        switch(e){
487
499
        case EBADF:
488
500
          status = EX_OSFILE;
498
510
    if(sret < 0){
499
511
      int e = errno;
500
512
      if(errno != EINTR and not feof(stdin)){
501
 
        error(0, errno, "getline");
 
513
        error_plus(0, errno, "getline");
502
514
        switch(e){
503
515
        case EBADF:
504
516
          status = EX_UNAVAILABLE;
 
517
          break;
505
518
        case EIO:
506
519
        case EINVAL:
507
520
        default:
527
540
    fprintf(stderr, "Restoring terminal attributes\n");
528
541
  }
529
542
  if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_old) != 0){
530
 
    error(0, errno, "tcsetattr+echo");
 
543
    error_plus(0, errno, "tcsetattr+echo");
531
544
  }
532
545
  
533
546
  if(quit_now){
535
548
    old_action.sa_handler = SIG_DFL;
536
549
    ret = sigaction(signal_received, &old_action, NULL);
537
550
    if(ret == -1){
538
 
      error(0, errno, "sigaction");
 
551
      error_plus(0, errno, "sigaction");
539
552
    }
540
553
    raise(signal_received);
541
554
  }