/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: 2008-08-29 05:53:59 UTC
  • Revision ID: teddy@fukt.bsnet.se-20080829055359-wkdasnyxtylmnxus
* mandos.xml (EXAMPLE): Replaced all occurences of command name with
                        "&COMMANDNAME;".

* plugins.d/password-prompt.c (main): Improved some documentation
                                      strings.  Do perror() of
                                      tcgetattr() fails.  Add debug
                                      output if interrupted by signal.
                                      Loop over write() instead of
                                      using fwrite() when outputting
                                      password.  Add debug output if
                                      getline() returns 0, unless it
                                      was caused by a signal.  Add
                                      exit status code to debug
                                      output.

* plugins.d/password-prompt.xml: Changed all single quotes to double
                                 quotes for consistency.  Removed
                                 <?xml-stylesheet>.
  (ENTITY TIMESTAMP): New.  Automatically updated by Emacs time-stamp
                      by using Emacs local variables.
  (/refentry/refentryinfo/title): Changed to "Mandos Manual".
  (/refentry/refentryinfo/productname): Changed to "Mandos".
  (/refentry/refentryinfo/date): New; set to "&TIMESTAMP;".
  (/refentry/refentryinfo/copyright): Split copyright holders.
  (/refentry/refnamediv/refpurpose): Improved wording.
  (SYNOPSIS): Fix to use correct markup.  Add short options.
  (DESCRIPTION, OPTIONS): Improved wording.
  (OPTIONS): Improved wording.  Use more correct markup.  Document
             short options.
  (EXIT STATUS): Add text.
  (ENVIRONMENT): Document use of "cryptsource" and "crypttarget".
  (FILES): REMOVED.
  (BUGS): Add text.
  (EXAMPLE): Added some examples.
  (SECURITY): Added text.
  (SEE ALSO): Remove reference to mandos(8).  Add reference to
              crypttab(5).

Show diffs side-by-side

added added

removed removed

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