/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

* plugins.d/password-prompt.c: Use exit codes from <sysexits.h>.  Do
                               close(STDOUT_FILENO) after writing to
                               check its return code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
                                   getopt_long, getenv() */
41
41
#include <stdio.h>              /* fprintf(), stderr, getline(),
42
42
                                   stdin, feof(), perror(), fputc(),
43
 
                                   stdout, getopt_long */
44
 
#include <errno.h>              /* errno, EINVAL */
 
43
                                   getopt_long */
 
44
#include <errno.h>              /* errno, EBADF, ENOTTY, EINVAL,
 
45
                                   EFAULT, EFBIG, EIO, ENOSPC, EINTR
 
46
                                */
45
47
#include <iso646.h>             /* or, not */
46
48
#include <stdbool.h>            /* bool, false, true */
47
49
#include <string.h>             /* strlen, rindex, strncmp, strcmp */
50
52
                                   argp_parse(), error_t,
51
53
                                   ARGP_KEY_ARG, ARGP_KEY_END,
52
54
                                   ARGP_ERR_UNKNOWN */
 
55
#include <sysexits.h>           /* EX_SOFTWARE, EX_OSERR,
 
56
                                   EX_UNAVAILABLE, EX_IOERR, EX_OK */
53
57
 
54
58
volatile sig_atomic_t quit_now = 0;
55
59
int signal_received;
111
115
    ret = argp_parse(&argp, argc, argv, 0, 0, NULL);
112
116
    if(ret == ARGP_ERR_UNKNOWN){
113
117
      fprintf(stderr, "Unknown error while parsing arguments\n");
114
 
      return EXIT_FAILURE;
 
118
      return EX_SOFTWARE;
115
119
    }
116
120
  }
117
121
  
123
127
  }
124
128
  
125
129
  if(tcgetattr(STDIN_FILENO, &t_old) != 0){
 
130
    int e = errno;
126
131
    perror("tcgetattr");
127
 
    return EXIT_FAILURE;
 
132
    switch(e){
 
133
    case EBADF:
 
134
    case ENOTTY:
 
135
      return EX_UNAVAILABLE;
 
136
    default:
 
137
      return EX_OSERR;
 
138
    }
128
139
  }
129
140
  
130
141
  sigemptyset(&new_action.sa_mask);
131
142
  ret = sigaddset(&new_action.sa_mask, SIGINT);
132
143
  if(ret == -1){
133
144
    perror("sigaddset");
134
 
    return EXIT_FAILURE;
 
145
    return EX_OSERR;
135
146
  }
136
147
  ret = sigaddset(&new_action.sa_mask, SIGHUP);
137
148
  if(ret == -1){
138
149
    perror("sigaddset");
139
 
    return EXIT_FAILURE;
 
150
    return EX_OSERR;
140
151
  }
141
152
  ret = sigaddset(&new_action.sa_mask, SIGTERM);
142
153
  if(ret == -1){
143
154
    perror("sigaddset");
144
 
    return EXIT_FAILURE;
 
155
    return EX_OSERR;
145
156
  }
146
157
  /* Need to check if the handler is SIG_IGN before handling:
147
158
     | [[info:libc:Initial Signal Actions]] |
150
161
  ret = sigaction(SIGINT, NULL, &old_action);
151
162
  if(ret == -1){
152
163
    perror("sigaction");
153
 
    return EXIT_FAILURE;
 
164
    return EX_OSERR;
154
165
  }
155
166
  if(old_action.sa_handler != SIG_IGN){
156
167
    ret = sigaction(SIGINT, &new_action, NULL);
157
168
    if(ret == -1){
158
169
      perror("sigaction");
159
 
      return EXIT_FAILURE;
 
170
      return EX_OSERR;
160
171
    }
161
172
  }
162
173
  ret = sigaction(SIGHUP, NULL, &old_action);
163
174
  if(ret == -1){
164
175
    perror("sigaction");
165
 
    return EXIT_FAILURE;
 
176
    return EX_OSERR;
166
177
  }
167
178
  if(old_action.sa_handler != SIG_IGN){
168
179
    ret = sigaction(SIGHUP, &new_action, NULL);
169
180
    if(ret == -1){
170
181
      perror("sigaction");
171
 
      return EXIT_FAILURE;
 
182
      return EX_OSERR;
172
183
    }
173
184
  }
174
185
  ret = sigaction(SIGTERM, NULL, &old_action);
175
186
  if(ret == -1){
176
187
    perror("sigaction");
177
 
    return EXIT_FAILURE;
 
188
    return EX_OSERR;
178
189
  }
179
190
  if(old_action.sa_handler != SIG_IGN){
180
191
    ret = sigaction(SIGTERM, &new_action, NULL);
181
192
    if(ret == -1){
182
193
      perror("sigaction");
183
 
      return EXIT_FAILURE;
 
194
      return EX_OSERR;
184
195
    }
185
196
  }
186
197
  
190
201
  }
191
202
  
192
203
  t_new = t_old;
193
 
  t_new.c_lflag &= ~ECHO;
 
204
  t_new.c_lflag &= ~(tcflag_t)ECHO;
194
205
  if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_new) != 0){
 
206
    int e = errno;
195
207
    perror("tcsetattr-echo");
196
 
    return EXIT_FAILURE;
 
208
    switch(e){
 
209
    case EBADF:
 
210
    case ENOTTY:
 
211
      return EX_UNAVAILABLE;
 
212
    case EINVAL:
 
213
    default:
 
214
      return EX_OSERR;
 
215
    }
197
216
  }
198
 
 
 
217
  
199
218
  if(debug){
200
219
    fprintf(stderr, "Waiting for input from stdin \n");
201
220
  }
237
256
      /* Make n = data size instead of allocated buffer size */
238
257
      n = (size_t)ret;
239
258
      /* Strip final newline */
240
 
      if(n>0 and buffer[n-1] == '\n'){
 
259
      if(n > 0 and buffer[n-1] == '\n'){
241
260
        buffer[n-1] = '\0';     /* not strictly necessary */
242
261
        n--;
243
262
      }
245
264
      while(written < n){
246
265
        ret = write(STDOUT_FILENO, buffer + written, n - written);
247
266
        if(ret < 0){
 
267
          int e = errno;
248
268
          perror("write");
249
 
          status = EXIT_FAILURE;
 
269
          switch(e){
 
270
          case EBADF:
 
271
          case EFAULT:
 
272
          case EINVAL:
 
273
          case EFBIG:
 
274
          case EIO:
 
275
          case ENOSPC:
 
276
          default:
 
277
            status = EX_IOERR;
 
278
            break;
 
279
          case EINTR:
 
280
            status = EXIT_FAILURE;
 
281
            break;
 
282
          }
250
283
          break;
251
284
        }
252
285
        written += (size_t)ret;
253
286
      }
 
287
      ret = close(STDOUT_FILENO);
 
288
      if(ret == -1){
 
289
        int e = errno;
 
290
        perror("close");
 
291
        switch(e){
 
292
        case EBADF:
 
293
          status = EX_OSFILE;
 
294
          break;
 
295
        case EIO:
 
296
        default:
 
297
          status = EX_IOERR;
 
298
          break;
 
299
        }
 
300
      }
254
301
      break;
255
302
    }
256
303
    if(ret < 0){
 
304
      int e = errno;
257
305
      if(errno != EINTR and not feof(stdin)){
258
306
        perror("getline");
259
 
        status = EXIT_FAILURE;
 
307
        switch(e){
 
308
        case EBADF:
 
309
          status = EX_UNAVAILABLE;
 
310
        case EIO:
 
311
        case EINVAL:
 
312
        default:
 
313
          status = EX_IOERR;
 
314
          break;
 
315
        }
260
316
        break;
261
317
      }
262
318
    }
293
349
    fprintf(stderr, "%s is exiting with status %d\n", argv[0],
294
350
            status);
295
351
  }
296
 
  if(status == EXIT_SUCCESS){
 
352
  if(status == EXIT_SUCCESS or status == EX_OK){
297
353
    fputc('\n', stderr);
298
354
  }
299
355