/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

  • Committer: Björn Påhlsson
  • Date: 2008-01-18 21:18:26 UTC
  • mto: This revision was merged to the branch mainline in revision 6.
  • Revision ID: belorn@legolas-20080118211826-5rbwo54l4bwim5x2
Client:
        [Working version in initrd for booting]
        Added #ifdef DEBUG statements through out the program
        Added support to keep bouth tcp and udp up at the same time
        Catching several more error return codes that was unchecked.
        Starts the Network interface during startup.
        Added support for entering password on console
        Added error handling, like looping until a password has been received.
        Added cleanup handling so console state is always restored
                
removed:
        Old server.cpp [see next version]
        Test certificates

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-2011 Teddy Hogeborn
6
 
 * Copyright © 2008-2011 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
 
void error_plus(int status, int errnum, const char *formatstring,
50
 
                ...){
51
 
  va_list ap;
52
 
  char *text;
53
 
  int ret;
54
 
  
55
 
  va_start(ap, formatstring);
56
 
  ret = vasprintf(&text, formatstring, ap);
57
 
  if (ret == -1){
58
 
    fprintf(stderr, "Mandos plugin %s: ",
59
 
            program_invocation_short_name);
60
 
    vfprintf(stderr, formatstring, ap);
61
 
    fprintf(stderr, ": ");
62
 
    fprintf(stderr, "%s\n", strerror(errnum));
63
 
    error(status, errno, "vasprintf while printing error");
64
 
    return;
65
 
  }
66
 
  fprintf(stderr, "Mandos plugin ");
67
 
  error(status, errnum, "%s", text);
68
 
  free(text);
69
 
}
70
 
 
71
 
int main(__attribute__((unused))int argc,
72
 
         __attribute__((unused))char **argv){
73
 
  int ret = 0;
74
 
  ssize_t sret;
75
 
  
76
 
  /* Create FIFO */
77
 
  const char passfifo[] = "/lib/cryptsetup/passfifo";
78
 
  ret = mkfifo(passfifo, S_IRUSR | S_IWUSR);
79
 
  if(ret == -1){
80
 
    int e = errno;
81
 
    switch(e){
82
 
    case EACCES:
83
 
    case ENOTDIR:
84
 
    case ELOOP:
85
 
      error_plus(EX_OSFILE, errno, "mkfifo");
86
 
    case ENAMETOOLONG:
87
 
    case ENOSPC:
88
 
    case EROFS:
89
 
    default:
90
 
      error_plus(EX_OSERR, errno, "mkfifo");
91
 
    case ENOENT:
92
 
      /* no "/lib/cryptsetup"? */
93
 
      error_plus(EX_UNAVAILABLE, errno, "mkfifo");
94
 
    case EEXIST:
95
 
      break;                    /* not an error */
96
 
    }
97
 
  }
98
 
  
99
 
  /* Open FIFO */
100
 
  int fifo_fd = open(passfifo, O_RDONLY);
101
 
  if(fifo_fd == -1){
102
 
    int e = errno;
103
 
    error_plus(0, errno, "open");
104
 
    switch(e){
105
 
    case EACCES:
106
 
    case ENOENT:
107
 
    case EFAULT:
108
 
      return EX_UNAVAILABLE;
109
 
    case ENAMETOOLONG:
110
 
    case EMFILE:
111
 
    case ENFILE:
112
 
    case ENOMEM:
113
 
    default:
114
 
      return EX_OSERR;
115
 
    case ENOTDIR:
116
 
    case ELOOP:
117
 
      return EX_OSFILE;
118
 
    }
119
 
  }
120
 
  
121
 
  /* Read from FIFO */
122
 
  char *buf = NULL;
123
 
  size_t buf_len = 0;
124
 
  {
125
 
    size_t buf_allocated = 0;
126
 
    const size_t blocksize = 1024;
127
 
    do {
128
 
      if(buf_len + blocksize > buf_allocated){
129
 
        char *tmp = realloc(buf, buf_allocated + blocksize);
130
 
        if(tmp == NULL){
131
 
          error_plus(0, errno, "realloc");
132
 
          free(buf);
133
 
          return EX_OSERR;
134
 
        }
135
 
        buf = tmp;
136
 
        buf_allocated += blocksize;
137
 
      }
138
 
      sret = read(fifo_fd, buf + buf_len, buf_allocated - buf_len);
139
 
      if(sret == -1){
140
 
        int e = errno;
141
 
        free(buf);
142
 
        errno = e;
143
 
        error_plus(0, errno, "read");
144
 
        switch(e){
145
 
        case EBADF:
146
 
        case EFAULT:
147
 
        case EINVAL:
148
 
        default:
149
 
          return EX_OSERR;
150
 
        case EIO:
151
 
          return EX_IOERR;
152
 
        case EISDIR:
153
 
          return EX_UNAVAILABLE;
154
 
        }
155
 
      }
156
 
      buf_len += (size_t)sret;
157
 
    } while(sret != 0);
158
 
  }
159
 
  
160
 
  /* Close FIFO */
161
 
  close(fifo_fd);
162
 
  
163
 
  /* Print password to stdout */
164
 
  size_t written = 0;
165
 
  while(written < buf_len){
166
 
    sret = write(STDOUT_FILENO, buf + written, buf_len - written);
167
 
    if(sret == -1){
168
 
      int e = errno;
169
 
      free(buf);
170
 
      errno = e;
171
 
      error_plus(0, errno, "write");
172
 
      switch(e){
173
 
      case EBADF:
174
 
      case EFAULT:
175
 
      case EINVAL:
176
 
        return EX_OSFILE;
177
 
      case EFBIG:
178
 
      case EIO:
179
 
      case ENOSPC:
180
 
      default:
181
 
        return EX_IOERR;
182
 
      }
183
 
    }
184
 
    written += (size_t)sret;
185
 
  }
186
 
  free(buf);
187
 
  
188
 
  ret = close(STDOUT_FILENO);
189
 
  if(ret == -1){
190
 
    int e = errno;
191
 
    error_plus(0, errno, "close");
192
 
    switch(e){
193
 
    case EBADF:
194
 
      return EX_OSFILE;
195
 
    case EIO:
196
 
    default:
197
 
      return EX_IOERR;
198
 
    }
199
 
  }
200
 
  return EXIT_SUCCESS;
201
 
}