/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/password-prompt.c

* README (FAQ): Fix typo.
* mandos (main): Try to always do cleanup() before exit, since
                 otherwise the D-Bus bus name gets unregistered first.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
/*
3
3
 * Password-prompt - Read a password from the terminal and print it
4
4
 * 
5
 
 * Copyright © 2008-2010 Teddy Hogeborn
6
 
 * Copyright © 2008-2010 Björn Påhlsson
 
5
 * Copyright © 2008,2009 Teddy Hogeborn
 
6
 * Copyright © 2008,2009 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
39
39
#include <stdlib.h>             /* EXIT_SUCCESS, EXIT_FAILURE,
40
40
                                   getenv() */
41
41
#include <stdio.h>              /* fprintf(), stderr, getline(),
42
 
                                   stdin, feof(), fputc()
 
42
                                   stdin, feof(), perror(), fputc()
43
43
                                */
44
44
#include <errno.h>              /* errno, EBADF, ENOTTY, EINVAL,
45
45
                                   EFAULT, EFBIG, EIO, ENOSPC, EINTR
46
46
                                */
47
 
#include <error.h>              /* error() */
48
47
#include <iso646.h>             /* or, not */
49
48
#include <stdbool.h>            /* bool, false, true */
50
 
#include <string.h>             /* strlen, rindex */
 
49
#include <string.h>             /* strlen, rindex, strncmp, strcmp */
51
50
#include <argp.h>               /* struct argp_option, struct
52
51
                                   argp_state, struct argp,
53
52
                                   argp_parse(), error_t,
71
70
}
72
71
 
73
72
int main(int argc, char **argv){
74
 
  ssize_t sret;
75
 
  int ret;
 
73
  ssize_t ret;
76
74
  size_t n;
77
75
  struct termios t_new, t_old;
78
76
  char *buffer = NULL;
141
139
    case ENOMEM:
142
140
    default:
143
141
      errno = ret;
144
 
      error(0, errno, "argp_parse");
 
142
      perror("argp_parse");
145
143
      return EX_OSERR;
146
144
    case EINVAL:
147
145
      return EX_USAGE;
157
155
  
158
156
  if(tcgetattr(STDIN_FILENO, &t_old) != 0){
159
157
    int e = errno;
160
 
    error(0, errno, "tcgetattr");
 
158
    perror("tcgetattr");
161
159
    switch(e){
162
160
    case EBADF:
163
161
    case ENOTTY:
170
168
  sigemptyset(&new_action.sa_mask);
171
169
  ret = sigaddset(&new_action.sa_mask, SIGINT);
172
170
  if(ret == -1){
173
 
    error(0, errno, "sigaddset");
 
171
    perror("sigaddset");
174
172
    return EX_OSERR;
175
173
  }
176
174
  ret = sigaddset(&new_action.sa_mask, SIGHUP);
177
175
  if(ret == -1){
178
 
    error(0, errno, "sigaddset");
 
176
    perror("sigaddset");
179
177
    return EX_OSERR;
180
178
  }
181
179
  ret = sigaddset(&new_action.sa_mask, SIGTERM);
182
180
  if(ret == -1){
183
 
    error(0, errno, "sigaddset");
 
181
    perror("sigaddset");
184
182
    return EX_OSERR;
185
183
  }
186
184
  /* Need to check if the handler is SIG_IGN before handling:
189
187
  */
190
188
  ret = sigaction(SIGINT, NULL, &old_action);
191
189
  if(ret == -1){
192
 
    error(0, errno, "sigaction");
 
190
    perror("sigaction");
193
191
    return EX_OSERR;
194
192
  }
195
193
  if(old_action.sa_handler != SIG_IGN){
196
194
    ret = sigaction(SIGINT, &new_action, NULL);
197
195
    if(ret == -1){
198
 
      error(0, errno, "sigaction");
 
196
      perror("sigaction");
199
197
      return EX_OSERR;
200
198
    }
201
199
  }
202
200
  ret = sigaction(SIGHUP, NULL, &old_action);
203
201
  if(ret == -1){
204
 
    error(0, errno, "sigaction");
 
202
    perror("sigaction");
205
203
    return EX_OSERR;
206
204
  }
207
205
  if(old_action.sa_handler != SIG_IGN){
208
206
    ret = sigaction(SIGHUP, &new_action, NULL);
209
207
    if(ret == -1){
210
 
      error(0, errno, "sigaction");
 
208
      perror("sigaction");
211
209
      return EX_OSERR;
212
210
    }
213
211
  }
214
212
  ret = sigaction(SIGTERM, NULL, &old_action);
215
213
  if(ret == -1){
216
 
    error(0, errno, "sigaction");
 
214
    perror("sigaction");
217
215
    return EX_OSERR;
218
216
  }
219
217
  if(old_action.sa_handler != SIG_IGN){
220
218
    ret = sigaction(SIGTERM, &new_action, NULL);
221
219
    if(ret == -1){
222
 
      error(0, errno, "sigaction");
 
220
      perror("sigaction");
223
221
      return EX_OSERR;
224
222
    }
225
223
  }
233
231
  t_new.c_lflag &= ~(tcflag_t)ECHO;
234
232
  if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_new) != 0){
235
233
    int e = errno;
236
 
    error(0, errno, "tcsetattr-echo");
 
234
    perror("tcsetattr-echo");
237
235
    switch(e){
238
236
    case EBADF:
239
237
    case ENOTTY:
288
286
        }
289
287
      }
290
288
    }
291
 
    sret = getline(&buffer, &n, stdin);
292
 
    if(sret > 0){
 
289
    ret = getline(&buffer, &n, stdin);
 
290
    if(ret > 0){
293
291
      status = EXIT_SUCCESS;
294
292
      /* Make n = data size instead of allocated buffer size */
295
 
      n = (size_t)sret;
 
293
      n = (size_t)ret;
296
294
      /* Strip final newline */
297
295
      if(n > 0 and buffer[n-1] == '\n'){
298
296
        buffer[n-1] = '\0';     /* not strictly necessary */
300
298
      }
301
299
      size_t written = 0;
302
300
      while(written < n){
303
 
        sret = write(STDOUT_FILENO, buffer + written, n - written);
304
 
        if(sret < 0){
 
301
        ret = write(STDOUT_FILENO, buffer + written, n - written);
 
302
        if(ret < 0){
305
303
          int e = errno;
306
 
          error(0, errno, "write");
 
304
          perror("write");
307
305
          switch(e){
308
306
          case EBADF:
309
307
          case EFAULT:
320
318
          }
321
319
          break;
322
320
        }
323
 
        written += (size_t)sret;
 
321
        written += (size_t)ret;
324
322
      }
325
 
      sret = close(STDOUT_FILENO);
326
 
      if(sret == -1){
 
323
      ret = close(STDOUT_FILENO);
 
324
      if(ret == -1){
327
325
        int e = errno;
328
 
        error(0, errno, "close");
 
326
        perror("close");
329
327
        switch(e){
330
328
        case EBADF:
331
329
          status = EX_OSFILE;
338
336
      }
339
337
      break;
340
338
    }
341
 
    if(sret < 0){
 
339
    if(ret < 0){
342
340
      int e = errno;
343
341
      if(errno != EINTR and not feof(stdin)){
344
 
        error(0, errno, "getline");
 
342
        perror("getline");
345
343
        switch(e){
346
344
        case EBADF:
347
345
          status = EX_UNAVAILABLE;
354
352
        break;
355
353
      }
356
354
    }
357
 
    /* if(sret == 0), then the only sensible thing to do is to retry to
 
355
    /* if(ret == 0), then the only sensible thing to do is to retry to
358
356
       read from stdin */
359
357
    fputc('\n', stderr);
360
358
    if(debug and not quit_now){
370
368
    fprintf(stderr, "Restoring terminal attributes\n");
371
369
  }
372
370
  if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_old) != 0){
373
 
    error(0, errno, "tcsetattr+echo");
 
371
    perror("tcsetattr+echo");
374
372
  }
375
373
  
376
374
  if(quit_now){
378
376
    old_action.sa_handler = SIG_DFL;
379
377
    ret = sigaction(signal_received, &old_action, NULL);
380
378
    if(ret == -1){
381
 
      error(0, errno, "sigaction");
 
379
      perror("sigaction");
382
380
    }
383
381
    raise(signal_received);
384
382
  }