/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: 2015-07-20 03:03:33 UTC
  • Revision ID: teddy@recompile.se-20150720030333-203m2aeblypcsfte
Bug fix for GnuTLS 3: be compatible with old 2048-bit DSA keys.

The mandos-keygen program in Mandos version 1.6.0 and older generated
2048-bit DSA keys, and when GnuTLS uses these it has trouble
connecting using the Mandos default priority string.  This was
previously fixed in Mandos 1.6.2, but the bug reappeared when using
GnuTLS 3, so the default priority string has to change again; this
time also the Mandos client has to change its default, so now the
server and the client should use the same default priority string:

SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP:!RSA:+SIGN-DSA-SHA256

* mandos (main/server_defaults): Changed default priority string.
* mandos-options.xml (/section/para[id="priority_compat"]): Removed.
  (/section/para[id="priority"]): Changed default priority string.
* mandos.conf ([DEFAULT]/priority): - '' -
* mandos.conf.xml (OPTIONS/priority): Refer to the id "priority"
                                      instead of "priority_compat".
* mandos.xml (OPTIONS/--priority): - '' -
* plugins.d/mandos-client.c (main): Changed default priority string.

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-2010 Teddy Hogeborn
6
 
 * Copyright © 2008-2010 Björn Påhlsson
 
5
 * Copyright © 2008-2014 Teddy Hogeborn
 
6
 * Copyright © 2008-2014 Björn Påhlsson
7
7
 * 
8
8
 * This program is free software: you can redistribute it and/or
9
9
 * modify it under the terms of the GNU General Public License as
19
19
 * along with this program.  If not, see
20
20
 * <http://www.gnu.org/licenses/>.
21
21
 * 
22
 
 * Contact the authors at <mandos@fukt.bsnet.se>.
 
22
 * Contact the authors at <mandos@recompile.se>.
23
23
 */
24
24
 
25
25
#define _GNU_SOURCE             /* getline(), asprintf() */
41
41
                                   getenv(), free() */
42
42
#include <dirent.h>             /* scandir(), alphasort() */
43
43
#include <stdio.h>              /* fprintf(), stderr, getline(),
44
 
                                   stdin, feof(), fputc(), vfprintf(), vasprintf()
45
 
                                */
 
44
                                   stdin, feof(), fputc(), vfprintf(),
 
45
                                   vasprintf() */
46
46
#include <errno.h>              /* errno, EBADF, ENOTTY, EINVAL,
47
47
                                   EFAULT, EFBIG, EIO, ENOSPC, EINTR
48
48
                                */
51
51
#include <stdbool.h>            /* bool, false, true */
52
52
#include <inttypes.h>           /* strtoumax() */
53
53
#include <sys/stat.h>           /* struct stat, lstat(), open() */
54
 
#include <string.h>             /* strlen, rindex, memcmp, strerror() */
 
54
#include <string.h>             /* strlen, rindex, memcmp, strerror()
 
55
                                 */
55
56
#include <argp.h>               /* struct argp_option, struct
56
57
                                   argp_state, struct argp,
57
58
                                   argp_parse(), error_t,
66
67
int signal_received;
67
68
bool debug = false;
68
69
const char *argp_program_version = "password-prompt " VERSION;
69
 
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
 
70
const char *argp_program_bug_address = "<mandos@recompile.se>";
70
71
 
71
72
/* Needed for conflict resolution */
72
73
const char plymouth_name[] = "plymouthd";
73
74
 
74
75
/* Function to use when printing errors */
75
 
void error_plus(int status, int errnum, const char *formatstring, ...){
 
76
__attribute__((format (gnu_printf, 3, 4)))
 
77
void error_plus(int status, int errnum, const char *formatstring,
 
78
                ...){
76
79
  va_list ap;
77
80
  char *text;
78
81
  int ret;
79
82
  
80
83
  va_start(ap, formatstring);
81
84
  ret = vasprintf(&text, formatstring, ap);
82
 
  if (ret == -1){
83
 
    fprintf(stderr, "Mandos plugin %s: ", program_invocation_short_name);
 
85
  if(ret == -1){
 
86
    fprintf(stderr, "Mandos plugin %s: ",
 
87
            program_invocation_short_name);
84
88
    vfprintf(stderr, formatstring, ap);
85
 
    fprintf(stderr, ": ");
86
 
    fprintf(stderr, "%s\n", strerror(errnum));
 
89
    fprintf(stderr, ": %s\n", strerror(errnum));
87
90
    error(status, errno, "vasprintf while printing error");
88
91
    return;
89
92
  }
106
109
     from the terminal.  Password-prompt will exit if it detects
107
110
     plymouth since plymouth performs the same functionality.
108
111
   */
 
112
  __attribute__((nonnull))
109
113
  int is_plymouth(const struct dirent *proc_entry){
110
114
    int ret;
111
115
    int cl_fd;
112
116
    {
113
 
      uintmax_t maxvalue;
 
117
      uintmax_t proc_id;
114
118
      char *tmp;
115
119
      errno = 0;
116
 
      maxvalue = strtoumax(proc_entry->d_name, &tmp, 10);
 
120
      proc_id = strtoumax(proc_entry->d_name, &tmp, 10);
117
121
      
118
122
      if(errno != 0 or *tmp != '\0'
119
 
         or maxvalue != (uintmax_t)((pid_t)maxvalue)){
 
123
         or proc_id != (uintmax_t)((pid_t)proc_id)){
120
124
        return 0;
121
125
      }
122
126
    }
125
129
    ret = asprintf(&cmdline_filename, "/proc/%s/cmdline",
126
130
                   proc_entry->d_name);
127
131
    if(ret == -1){
128
 
      error(0, errno, "asprintf");
 
132
      error_plus(0, errno, "asprintf");
129
133
      return 0;
130
134
    }
131
135
    
134
138
    free(cmdline_filename);
135
139
    if(cl_fd == -1){
136
140
      if(errno != ENOENT){
137
 
        error(0, errno, "open");
 
141
        error_plus(0, errno, "open");
138
142
      }
139
143
      return 0;
140
144
    }
151
155
        if(cmdline_len + blocksize + 1 > cmdline_allocated){
152
156
          tmp = realloc(cmdline, cmdline_allocated + blocksize + 1);
153
157
          if(tmp == NULL){
154
 
            error(0, errno, "realloc");
 
158
            error_plus(0, errno, "realloc");
155
159
            free(cmdline);
156
160
            close(cl_fd);
157
161
            return 0;
164
168
        sret = read(cl_fd, cmdline + cmdline_len,
165
169
                    cmdline_allocated - cmdline_len);
166
170
        if(sret == -1){
167
 
          error(0, errno, "read");
 
171
          error_plus(0, errno, "read");
168
172
          free(cmdline);
169
173
          close(cl_fd);
170
174
          return 0;
173
177
      } while(sret != 0);
174
178
      ret = close(cl_fd);
175
179
      if(ret == -1){
176
 
        error(0, errno, "close");
 
180
        error_plus(0, errno, "close");
177
181
        free(cmdline);
178
182
        return 0;
179
183
      }
205
209
    return 1;
206
210
  }
207
211
  
208
 
  struct dirent **direntries;
 
212
  struct dirent **direntries = NULL;
209
213
  int ret;
210
214
  ret = scandir("/proc", &direntries, is_plymouth, alphasort);
211
 
  if (ret == -1){
212
 
    error(1, errno, "scandir");
 
215
  if(ret == -1){
 
216
    error_plus(1, errno, "scandir");
213
217
  }
 
218
  free(direntries);
214
219
  return ret > 0;
215
220
}
216
221
 
245
250
      { .name = NULL }
246
251
    };
247
252
    
 
253
    __attribute__((nonnull(3)))
248
254
    error_t parse_opt (int key, char *arg, struct argp_state *state){
249
255
      errno = 0;
250
256
      switch (key){
286
292
    case ENOMEM:
287
293
    default:
288
294
      errno = ret;
289
 
      error(0, errno, "argp_parse");
 
295
      error_plus(0, errno, "argp_parse");
290
296
      return EX_OSERR;
291
297
    case EINVAL:
292
298
      return EX_USAGE;
297
303
    fprintf(stderr, "Starting %s\n", argv[0]);
298
304
  }
299
305
 
300
 
  if (conflict_detection()){
 
306
  if(conflict_detection()){
301
307
    if(debug){
302
308
      fprintf(stderr, "Stopping %s because of conflict\n", argv[0]);
303
309
    }
310
316
  
311
317
  if(tcgetattr(STDIN_FILENO, &t_old) != 0){
312
318
    int e = errno;
313
 
    error(0, errno, "tcgetattr");
 
319
    error_plus(0, errno, "tcgetattr");
314
320
    switch(e){
315
321
    case EBADF:
316
322
    case ENOTTY:
323
329
  sigemptyset(&new_action.sa_mask);
324
330
  ret = sigaddset(&new_action.sa_mask, SIGINT);
325
331
  if(ret == -1){
326
 
    error(0, errno, "sigaddset");
 
332
    error_plus(0, errno, "sigaddset");
327
333
    return EX_OSERR;
328
334
  }
329
335
  ret = sigaddset(&new_action.sa_mask, SIGHUP);
330
336
  if(ret == -1){
331
 
    error(0, errno, "sigaddset");
 
337
    error_plus(0, errno, "sigaddset");
332
338
    return EX_OSERR;
333
339
  }
334
340
  ret = sigaddset(&new_action.sa_mask, SIGTERM);
335
341
  if(ret == -1){
336
 
    error(0, errno, "sigaddset");
 
342
    error_plus(0, errno, "sigaddset");
337
343
    return EX_OSERR;
338
344
  }
339
345
  /* Need to check if the handler is SIG_IGN before handling:
342
348
  */
343
349
  ret = sigaction(SIGINT, NULL, &old_action);
344
350
  if(ret == -1){
345
 
    error(0, errno, "sigaction");
 
351
    error_plus(0, errno, "sigaction");
346
352
    return EX_OSERR;
347
353
  }
348
354
  if(old_action.sa_handler != SIG_IGN){
349
355
    ret = sigaction(SIGINT, &new_action, NULL);
350
356
    if(ret == -1){
351
 
      error(0, errno, "sigaction");
 
357
      error_plus(0, errno, "sigaction");
352
358
      return EX_OSERR;
353
359
    }
354
360
  }
355
361
  ret = sigaction(SIGHUP, NULL, &old_action);
356
362
  if(ret == -1){
357
 
    error(0, errno, "sigaction");
 
363
    error_plus(0, errno, "sigaction");
358
364
    return EX_OSERR;
359
365
  }
360
366
  if(old_action.sa_handler != SIG_IGN){
361
367
    ret = sigaction(SIGHUP, &new_action, NULL);
362
368
    if(ret == -1){
363
 
      error(0, errno, "sigaction");
 
369
      error_plus(0, errno, "sigaction");
364
370
      return EX_OSERR;
365
371
    }
366
372
  }
367
373
  ret = sigaction(SIGTERM, NULL, &old_action);
368
374
  if(ret == -1){
369
 
    error(0, errno, "sigaction");
 
375
    error_plus(0, errno, "sigaction");
370
376
    return EX_OSERR;
371
377
  }
372
378
  if(old_action.sa_handler != SIG_IGN){
373
379
    ret = sigaction(SIGTERM, &new_action, NULL);
374
380
    if(ret == -1){
375
 
      error(0, errno, "sigaction");
 
381
      error_plus(0, errno, "sigaction");
376
382
      return EX_OSERR;
377
383
    }
378
384
  }
386
392
  t_new.c_lflag &= ~(tcflag_t)ECHO;
387
393
  if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_new) != 0){
388
394
    int e = errno;
389
 
    error(0, errno, "tcsetattr-echo");
 
395
    error_plus(0, errno, "tcsetattr-echo");
390
396
    switch(e){
391
397
    case EBADF:
392
398
    case ENOTTY:
456
462
        sret = write(STDOUT_FILENO, buffer + written, n - written);
457
463
        if(sret < 0){
458
464
          int e = errno;
459
 
          error(0, errno, "write");
 
465
          error_plus(0, errno, "write");
460
466
          switch(e){
461
467
          case EBADF:
462
468
          case EFAULT:
478
484
      sret = close(STDOUT_FILENO);
479
485
      if(sret == -1){
480
486
        int e = errno;
481
 
        error(0, errno, "close");
 
487
        error_plus(0, errno, "close");
482
488
        switch(e){
483
489
        case EBADF:
484
490
          status = EX_OSFILE;
494
500
    if(sret < 0){
495
501
      int e = errno;
496
502
      if(errno != EINTR and not feof(stdin)){
497
 
        error(0, errno, "getline");
 
503
        error_plus(0, errno, "getline");
498
504
        switch(e){
499
505
        case EBADF:
500
506
          status = EX_UNAVAILABLE;
 
507
          break;
501
508
        case EIO:
502
509
        case EINVAL:
503
510
        default:
523
530
    fprintf(stderr, "Restoring terminal attributes\n");
524
531
  }
525
532
  if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_old) != 0){
526
 
    error(0, errno, "tcsetattr+echo");
 
533
    error_plus(0, errno, "tcsetattr+echo");
527
534
  }
528
535
  
529
536
  if(quit_now){
531
538
    old_action.sa_handler = SIG_DFL;
532
539
    ret = sigaction(signal_received, &old_action, NULL);
533
540
    if(ret == -1){
534
 
      error(0, errno, "sigaction");
 
541
      error_plus(0, errno, "sigaction");
535
542
    }
536
543
    raise(signal_received);
537
544
  }