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

  • Committer: Teddy Hogeborn
  • Date: 2009-10-22 00:05:01 UTC
  • Revision ID: teddy@fukt.bsnet.se-20091022000501-g792e99q5g1wkyet
Merge from release branch.

Show diffs side-by-side

added added

removed removed

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