/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/plymouth.c

  • Committer: Björn Påhlsson
  • Date: 2011-06-23 22:27:15 UTC
  • mto: This revision was merged to the branch mainline in revision 485.
  • Revision ID: belorn@fukt.bsnet.se-20110623222715-q5wro9ma9iyjl367
* Makefile (CFLAGS): Added "-lrt" to include real time library.
* plugins.d/mandos-client.c: use scandir(3) instead of readdir(3)
                             Prefix all debug output with "Mandos plugin " + program_invocation_short_name
                             Retry servers that failed to provide password.
                             New option --retry SECONDS that sets the interval between rechecking.
                             --retry also controls how often it retries a server when using --connect.
* plugins.d/splashy.c:  Prefix all debug output with "Mandos plugin " + program_invocation_short_name
* plugins.d/usplash.c: --||--
* plugins.d/askpass-fifo.c: --||--
* plugins.d/password-prompt.c: --||--
* plugins.d/plymouth.c: --||--
* mandos: Lower logger level from warning to info on failed client requests because client was disabled or unknown fingerprint.
* plugins.d/plymouth.c (get_pid): bug fix. Was not calling free on direntries. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
#include <stddef.h>             /* NULL */
37
37
#include <string.h>             /* strchr(), memcmp() */
38
38
#include <stdio.h>              /* asprintf(), perror(), fopen(),
39
 
                                   fscanf() */
 
39
                                   fscanf(), vasprintf(), fprintf(), vfprintf() */
40
40
#include <unistd.h>             /* close(), readlink(), read(),
41
41
                                   fork(), setsid(), chdir(), dup2(),
42
42
                                   STDERR_FILENO, execv(), access() */
50
50
#include <error.h>              /* error() */
51
51
#include <errno.h>              /* TEMP_FAILURE_RETRY */
52
52
#include <argz.h>               /* argz_count(), argz_extract() */
 
53
#include <stdarg.h>             /* va_list, va_start(), ... */
53
54
 
54
55
sig_atomic_t interrupted_by_signal = 0;
55
56
const char plymouth_pid[] = "/dev/.initramfs/plymouth.pid";
70
71
  interrupted_by_signal = 1;
71
72
}
72
73
 
 
74
/* Function to use when printing errors */
 
75
void error_plus(int status, int errnum, const char *formatstring, ...){
 
76
  va_list ap;
 
77
  char *text;
 
78
  int ret;
 
79
  
 
80
  va_start(ap, formatstring);
 
81
  ret = vasprintf(&text, formatstring, ap);
 
82
  if (ret == -1){
 
83
    fprintf(stderr, "Mandos plugin %s: ", program_invocation_short_name);
 
84
    vfprintf(stderr, formatstring, ap);
 
85
    fprintf(stderr, ": ");
 
86
    fprintf(stderr, "%s\n", strerror(errnum));
 
87
    error(status, errno, "vasprintf while printing error");
 
88
    return;
 
89
  }
 
90
  fprintf(stderr, "Mandos plugin ");
 
91
  error(status, errnum, "%s", text);
 
92
  free(text);
 
93
}
 
94
 
73
95
/* Create prompt string */
74
96
char *makeprompt(void){
75
97
  int ret = 0;
109
131
bool become_a_daemon(void){
110
132
  int ret = setuid(geteuid());
111
133
  if(ret == -1){
112
 
    error(0, errno, "setuid");
 
134
    error_plus(0, errno, "setuid");
113
135
  }
114
136
    
115
137
  setsid();
116
138
  ret = chdir("/");
117
139
  if(ret == -1){
118
 
    error(0, errno, "chdir");
 
140
    error_plus(0, errno, "chdir");
119
141
    return false;
120
142
  }
121
143
  ret = dup2(STDERR_FILENO, STDOUT_FILENO); /* replace our stdout */
122
144
  if(ret == -1){
123
 
    error(0, errno, "dup2");
 
145
    error_plus(0, errno, "dup2");
124
146
    return false;
125
147
  }
126
148
  return true;
134
156
  pid_t pid;
135
157
  pid = fork();
136
158
  if(pid == -1){
137
 
    error(0, errno, "fork");
 
159
    error_plus(0, errno, "fork");
138
160
    return false;
139
161
  }
140
162
  if(pid == 0){
151
173
    for (; argv[i]!=NULL; i++){
152
174
      tmp = realloc(new_argv, sizeof(const char *) * ((size_t)i + 1));
153
175
      if (tmp == NULL){
154
 
        error(0, errno, "realloc");
 
176
        error_plus(0, errno, "realloc");
155
177
        free(new_argv);
156
178
        _exit(EX_OSERR);
157
179
      }
161
183
    new_argv[i] = NULL;
162
184
    
163
185
    execv(path, (char *const *)new_argv);
164
 
    error(0, errno, "execv");
 
186
    error_plus(0, errno, "execv");
165
187
    _exit(EXIT_FAILURE);
166
188
  }
167
189
  if(pid_return != NULL){
176
198
    return false;
177
199
  }
178
200
  if(ret == -1){
179
 
    error(0, errno, "waitpid");
 
201
    error_plus(0, errno, "waitpid");
180
202
    return false;
181
203
  }
182
204
  if(WIFEXITED(status) and (WEXITSTATUS(status) == 0)){
202
224
  char *exe_link;
203
225
  ret = asprintf(&exe_link, "/proc/%s/exe", proc_entry->d_name);
204
226
  if(ret == -1){
205
 
    error(0, errno, "asprintf");
 
227
    error_plus(0, errno, "asprintf");
206
228
    return 0;
207
229
  }
208
230
  
211
233
  if(ret == -1){
212
234
    free(exe_link);
213
235
    if(errno != ENOENT){
214
 
      error(0, errno, "lstat");
 
236
      error_plus(0, errno, "lstat");
215
237
    }
216
238
    return 0;
217
239
  }
245
267
    fclose(pidfile);
246
268
  }
247
269
  if(maxvalue == 0){
248
 
    struct dirent **direntries;
 
270
    struct dirent **direntries = NULL;
249
271
    ret = scandir("/proc", &direntries, is_plymouth, alphasort);
250
272
    if (ret == -1){
251
 
      error(0, errno, "scandir");
 
273
      error_plus(0, errno, "scandir");
252
274
    }
253
275
    if (ret > 0){
254
276
      ret = sscanf(direntries[0]->d_name, "%" SCNuMAX, &maxvalue);
255
277
      if (ret < 0){
256
 
        error(0, errno, "sscanf");
 
278
        error_plus(0, errno, "sscanf");
257
279
      }
258
280
    }
 
281
    /* scandir might preallocate for this variable (man page unclear).
 
282
       even if ret == 0, we need to free it. */
 
283
    free(direntries);
259
284
  }
260
285
  pid_t pid;
261
286
  pid = (pid_t)maxvalue;
275
300
  ret = asprintf(&cmdline_filename, "/proc/%" PRIuMAX "/cmdline",
276
301
                 (uintmax_t)pid);
277
302
  if(ret == -1){
278
 
    error(0, errno, "asprintf");
 
303
    error_plus(0, errno, "asprintf");
279
304
    return NULL;
280
305
  }
281
306
  
283
308
  cl_fd = open(cmdline_filename, O_RDONLY);
284
309
  free(cmdline_filename);
285
310
  if(cl_fd == -1){
286
 
    error(0, errno, "open");
 
311
    error_plus(0, errno, "open");
287
312
    return NULL;
288
313
  }
289
314
  
297
322
    if(cmdline_len + blocksize > cmdline_allocated){
298
323
      tmp = realloc(cmdline, cmdline_allocated + blocksize);
299
324
      if(tmp == NULL){
300
 
        error(0, errno, "realloc");
 
325
        error_plus(0, errno, "realloc");
301
326
        free(cmdline);
302
327
        close(cl_fd);
303
328
        return NULL;
310
335
    sret = read(cl_fd, cmdline + cmdline_len,
311
336
                cmdline_allocated - cmdline_len);
312
337
    if(sret == -1){
313
 
      error(0, errno, "read");
 
338
      error_plus(0, errno, "read");
314
339
      free(cmdline);
315
340
      close(cl_fd);
316
341
      return NULL;
319
344
  } while(sret != 0);
320
345
  ret = close(cl_fd);
321
346
  if(ret == -1){
322
 
    error(0, errno, "close");
 
347
    error_plus(0, errno, "close");
323
348
    free(cmdline);
324
349
    return NULL;
325
350
  }
328
353
  char **argv = malloc((argz_count(cmdline, cmdline_len) + 1)
329
354
                       * sizeof(char *)); /* Get number of args */
330
355
  if(argv == NULL){
331
 
    error(0, errno, "argv = malloc()");
 
356
    error_plus(0, errno, "argv = malloc()");
332
357
    free(cmdline);
333
358
    return NULL;
334
359
  }
361
386
        *sig != 0; sig++){
362
387
      ret = sigaddset(&new_action.sa_mask, *sig);
363
388
      if(ret == -1){
364
 
        error(EX_OSERR, errno, "sigaddset");
 
389
        error_plus(EX_OSERR, errno, "sigaddset");
365
390
      }
366
391
      ret = sigaction(*sig, NULL, &old_action);
367
392
      if(ret == -1){
368
 
        error(EX_OSERR, errno, "sigaction");
 
393
        error_plus(EX_OSERR, errno, "sigaction");
369
394
      }
370
395
      if(old_action.sa_handler != SIG_IGN){
371
396
        ret = sigaction(*sig, &new_action, NULL);
372
397
        if(ret == -1){
373
 
          error(EX_OSERR, errno, "sigaction");
 
398
          error_plus(EX_OSERR, errno, "sigaction");
374
399
        }
375
400
      }
376
401
    }
395
420
  ret = asprintf(&prompt_arg, "--prompt=%s", prompt);
396
421
  free(prompt);
397
422
  if(ret == -1){
398
 
    error(EX_OSERR, errno, "asprintf");
 
423
    error_plus(EX_OSERR, errno, "asprintf");
399
424
  }
400
425
  
401
426
  /* plymouth ask-for-password --prompt="$prompt" */
417
442
  const char **plymouthd_argv;
418
443
  pid_t pid = get_pid();
419
444
  if(pid == 0){
420
 
    error(0, 0, "plymouthd pid not found");
 
445
    error_plus(0, 0, "plymouthd pid not found");
421
446
    plymouthd_argv = plymouthd_default_argv;
422
447
  } else {
423
448
    plymouthd_argv = getargv(pid);