/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: 2018-08-15 09:26:02 UTC
  • Revision ID: teddy@recompile.se-20180815092602-xoyb5s6gf8376i7u
mandos-client: Set system clock if necessary

* plugins.d/mandos-client.c (init_gpgme/import_key): If the system
  clock is not set, or set to january 1970, set the system clock to
  the more plausible value that is the mtime of the key file.  This is
  required by GnuPG to be able to import the keys.  (We can't pass the
  --ignore-time-conflict or the --ignore-valid-from options though
  GPGME.)

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-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
 
5
 * Copyright © 2008-2018 Teddy Hogeborn
 
6
 * Copyright © 2008-2018 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
14
16
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
18
 * General Public License for more details.
17
19
 * 
18
20
 * You should have received a copy of the GNU General Public License
19
 
 * along with this program.  If not, see
20
 
 * <http://www.gnu.org/licenses/>.
 
21
 * along with Mandos.  If not, see <http://www.gnu.org/licenses/>.
21
22
 * 
22
23
 * Contact the authors at <mandos@recompile.se>.
23
24
 */
82
83
  
83
84
  va_start(ap, formatstring);
84
85
  ret = vasprintf(&text, formatstring, ap);
85
 
  if (ret == -1){
 
86
  if(ret == -1){
86
87
    fprintf(stderr, "Mandos plugin %s: ",
87
88
            program_invocation_short_name);
88
89
    vfprintf(stderr, formatstring, ap);
89
 
    fprintf(stderr, ": ");
90
 
    fprintf(stderr, "%s\n", strerror(errnum));
 
90
    fprintf(stderr, ": %s\n", strerror(errnum));
91
91
    error(status, errno, "vasprintf while printing error");
92
92
    return;
93
93
  }
110
110
     from the terminal.  Password-prompt will exit if it detects
111
111
     plymouth since plymouth performs the same functionality.
112
112
   */
 
113
  __attribute__((nonnull))
113
114
  int is_plymouth(const struct dirent *proc_entry){
114
115
    int ret;
115
116
    int cl_fd;
116
117
    {
117
 
      uintmax_t maxvalue;
 
118
      uintmax_t proc_id;
118
119
      char *tmp;
119
120
      errno = 0;
120
 
      maxvalue = strtoumax(proc_entry->d_name, &tmp, 10);
 
121
      proc_id = strtoumax(proc_entry->d_name, &tmp, 10);
121
122
      
122
123
      if(errno != 0 or *tmp != '\0'
123
 
         or maxvalue != (uintmax_t)((pid_t)maxvalue)){
 
124
         or proc_id != (uintmax_t)((pid_t)proc_id)){
124
125
        return 0;
125
126
      }
126
127
    }
129
130
    ret = asprintf(&cmdline_filename, "/proc/%s/cmdline",
130
131
                   proc_entry->d_name);
131
132
    if(ret == -1){
132
 
      error(0, errno, "asprintf");
 
133
      error_plus(0, errno, "asprintf");
133
134
      return 0;
134
135
    }
135
136
    
138
139
    free(cmdline_filename);
139
140
    if(cl_fd == -1){
140
141
      if(errno != ENOENT){
141
 
        error(0, errno, "open");
 
142
        error_plus(0, errno, "open");
142
143
      }
143
144
      return 0;
144
145
    }
155
156
        if(cmdline_len + blocksize + 1 > cmdline_allocated){
156
157
          tmp = realloc(cmdline, cmdline_allocated + blocksize + 1);
157
158
          if(tmp == NULL){
158
 
            error(0, errno, "realloc");
 
159
            error_plus(0, errno, "realloc");
159
160
            free(cmdline);
160
161
            close(cl_fd);
161
162
            return 0;
168
169
        sret = read(cl_fd, cmdline + cmdline_len,
169
170
                    cmdline_allocated - cmdline_len);
170
171
        if(sret == -1){
171
 
          error(0, errno, "read");
 
172
          error_plus(0, errno, "read");
172
173
          free(cmdline);
173
174
          close(cl_fd);
174
175
          return 0;
177
178
      } while(sret != 0);
178
179
      ret = close(cl_fd);
179
180
      if(ret == -1){
180
 
        error(0, errno, "close");
 
181
        error_plus(0, errno, "close");
181
182
        free(cmdline);
182
183
        return 0;
183
184
      }
212
213
  struct dirent **direntries = NULL;
213
214
  int ret;
214
215
  ret = scandir("/proc", &direntries, is_plymouth, alphasort);
215
 
  if (ret == -1){
216
 
    error(1, errno, "scandir");
 
216
  if(ret == -1){
 
217
    error_plus(1, errno, "scandir");
 
218
  }
 
219
  {
 
220
    int i = ret;
 
221
    while(i--){
 
222
      free(direntries[i]);
 
223
    }
217
224
  }
218
225
  free(direntries);
219
226
  return ret > 0;
250
257
      { .name = NULL }
251
258
    };
252
259
    
 
260
    __attribute__((nonnull(3)))
253
261
    error_t parse_opt (int key, char *arg, struct argp_state *state){
254
262
      errno = 0;
255
263
      switch (key){
291
299
    case ENOMEM:
292
300
    default:
293
301
      errno = ret;
294
 
      error(0, errno, "argp_parse");
 
302
      error_plus(0, errno, "argp_parse");
295
303
      return EX_OSERR;
296
304
    case EINVAL:
297
305
      return EX_USAGE;
302
310
    fprintf(stderr, "Starting %s\n", argv[0]);
303
311
  }
304
312
 
305
 
  if (conflict_detection()){
 
313
  if(conflict_detection()){
306
314
    if(debug){
307
315
      fprintf(stderr, "Stopping %s because of conflict\n", argv[0]);
308
316
    }
315
323
  
316
324
  if(tcgetattr(STDIN_FILENO, &t_old) != 0){
317
325
    int e = errno;
318
 
    error(0, errno, "tcgetattr");
 
326
    error_plus(0, errno, "tcgetattr");
319
327
    switch(e){
320
328
    case EBADF:
321
329
    case ENOTTY:
328
336
  sigemptyset(&new_action.sa_mask);
329
337
  ret = sigaddset(&new_action.sa_mask, SIGINT);
330
338
  if(ret == -1){
331
 
    error(0, errno, "sigaddset");
 
339
    error_plus(0, errno, "sigaddset");
332
340
    return EX_OSERR;
333
341
  }
334
342
  ret = sigaddset(&new_action.sa_mask, SIGHUP);
335
343
  if(ret == -1){
336
 
    error(0, errno, "sigaddset");
 
344
    error_plus(0, errno, "sigaddset");
337
345
    return EX_OSERR;
338
346
  }
339
347
  ret = sigaddset(&new_action.sa_mask, SIGTERM);
340
348
  if(ret == -1){
341
 
    error(0, errno, "sigaddset");
 
349
    error_plus(0, errno, "sigaddset");
342
350
    return EX_OSERR;
343
351
  }
344
352
  /* Need to check if the handler is SIG_IGN before handling:
347
355
  */
348
356
  ret = sigaction(SIGINT, NULL, &old_action);
349
357
  if(ret == -1){
350
 
    error(0, errno, "sigaction");
 
358
    error_plus(0, errno, "sigaction");
351
359
    return EX_OSERR;
352
360
  }
353
361
  if(old_action.sa_handler != SIG_IGN){
354
362
    ret = sigaction(SIGINT, &new_action, NULL);
355
363
    if(ret == -1){
356
 
      error(0, errno, "sigaction");
 
364
      error_plus(0, errno, "sigaction");
357
365
      return EX_OSERR;
358
366
    }
359
367
  }
360
368
  ret = sigaction(SIGHUP, NULL, &old_action);
361
369
  if(ret == -1){
362
 
    error(0, errno, "sigaction");
 
370
    error_plus(0, errno, "sigaction");
363
371
    return EX_OSERR;
364
372
  }
365
373
  if(old_action.sa_handler != SIG_IGN){
366
374
    ret = sigaction(SIGHUP, &new_action, NULL);
367
375
    if(ret == -1){
368
 
      error(0, errno, "sigaction");
 
376
      error_plus(0, errno, "sigaction");
369
377
      return EX_OSERR;
370
378
    }
371
379
  }
372
380
  ret = sigaction(SIGTERM, NULL, &old_action);
373
381
  if(ret == -1){
374
 
    error(0, errno, "sigaction");
 
382
    error_plus(0, errno, "sigaction");
375
383
    return EX_OSERR;
376
384
  }
377
385
  if(old_action.sa_handler != SIG_IGN){
378
386
    ret = sigaction(SIGTERM, &new_action, NULL);
379
387
    if(ret == -1){
380
 
      error(0, errno, "sigaction");
 
388
      error_plus(0, errno, "sigaction");
381
389
      return EX_OSERR;
382
390
    }
383
391
  }
391
399
  t_new.c_lflag &= ~(tcflag_t)ECHO;
392
400
  if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_new) != 0){
393
401
    int e = errno;
394
 
    error(0, errno, "tcsetattr-echo");
 
402
    error_plus(0, errno, "tcsetattr-echo");
395
403
    switch(e){
396
404
    case EBADF:
397
405
    case ENOTTY:
461
469
        sret = write(STDOUT_FILENO, buffer + written, n - written);
462
470
        if(sret < 0){
463
471
          int e = errno;
464
 
          error(0, errno, "write");
 
472
          error_plus(0, errno, "write");
465
473
          switch(e){
466
474
          case EBADF:
467
475
          case EFAULT:
483
491
      sret = close(STDOUT_FILENO);
484
492
      if(sret == -1){
485
493
        int e = errno;
486
 
        error(0, errno, "close");
 
494
        error_plus(0, errno, "close");
487
495
        switch(e){
488
496
        case EBADF:
489
497
          status = EX_OSFILE;
499
507
    if(sret < 0){
500
508
      int e = errno;
501
509
      if(errno != EINTR and not feof(stdin)){
502
 
        error(0, errno, "getline");
 
510
        error_plus(0, errno, "getline");
503
511
        switch(e){
504
512
        case EBADF:
505
513
          status = EX_UNAVAILABLE;
 
514
          break;
506
515
        case EIO:
507
516
        case EINVAL:
508
517
        default:
528
537
    fprintf(stderr, "Restoring terminal attributes\n");
529
538
  }
530
539
  if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_old) != 0){
531
 
    error(0, errno, "tcsetattr+echo");
 
540
    error_plus(0, errno, "tcsetattr+echo");
532
541
  }
533
542
  
534
543
  if(quit_now){
536
545
    old_action.sa_handler = SIG_DFL;
537
546
    ret = sigaction(signal_received, &old_action, NULL);
538
547
    if(ret == -1){
539
 
      error(0, errno, "sigaction");
 
548
      error_plus(0, errno, "sigaction");
540
549
    }
541
550
    raise(signal_received);
542
551
  }