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

First version of a somewhat complete D-Bus server interface.  Also
change user/group name to "_mandos".

* debian/mandos.postinst: Rename old "mandos" user and group to
                          "_mandos"; create "_mandos" user and group
                          if none exist.
* debian/mandos-client.postinst: - '' -

* initramfs-tools-hook: Try "_mandos" before "mandos" as user and
                        group name.

* mandos (_datetime_to_dbus_struct): New; was previously local.
  (Client.started): Renamed to "last_started".  All users changed.
  (Client.started): New; boolean.
  (Client.dbus_object_path): New.
  (Client.check_command): Renamed to "checker_command".  All users
                          changed.
  (Client.__init__): Set and use "self.dbus_object_path".  Set
                     "self.started".
  (Client.start): Update "self.started".  Emit "self.PropertyChanged"
                  signals for both "started" and "last_started".
  (Client.stop): Update "self.started".  Emit "self.PropertyChanged"
                 signal for "started".
  (Client.checker_callback): Take additional "command" argument.  All
                             callers changed. Emit
                             "self.PropertyChanged" signal.
  (Client.bump_timeout): Emit "self.PropertyChanged" signal for
                         "last_checked_ok".
  (Client.start_checker): Emit "self.PropertyChanged" signal for
                          "checker_running".
  (Client.stop_checker): Emit "self.PropertyChanged" signal for
                         "checker_running".
  (Client.still_valid): Bug fix: use "getattr(self, started, False)"
                        instead of "self.started" in case this client
                        object is so new that the "started" attribute
                        has not been created yet.
  (Client.IntervalChanged, Client.CheckerIsRunning, Client.GetChecker,
  Client.GetCreated, Client.GetFingerprint, Client.GetHost,
  Client.GetInterval, Client.GetName, Client.GetStarted,
  Client.GetTimeout, Client.StateChanged, Client.TimeoutChanged):
  Removed; all callers changed.
  (Client.CheckerCompleted): Add "condition" and "command" arguments.
                             All callers changed.
  (Client.GetAllProperties, Client.PropertyChanged): New.
  (Client.StillValid): Renamed to "IsStillValid".
  (Client.StartChecker): Changed to its own function to avoid the
                         return value from "Client.start_checker()".
  (Client.Stop): Changed to its own function to avoid the return value
                 from "Client.stop()".
  (main): Try "_mandos" before "mandos" as user and group name.
          Removed inner function "remove_from_clients".  New inner
          class "MandosServer".

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  -*- coding: utf-8 -*- */
 
2
/*
 
3
 * Passprompt - Read a password from usplash and output it
 
4
 * 
 
5
 * Copyright © 2008 Teddy Hogeborn
 
6
 * Copyright © 2008 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 <https://www.fukt.bsnet.se/~belorn/> and
 
23
 * <https://www.fukt.bsnet.se/~teddy/>.
 
24
 */
 
25
 
1
26
#define _GNU_SOURCE             /* asprintf() */
2
27
#include <signal.h>             /* sig_atomic_t, struct sigaction,
3
28
                                   sigemptyset(), sigaddset(), SIGINT,
5
30
                                   SIG_IGN, kill(), SIGKILL */
6
31
#include <stdbool.h>            /* bool, false, true */
7
32
#include <fcntl.h>              /* open(), O_WRONLY, O_RDONLY */
 
33
#include <iso646.h>             /* and, or, not*/
8
34
#include <errno.h>              /* errno, EINTR */
9
 
#include <sys/types.h>          /* size_t, ssize_t, pid_t, DIR,
10
 
                                   struct dirent */
 
35
#include <sys/types.h>          /* size_t, ssize_t, pid_t, DIR, struct
 
36
                                   dirent */
11
37
#include <stddef.h>             /* NULL */
12
38
#include <string.h>             /* strlen(), memcmp() */
13
39
#include <stdio.h>              /* asprintf(), perror() */
21
47
                                   _exit() */
22
48
#include <stdlib.h>             /* getenv() */
23
49
#include <dirent.h>             /* opendir(), readdir(), closedir() */
24
 
 
25
 
 
26
 
 
27
 
#include <iso646.h>             /* and */
28
 
#include <sys/wait.h>           /* waitpid(), WIFEXITED(),
29
 
                                   WEXITSTATUS() */
 
50
#include <sys/stat.h>           /* struct stat, lstat(), S_ISLNK */
30
51
 
31
52
sig_atomic_t interrupted_by_signal = 0;
32
53
 
36
57
 
37
58
static bool usplash_write(const char *cmd, const char *arg){
38
59
  /* 
39
 
   * usplash_write("TIMEOUT", "15"); -> "TIMEOUT 15\0"
40
 
   * usplash_write("PULSATE", NULL); -> "PULSATE\0"
 
60
   * usplash_write("TIMEOUT", "15") will write "TIMEOUT 15\0"
 
61
   * usplash_write("PULSATE", NULL) will write "PULSATE\0"
41
62
   * SEE ALSO
42
63
   *         usplash_write(8)
43
64
   */
157
178
         /proc/<pid>/exe link */
158
179
      char exe_target[sizeof(usplash_name)];
159
180
      {
 
181
        /* create file name string */
160
182
        char *exe_link;
161
183
        ret = asprintf(&exe_link, "/proc/%s/exe", proc_ent->d_name);
162
184
        if(ret == -1){
165
187
          closedir(proc_dir);
166
188
          return EXIT_FAILURE;
167
189
        }
 
190
        
 
191
        /* Check that it refers to a symlink owned by root:root */
 
192
        struct stat exe_stat;
 
193
        ret = lstat(exe_link, &exe_stat);
 
194
        if(ret == -1){
 
195
          perror("lstat");
 
196
          free(exe_link);
 
197
          free(prompt);
 
198
          closedir(proc_dir);
 
199
          return EXIT_FAILURE;
 
200
        }
 
201
        if(not S_ISLNK(exe_stat.st_mode)
 
202
           or exe_stat.st_uid != 0
 
203
           or exe_stat.st_gid != 0){
 
204
          free(exe_link);
 
205
          continue;
 
206
        }
 
207
        
168
208
        sret = readlink(exe_link, exe_target, sizeof(exe_target));
169
209
        free(exe_link);
170
210
        if(sret == -1){
253
293
      free(prompt);
254
294
      return EXIT_FAILURE;
255
295
    }
256
 
    if (old_action.sa_handler != SIG_IGN){
 
296
    if(old_action.sa_handler != SIG_IGN){
257
297
      ret = sigaction(SIGINT, &new_action, NULL);
258
298
      if(ret == -1){
259
299
        perror("sigaction");
267
307
      free(prompt);
268
308
      return EXIT_FAILURE;
269
309
    }
270
 
    if (old_action.sa_handler != SIG_IGN){
 
310
    if(old_action.sa_handler != SIG_IGN){
271
311
      ret = sigaction(SIGHUP, &new_action, NULL);
272
312
      if(ret == -1){
273
313
        perror("sigaction");
281
321
      free(prompt);
282
322
      return EXIT_FAILURE;
283
323
    }
284
 
    if (old_action.sa_handler != SIG_IGN){
 
324
    if(old_action.sa_handler != SIG_IGN){
285
325
      ret = sigaction(SIGTERM, &new_action, NULL);
286
326
      if(ret == -1){
287
327
        perror("sigaction");
407
447
      return EXIT_SUCCESS;
408
448
    }
409
449
    break;                      /* Big */
410
 
  }
 
450
  }                             /* end of non-loop while() */
411
451
  
412
452
  /* If we got here, an error or interrupt must have happened */
413
453
  
 
454
  /* Create argc and argv for new usplash*/
414
455
  int cmdline_argc = 0;
415
456
  char **cmdline_argv = malloc(sizeof(char *));
416
 
  /* Create argv and argc for new usplash*/
417
457
  {
418
458
    size_t position = 0;
419
459
    while(position < cmdline_len){
431
471
      position += strlen(cmdline + position) + 1;
432
472
    }
433
473
    cmdline_argv[cmdline_argc] = NULL;
434
 
    free(cmdline);
435
474
  }
436
475
  /* Kill old usplash */
437
 
    kill(usplash_pid, SIGTERM);
438
 
    sleep(2);
 
476
  kill(usplash_pid, SIGTERM);
 
477
  sleep(2);
439
478
  while(kill(usplash_pid, 0) == 0){
440
479
    kill(usplash_pid, SIGKILL);
441
480
    sleep(1);
447
486
    /* Make the effective user ID (root) the only user ID instead of
448
487
       the real user ID (mandos) */
449
488
    ret = setuid(geteuid());
450
 
    if (ret == -1){
 
489
    if(ret == -1){
451
490
      perror("setuid");
452
491
    }
453
492
    
463
502
    }
464
503
    
465
504
    execv(usplash_name, cmdline_argv);
466
 
    perror("execv");
 
505
    if(not interrupted_by_signal){
 
506
      perror("execv");
 
507
    }
 
508
    free(cmdline);
467
509
    free(cmdline_argv);
468
510
    _exit(EXIT_FAILURE);
469
511
  }
 
512
  free(cmdline);
470
513
  free(cmdline_argv);
471
514
  sleep(2);
472
515
  if(not usplash_write("PULSATE", NULL)