/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/splashy.c

  • Committer: Teddy Hogeborn
  • Date: 2015-03-10 18:03:38 UTC
  • Revision ID: teddy@recompile.se-20150310180338-pcxw6r2qmw9k6br9
Add ":!RSA" to GnuTLS priority string, to disallow non-DHE kx.

If Mandos was somehow made to use a non-ephemeral Diffie-Hellman key
exchange algorithm in the TLS handshake, any saved network traffic
could then be decrypted later if the Mandos client key was obtained.
By default, Mandos uses ephemeral DH key exchanges which does not have
this problem, but a non-ephemeral key exchange algorithm was still
enabled by default.  The simplest solution is to simply turn that off,
which ensures that Mandos will always use ephemeral DH key exchanges.

There is a "PFS" priority string specifier, but we can't use it because:

1. Security-wise, it is a mix between "NORMAL" and "SECURE128" - it
   enables a lot more algorithms than "SECURE256".

2. It is only available since GnuTLS 3.2.4.

Thanks to Andreas Fischer <af@bantuX.org> for reporting this issue.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
/*
3
3
 * Splashy - Read a password from splashy and output it
4
4
 * 
5
 
 * Copyright © 2008-2011 Teddy Hogeborn
6
 
 * Copyright © 2008-2011 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             /* TEMP_FAILURE_RETRY(), asprintf() */
29
29
                                   SIG_IGN, kill(), SIGKILL */
30
30
#include <stddef.h>             /* NULL */
31
31
#include <stdlib.h>             /* getenv() */
32
 
#include <stdio.h>              /* asprintf() */
 
32
#include <stdio.h>              /* asprintf(), vasprintf(), vprintf(),
 
33
                                   fprintf() */
33
34
#include <stdlib.h>             /* EXIT_FAILURE, free(),
34
35
                                   EXIT_SUCCESS */
35
36
#include <sys/types.h>          /* pid_t, DIR, struct dirent,
42
43
                                   sleep(), dup2() STDERR_FILENO,
43
44
                                   STDOUT_FILENO, _exit(),
44
45
                                   pause() */
45
 
#include <string.h>             /* memcmp() */
 
46
#include <string.h>             /* memcmp(), strerror() */
46
47
#include <errno.h>              /* errno, EACCES, ENOTDIR, ELOOP,
47
48
                                   ENOENT, ENAMETOOLONG, EMFILE,
48
49
                                   ENFILE, ENOMEM, ENOEXEC, EINVAL,
54
55
                                   WEXITSTATUS() */
55
56
#include <sysexits.h>           /* EX_OSERR, EX_OSFILE,
56
57
                                   EX_UNAVAILABLE */
 
58
#include <stdarg.h>             /* va_list, va_start(), ... */
57
59
 
58
60
sig_atomic_t interrupted_by_signal = 0;
59
61
int signal_received;
60
62
 
 
63
/* Function to use when printing errors */
 
64
__attribute__((format (gnu_printf, 3, 4)))
 
65
void error_plus(int status, int errnum, const char *formatstring,
 
66
                ...){
 
67
  va_list ap;
 
68
  char *text;
 
69
  int ret;
 
70
  
 
71
  va_start(ap, formatstring);
 
72
  ret = vasprintf(&text, formatstring, ap);
 
73
  if(ret == -1){
 
74
    fprintf(stderr, "Mandos plugin %s: ",
 
75
            program_invocation_short_name);
 
76
    vfprintf(stderr, formatstring, ap);
 
77
    fprintf(stderr, ": ");
 
78
    fprintf(stderr, "%s\n", strerror(errnum));
 
79
    error(status, errno, "vasprintf while printing error");
 
80
    return;
 
81
  }
 
82
  fprintf(stderr, "Mandos plugin ");
 
83
  error(status, errnum, "%s", text);
 
84
  free(text);
 
85
}
 
86
 
 
87
 
61
88
static void termination_handler(int signum){
62
89
  if(interrupted_by_signal){
63
90
    return;
110
137
    proc_dir = opendir("/proc");
111
138
    if(proc_dir == NULL){
112
139
      int e = errno;
113
 
      error(0, errno, "opendir");
 
140
      error_plus(0, errno, "opendir");
114
141
      switch(e){
115
142
      case EACCES:
116
143
      case ENOTDIR:
152
179
        char *exe_link;
153
180
        ret = asprintf(&exe_link, "/proc/%s/exe", proc_ent->d_name);
154
181
        if(ret == -1){
155
 
          error(0, errno, "asprintf");
 
182
          error_plus(0, errno, "asprintf");
156
183
          exitstatus = EX_OSERR;
157
184
          goto failure;
158
185
        }
166
193
            continue;
167
194
          }
168
195
          int e = errno;
169
 
          error(0, errno, "lstat");
 
196
          error_plus(0, errno, "lstat");
170
197
          free(exe_link);
171
198
          switch(e){
172
199
          case EACCES:
214
241
    sigemptyset(&new_action.sa_mask);
215
242
    ret = sigaddset(&new_action.sa_mask, SIGINT);
216
243
    if(ret == -1){
217
 
      error(0, errno, "sigaddset");
 
244
      error_plus(0, errno, "sigaddset");
218
245
      exitstatus = EX_OSERR;
219
246
      goto failure;
220
247
    }
221
248
    ret = sigaddset(&new_action.sa_mask, SIGHUP);
222
249
    if(ret == -1){
223
 
      error(0, errno, "sigaddset");
 
250
      error_plus(0, errno, "sigaddset");
224
251
      exitstatus = EX_OSERR;
225
252
      goto failure;
226
253
    }
227
254
    ret = sigaddset(&new_action.sa_mask, SIGTERM);
228
255
    if(ret == -1){
229
 
      error(0, errno, "sigaddset");
 
256
      error_plus(0, errno, "sigaddset");
230
257
      exitstatus = EX_OSERR;
231
258
      goto failure;
232
259
    }
233
260
    ret = sigaction(SIGINT, NULL, &old_action);
234
261
    if(ret == -1){
235
 
      error(0, errno, "sigaction");
 
262
      error_plus(0, errno, "sigaction");
236
263
      exitstatus = EX_OSERR;
237
264
      goto failure;
238
265
    }
239
266
    if(old_action.sa_handler != SIG_IGN){
240
267
      ret = sigaction(SIGINT, &new_action, NULL);
241
268
      if(ret == -1){
242
 
        error(0, errno, "sigaction");
 
269
        error_plus(0, errno, "sigaction");
243
270
        exitstatus = EX_OSERR;
244
271
        goto failure;
245
272
      }
246
273
    }
247
274
    ret = sigaction(SIGHUP, NULL, &old_action);
248
275
    if(ret == -1){
249
 
      error(0, errno, "sigaction");
 
276
      error_plus(0, errno, "sigaction");
250
277
      exitstatus = EX_OSERR;
251
278
      goto failure;
252
279
    }
253
280
    if(old_action.sa_handler != SIG_IGN){
254
281
      ret = sigaction(SIGHUP, &new_action, NULL);
255
282
      if(ret == -1){
256
 
        error(0, errno, "sigaction");
 
283
        error_plus(0, errno, "sigaction");
257
284
        exitstatus = EX_OSERR;
258
285
        goto failure;
259
286
      }
260
287
    }
261
288
    ret = sigaction(SIGTERM, NULL, &old_action);
262
289
    if(ret == -1){
263
 
      error(0, errno, "sigaction");
 
290
      error_plus(0, errno, "sigaction");
264
291
      exitstatus = EX_OSERR;
265
292
      goto failure;
266
293
    }
267
294
    if(old_action.sa_handler != SIG_IGN){
268
295
      ret = sigaction(SIGTERM, &new_action, NULL);
269
296
      if(ret == -1){
270
 
        error(0, errno, "sigaction");
 
297
        error_plus(0, errno, "sigaction");
271
298
        exitstatus = EX_OSERR;
272
299
        goto failure;
273
300
      }
284
311
    goto failure;
285
312
  }
286
313
  if(splashy_command_pid == -1){
287
 
    error(0, errno, "fork");
 
314
    error_plus(0, errno, "fork");
288
315
    exitstatus = EX_OSERR;
289
316
    goto failure;
290
317
  }
294
321
      const char splashy_command[] = "/sbin/splashy_update";
295
322
      execl(splashy_command, splashy_command, prompt, (char *)NULL);
296
323
      int e = errno;
297
 
      error(0, errno, "execl");
 
324
      error_plus(0, errno, "execl");
298
325
      switch(e){
299
326
      case EACCES:
300
327
      case ENOENT:
344
371
      goto failure;
345
372
    }
346
373
    if(ret == -1){
347
 
      error(0, errno, "waitpid");
 
374
      error_plus(0, errno, "waitpid");
348
375
      if(errno == ECHILD){
349
376
        splashy_command_pid = 0;
350
377
      }
382
409
         the real user ID (_mandos) */
383
410
      ret = setuid(geteuid());
384
411
      if(ret == -1){
385
 
        error(0, errno, "setuid");
 
412
        error_plus(0, errno, "setuid");
386
413
      }
387
414
      
388
415
      setsid();
389
416
      ret = chdir("/");
390
417
      if(ret == -1){
391
 
        error(0, errno, "chdir");
 
418
        error_plus(0, errno, "chdir");
392
419
      }
393
420
/*       if(fork() != 0){ */
394
421
/*      _exit(EXIT_SUCCESS); */
395
422
/*       } */
396
423
      ret = dup2(STDERR_FILENO, STDOUT_FILENO); /* replace stdout */
397
424
      if(ret == -1){
398
 
        error(0, errno, "dup2");
 
425
        error_plus(0, errno, "dup2");
399
426
        _exit(EX_OSERR);
400
427
      }
401
428
      
402
429
      execl("/sbin/splashy", "/sbin/splashy", "boot", (char *)NULL);
403
430
      {
404
431
        int e = errno;
405
 
        error(0, errno, "execl");
 
432
        error_plus(0, errno, "execl");
406
433
        switch(e){
407
434
        case EACCES:
408
435
        case ENOENT:
428
455
    ret = (int)TEMP_FAILURE_RETRY(sigaction(signal_received,
429
456
                                            &signal_action, NULL));
430
457
    if(ret == -1){
431
 
      error(0, errno, "sigaction");
 
458
      error_plus(0, errno, "sigaction");
432
459
    }
433
460
    do {
434
461
      ret = raise(signal_received);
435
462
    } while(ret != 0 and errno == EINTR);
436
463
    if(ret != 0){
437
 
      error(0, errno, "raise");
 
464
      error_plus(0, errno, "raise");
438
465
      abort();
439
466
    }
440
467
    TEMP_FAILURE_RETRY(pause());