/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release

« back to all changes in this revision

Viewing changes to plugins.d/askpass-fifo.c

First version of a somewhat complete D-Bus server interface.  Also
change user/group name to "_mandos".

* debian/mandos.postinst: Rename old "mandos" user and group to
                          "_mandos"; create "_mandos" user and group
                          if none exist.
* debian/mandos-client.postinst: - '' -

* initramfs-tools-hook: Try "_mandos" before "mandos" as user and
                        group name.

* mandos (_datetime_to_dbus_struct): New; was previously local.
  (Client.started): Renamed to "last_started".  All users changed.
  (Client.started): New; boolean.
  (Client.dbus_object_path): New.
  (Client.check_command): Renamed to "checker_command".  All users
                          changed.
  (Client.__init__): Set and use "self.dbus_object_path".  Set
                     "self.started".
  (Client.start): Update "self.started".  Emit "self.PropertyChanged"
                  signals for both "started" and "last_started".
  (Client.stop): Update "self.started".  Emit "self.PropertyChanged"
                 signal for "started".
  (Client.checker_callback): Take additional "command" argument.  All
                             callers changed. Emit
                             "self.PropertyChanged" signal.
  (Client.bump_timeout): Emit "self.PropertyChanged" signal for
                         "last_checked_ok".
  (Client.start_checker): Emit "self.PropertyChanged" signal for
                          "checker_running".
  (Client.stop_checker): Emit "self.PropertyChanged" signal for
                         "checker_running".
  (Client.still_valid): Bug fix: use "getattr(self, started, False)"
                        instead of "self.started" in case this client
                        object is so new that the "started" attribute
                        has not been created yet.
  (Client.IntervalChanged, Client.CheckerIsRunning, Client.GetChecker,
  Client.GetCreated, Client.GetFingerprint, Client.GetHost,
  Client.GetInterval, Client.GetName, Client.GetStarted,
  Client.GetTimeout, Client.StateChanged, Client.TimeoutChanged):
  Removed; all callers changed.
  (Client.CheckerCompleted): Add "condition" and "command" arguments.
                             All callers changed.
  (Client.GetAllProperties, Client.PropertyChanged): New.
  (Client.StillValid): Renamed to "IsStillValid".
  (Client.StartChecker): Changed to its own function to avoid the
                         return value from "Client.start_checker()".
  (Client.Stop): Changed to its own function to avoid the return value
                 from "Client.stop()".
  (main): Try "_mandos" before "mandos" as user and group name.
          Removed inner function "remove_from_clients".  New inner
          class "MandosServer".

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*  -*- coding: utf-8 -*- */
2
2
/*
3
 
 * Askpass-FIFO - Read a password from a FIFO and output it
 
3
 * Passprompt - 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 Teddy Hogeborn
 
6
 * Copyright © 2008 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 <https://www.fukt.bsnet.se/~belorn/> and
 
23
 * <https://www.fukt.bsnet.se/~teddy/>.
23
24
 */
24
25
 
25
26
#define _GNU_SOURCE             /* TEMP_FAILURE_RETRY() */
26
27
#include <sys/types.h>          /* ssize_t */
27
28
#include <sys/stat.h>           /* mkfifo(), S_IRUSR, S_IWUSR */
28
29
#include <iso646.h>             /* and */
29
 
#include <errno.h>              /* errno, EACCES, ENOTDIR, ELOOP,
30
 
                                   ENAMETOOLONG, ENOSPC, EROFS,
31
 
                                   ENOENT, EEXIST, EFAULT, EMFILE,
32
 
                                   ENFILE, ENOMEM, EBADF, EINVAL, EIO,
33
 
                                   EISDIR, EFBIG */
34
 
#include <error.h>              /* error() */
35
 
#include <stdio.h>              /* fprintf(), vfprintf(), vasprintf() */
36
 
#include <stdlib.h>             /* EXIT_FAILURE, NULL, size_t, free(),
 
30
#include <errno.h>              /* errno, EEXIST */
 
31
#include <stdio.h>              /* perror() */
 
32
#include <stdlib.h>             /* EXIT_FAILURE, NULL, size_t, free(), 
37
33
                                   realloc(), EXIT_SUCCESS */
38
34
#include <fcntl.h>              /* open(), O_RDONLY */
39
35
#include <unistd.h>             /* read(), close(), write(),
40
36
                                   STDOUT_FILENO */
41
 
#include <sysexits.h>           /* EX_OSERR, EX_OSFILE,
42
 
                                   EX_UNAVAILABLE, EX_IOERR */
43
 
#include <string.h>             /* strerror() */
44
 
#include <stdarg.h>             /* va_list, va_start(), ... */
45
 
 
46
 
 
47
 
/* Function to use when printing errors */
48
 
void error_plus(int status, int errnum, const char *formatstring, ...){
49
 
  va_list ap;
50
 
  char *text;
51
 
  int ret;
52
 
  
53
 
  va_start(ap, formatstring);
54
 
  ret = vasprintf(&text, formatstring, ap);
55
 
  if (ret == -1){
56
 
    fprintf(stderr, "Mandos plugin %s: ", program_invocation_short_name);
57
 
    vfprintf(stderr, formatstring, ap);
58
 
    fprintf(stderr, ": ");
59
 
    fprintf(stderr, "%s\n", strerror(errnum));
60
 
    error(status, errno, "vasprintf while printing error");
61
 
    return;
62
 
  }
63
 
  fprintf(stderr, "Mandos plugin ");
64
 
  error(status, errnum, "%s", text);
65
 
  free(text);
66
 
}
 
37
 
67
38
 
68
39
int main(__attribute__((unused))int argc,
69
40
         __attribute__((unused))char **argv){
72
43
  
73
44
  /* Create FIFO */
74
45
  const char passfifo[] = "/lib/cryptsetup/passfifo";
75
 
  ret = mkfifo(passfifo, S_IRUSR | S_IWUSR);
76
 
  if(ret == -1){
77
 
    int e = errno;
78
 
    switch(e){
79
 
    case EACCES:
80
 
    case ENOTDIR:
81
 
    case ELOOP:
82
 
      error_plus(EX_OSFILE, errno, "mkfifo");
83
 
    case ENAMETOOLONG:
84
 
    case ENOSPC:
85
 
    case EROFS:
86
 
    default:
87
 
      error_plus(EX_OSERR, errno, "mkfifo");
88
 
    case ENOENT:
89
 
      /* no "/lib/cryptsetup"? */
90
 
      error_plus(EX_UNAVAILABLE, errno, "mkfifo");
91
 
    case EEXIST:
92
 
      break;                    /* not an error */
93
 
    }
 
46
  ret = TEMP_FAILURE_RETRY(mkfifo(passfifo, S_IRUSR | S_IWUSR));
 
47
  if(ret == -1 and errno != EEXIST){
 
48
    perror("mkfifo");
 
49
    return EXIT_FAILURE;
94
50
  }
95
51
  
96
52
  /* Open FIFO */
97
 
  int fifo_fd = open(passfifo, O_RDONLY);
 
53
  int fifo_fd = TEMP_FAILURE_RETRY(open(passfifo, O_RDONLY));
98
54
  if(fifo_fd == -1){
99
 
    int e = errno;
100
 
    error_plus(0, errno, "open");
101
 
    switch(e){
102
 
    case EACCES:
103
 
    case ENOENT:
104
 
    case EFAULT:
105
 
      return EX_UNAVAILABLE;
106
 
    case ENAMETOOLONG:
107
 
    case EMFILE:
108
 
    case ENFILE:
109
 
    case ENOMEM:
110
 
    default:
111
 
      return EX_OSERR;
112
 
    case ENOTDIR:
113
 
    case ELOOP:
114
 
      return EX_OSFILE;
115
 
    }
 
55
    perror("open");
 
56
    return EXIT_FAILURE;
116
57
  }
117
58
  
118
59
  /* Read from FIFO */
121
62
  {
122
63
    size_t buf_allocated = 0;
123
64
    const size_t blocksize = 1024;
124
 
    do {
 
65
    do{
125
66
      if(buf_len + blocksize > buf_allocated){
126
67
        char *tmp = realloc(buf, buf_allocated + blocksize);
127
68
        if(tmp == NULL){
128
 
          error_plus(0, errno, "realloc");
 
69
          perror("realloc");
129
70
          free(buf);
130
 
          return EX_OSERR;
 
71
          return EXIT_FAILURE;
131
72
        }
132
73
        buf = tmp;
133
74
        buf_allocated += blocksize;
134
75
      }
135
 
      sret = read(fifo_fd, buf + buf_len, buf_allocated - buf_len);
 
76
      sret = TEMP_FAILURE_RETRY(read(fifo_fd, buf + buf_len,
 
77
                                     buf_allocated - buf_len));
136
78
      if(sret == -1){
137
 
        int e = errno;
 
79
        perror("read");
138
80
        free(buf);
139
 
        errno = e;
140
 
        error_plus(0, errno, "read");
141
 
        switch(e){
142
 
        case EBADF:
143
 
        case EFAULT:
144
 
        case EINVAL:
145
 
        default:
146
 
          return EX_OSERR;
147
 
        case EIO:
148
 
          return EX_IOERR;
149
 
        case EISDIR:
150
 
          return EX_UNAVAILABLE;
151
 
        }
 
81
        return EXIT_FAILURE;
152
82
      }
153
83
      buf_len += (size_t)sret;
154
 
    } while(sret != 0);
 
84
    }while(sret != 0);
155
85
  }
156
86
  
157
87
  /* Close FIFO */
158
 
  close(fifo_fd);
 
88
  TEMP_FAILURE_RETRY(close(fifo_fd));
159
89
  
160
90
  /* Print password to stdout */
161
91
  size_t written = 0;
162
92
  while(written < buf_len){
163
 
    sret = write(STDOUT_FILENO, buf + written, buf_len - written);
 
93
    sret = TEMP_FAILURE_RETRY(write(STDOUT_FILENO, buf + written,
 
94
                                    buf_len - written));
164
95
    if(sret == -1){
165
 
      int e = errno;
 
96
      perror("write");
166
97
      free(buf);
167
 
      errno = e;
168
 
      error_plus(0, errno, "write");
169
 
      switch(e){
170
 
      case EBADF:
171
 
      case EFAULT:
172
 
      case EINVAL:
173
 
        return EX_OSFILE;
174
 
      case EFBIG:
175
 
      case EIO:
176
 
      case ENOSPC:
177
 
      default:
178
 
        return EX_IOERR;
179
 
      }
 
98
      return EXIT_FAILURE;
180
99
    }
181
100
    written += (size_t)sret;
182
101
  }
183
102
  free(buf);
184
103
  
185
 
  ret = close(STDOUT_FILENO);
186
 
  if(ret == -1){
187
 
    int e = errno;
188
 
    error_plus(0, errno, "close");
189
 
    switch(e){
190
 
    case EBADF:
191
 
      return EX_OSFILE;
192
 
    case EIO:
193
 
    default:
194
 
      return EX_IOERR;
195
 
    }
196
 
  }
197
104
  return EXIT_SUCCESS;
198
105
}