/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/askpass-fifo.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
 * Askpass-FIFO - Read a password from a FIFO 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() */
26
 
#include <sys/types.h>          /* ssize_t */
 
26
#include <sys/types.h>          /* uid_t, gid_t, ssize_t */
27
27
#include <sys/stat.h>           /* mkfifo(), S_IRUSR, S_IWUSR */
28
28
#include <iso646.h>             /* and */
29
29
#include <errno.h>              /* errno, EACCES, ENOTDIR, ELOOP,
32
32
                                   ENFILE, ENOMEM, EBADF, EINVAL, EIO,
33
33
                                   EISDIR, EFBIG */
34
34
#include <error.h>              /* error() */
 
35
#include <stdio.h>              /* fprintf(), vfprintf(),
 
36
                                   vasprintf() */
35
37
#include <stdlib.h>             /* EXIT_FAILURE, NULL, size_t, free(),
36
38
                                   realloc(), EXIT_SUCCESS */
37
39
#include <fcntl.h>              /* open(), O_RDONLY */
39
41
                                   STDOUT_FILENO */
40
42
#include <sysexits.h>           /* EX_OSERR, EX_OSFILE,
41
43
                                   EX_UNAVAILABLE, EX_IOERR */
42
 
 
 
44
#include <string.h>             /* strerror() */
 
45
#include <stdarg.h>             /* va_list, va_start(), ... */
 
46
 
 
47
uid_t uid = 65534;
 
48
gid_t gid = 65534;
 
49
 
 
50
/* Function to use when printing errors */
 
51
__attribute__((format (gnu_printf, 3, 4)))
 
52
void error_plus(int status, int errnum, const char *formatstring,
 
53
                ...){
 
54
  va_list ap;
 
55
  char *text;
 
56
  int ret;
 
57
  
 
58
  va_start(ap, formatstring);
 
59
  ret = vasprintf(&text, formatstring, ap);
 
60
  if(ret == -1){
 
61
    fprintf(stderr, "Mandos plugin %s: ",
 
62
            program_invocation_short_name);
 
63
    vfprintf(stderr, formatstring, ap);
 
64
    fprintf(stderr, ": ");
 
65
    fprintf(stderr, "%s\n", strerror(errnum));
 
66
    error(status, errno, "vasprintf while printing error");
 
67
    return;
 
68
  }
 
69
  fprintf(stderr, "Mandos plugin ");
 
70
  error(status, errnum, "%s", text);
 
71
  free(text);
 
72
}
43
73
 
44
74
int main(__attribute__((unused))int argc,
45
75
         __attribute__((unused))char **argv){
46
76
  int ret = 0;
47
77
  ssize_t sret;
48
78
  
 
79
  uid = getuid();
 
80
  gid = getgid();
 
81
  
49
82
  /* Create FIFO */
50
83
  const char passfifo[] = "/lib/cryptsetup/passfifo";
51
84
  ret = mkfifo(passfifo, S_IRUSR | S_IWUSR);
52
85
  if(ret == -1){
53
86
    int e = errno;
54
 
    error(0, errno, "mkfifo");
55
87
    switch(e){
56
88
    case EACCES:
57
89
    case ENOTDIR:
58
90
    case ELOOP:
59
 
      return EX_OSFILE;
 
91
      error_plus(EX_OSFILE, errno, "mkfifo");
60
92
    case ENAMETOOLONG:
61
93
    case ENOSPC:
62
94
    case EROFS:
63
95
    default:
64
 
      return EX_OSERR;
 
96
      error_plus(EX_OSERR, errno, "mkfifo");
65
97
    case ENOENT:
66
 
      return EX_UNAVAILABLE;    /* no "/lib/cryptsetup"? */
 
98
      /* no "/lib/cryptsetup"? */
 
99
      error_plus(EX_UNAVAILABLE, errno, "mkfifo");
67
100
    case EEXIST:
68
101
      break;                    /* not an error */
69
102
    }
73
106
  int fifo_fd = open(passfifo, O_RDONLY);
74
107
  if(fifo_fd == -1){
75
108
    int e = errno;
76
 
    error(0, errno, "open");
 
109
    error_plus(0, errno, "open");
77
110
    switch(e){
78
111
    case EACCES:
79
112
    case ENOENT:
91
124
    }
92
125
  }
93
126
  
 
127
  /* Lower group privileges  */
 
128
  if(setgid(gid) == -1){
 
129
    error_plus(0, errno, "setgid");
 
130
  }
 
131
  
 
132
  /* Lower user privileges */
 
133
  if(setuid(uid) == -1){
 
134
    error_plus(0, errno, "setuid");
 
135
  }
 
136
  
94
137
  /* Read from FIFO */
95
138
  char *buf = NULL;
96
139
  size_t buf_len = 0;
101
144
      if(buf_len + blocksize > buf_allocated){
102
145
        char *tmp = realloc(buf, buf_allocated + blocksize);
103
146
        if(tmp == NULL){
104
 
          error(0, errno, "realloc");
 
147
          error_plus(0, errno, "realloc");
105
148
          free(buf);
106
149
          return EX_OSERR;
107
150
        }
113
156
        int e = errno;
114
157
        free(buf);
115
158
        errno = e;
116
 
        error(0, errno, "read");
 
159
        error_plus(0, errno, "read");
117
160
        switch(e){
118
161
        case EBADF:
119
162
        case EFAULT:
141
184
      int e = errno;
142
185
      free(buf);
143
186
      errno = e;
144
 
      error(0, errno, "write");
 
187
      error_plus(0, errno, "write");
145
188
      switch(e){
146
189
      case EBADF:
147
190
      case EFAULT:
161
204
  ret = close(STDOUT_FILENO);
162
205
  if(ret == -1){
163
206
    int e = errno;
164
 
    error(0, errno, "close");
 
207
    error_plus(0, errno, "close");
165
208
    switch(e){
166
209
    case EBADF:
167
210
      return EX_OSFILE;