=== modified file '.bzrignore' --- .bzrignore 2008-09-30 07:23:39 +0000 +++ .bzrignore 2008-10-03 09:32:30 +0000 @@ -7,6 +7,7 @@ keydir man plugin-runner +plugins.d/askpass-fifo plugins.d/mandos-client plugins.d/password-prompt plugins.d/splashy === modified file 'Makefile' --- Makefile 2008-09-30 18:59:44 +0000 +++ Makefile 2008-10-03 09:32:30 +0000 @@ -9,7 +9,7 @@ #DEBUG=-ggdb3 # For info about _FORTIFY_SOURCE, see # -FORTIFY=-D_FORTIFY_SOURCE=2 # -fstack-protector-all +FORTIFY=-D_FORTIFY_SOURCE=2 -fstack-protector-all #COVERAGE=--coverage OPTIMIZE=-Os LANGUAGE=-std=gnu99 @@ -149,10 +149,10 @@ $(SED) --in-place --expression='s/^\($$/\1$(version)"/' $@ mandos: Makefile - $(SED) --in-place --expression='s/^\(version = "\)[^"]*"/\1$(version)"/' $@ + $(SED) --in-place --expression='s/^\(version = "\)[^"]*"$$/\1$(version)"/' $@ mandos-keygen: Makefile - $(SED) --in-place --expression='s/^\(VERSION="\)[^"]*"/\1$(version)"/' $@ + $(SED) --in-place --expression='s/^\(VERSION="\)[^"]*"$$/\1$(version)"/' $@ plugins.d/mandos-client: plugins.d/mandos-client.o $(LINK.o) $(GNUTLS_LIBS) $(AVAHI_LIBS) $(GPGME_LIBS) \ === modified file 'mandos' --- mandos 2008-09-26 21:54:54 +0000 +++ mandos 2008-10-03 09:32:30 +0000 @@ -240,7 +240,8 @@ if "secret" in config: self.secret = config["secret"].decode(u"base64") elif "secfile" in config: - secfile = open(config["secfile"]) + secfile = open(os.path.expanduser(os.path.expandvars + (config["secfile"]))) self.secret = secfile.read() secfile.close() else: === modified file 'plugins.d/splashy.c' --- plugins.d/splashy.c 2008-09-24 23:03:31 +0000 +++ plugins.d/splashy.c 2008-10-03 09:32:30 +0000 @@ -1,20 +1,22 @@ #define _GNU_SOURCE /* asprintf() */ #include /* sig_atomic_t, struct sigaction, - sigemptyset(), sigaddset(), - sigaction, SIGINT, SIG_IGN, SIGHUP, - SIGTERM, kill(), SIGKILL */ + sigemptyset(), sigaddset(), SIGINT, + SIGHUP, SIGTERM, sigaction, + SIG_IGN, kill(), SIGKILL */ #include /* NULL */ #include /* getenv() */ #include /* asprintf(), perror() */ -#include /* EXIT_FAILURE, EXIT_SUCCESS, - strtoul(), free() */ +#include /* EXIT_FAILURE, free(), strtoul(), + EXIT_SUCCESS */ #include /* pid_t, DIR, struct dirent, ssize_t */ #include /* opendir(), readdir(), closedir() */ +#include /* struct stat, lstat(), S_ISLNK */ +#include /* not, or, and */ #include /* readlink(), fork(), execl(), - _exit */ + sleep(), dup2() STDERR_FILENO, + STDOUT_FILENO, _exit() */ #include /* memcmp() */ -#include /* and */ #include /* errno */ #include /* waitpid(), WIFEXITED(), WEXITSTATUS() */ @@ -88,6 +90,24 @@ closedir(proc_dir); return EXIT_FAILURE; } + + /* Check that it refers to a symlink owned by root:root */ + struct stat exe_stat; + ret = lstat(exe_link, &exe_stat); + if(ret == -1){ + perror("lstat"); + free(exe_link); + free(prompt); + closedir(proc_dir); + return EXIT_FAILURE; + } + if(not S_ISLNK(exe_stat.st_mode) + or exe_stat.st_uid != 0 + or exe_stat.st_gid != 0){ + free(exe_link); + continue; + } + sret = readlink(exe_link, exe_target, sizeof(exe_target)); free(exe_link); } @@ -120,7 +140,7 @@ free(prompt); return EXIT_FAILURE; } - if (old_action.sa_handler != SIG_IGN){ + if(old_action.sa_handler != SIG_IGN){ ret = sigaction(SIGINT, &new_action, NULL); if(ret == -1){ perror("sigaction"); @@ -134,7 +154,7 @@ free(prompt); return EXIT_FAILURE; } - if (old_action.sa_handler != SIG_IGN){ + if(old_action.sa_handler != SIG_IGN){ ret = sigaction(SIGHUP, &new_action, NULL); if(ret == -1){ perror("sigaction"); @@ -148,7 +168,7 @@ free(prompt); return EXIT_FAILURE; } - if (old_action.sa_handler != SIG_IGN){ + if(old_action.sa_handler != SIG_IGN){ ret = sigaction(SIGTERM, &new_action, NULL); if(ret == -1){ perror("sigaction"); @@ -173,13 +193,11 @@ const char splashy_command[] = "/sbin/splashy_update"; ret = execl(splashy_command, splashy_command, prompt, (char *)NULL); - if(not interrupted_by_signal and errno != ENOENT){ - /* Don't report "File not found", since splashy might not be - installed. */ + if(not interrupted_by_signal){ perror("execl"); } free(prompt); - return EXIT_FAILURE; + _exit(EXIT_FAILURE); } } @@ -187,33 +205,61 @@ free(prompt); /* Wait for command to complete */ - int status; - while(not interrupted_by_signal){ - waitpid(splashy_command_pid, &status, 0); - if(not interrupted_by_signal - and WIFEXITED(status) and WEXITSTATUS(status)==0){ - return EXIT_SUCCESS; + if(not interrupted_by_signal and splashy_command_pid != 0){ + int status; + ret = waitpid(splashy_command_pid, &status, 0); + if(ret == -1){ + if(errno != EINTR){ + perror("waitpid"); + } + if(errno == ECHILD){ + splashy_command_pid = 0; + } + } else { + /* The child process has exited */ + splashy_command_pid = 0; + if(not interrupted_by_signal and WIFEXITED(status) + and WEXITSTATUS(status)==0){ + return EXIT_SUCCESS; + } } } kill(splashy_pid, SIGTERM); - if(interrupted_by_signal){ + if(interrupted_by_signal and splashy_command_pid != 0){ kill(splashy_command_pid, SIGTERM); } - + sleep(2); + while(kill(splashy_pid, 0) == 0){ + kill(splashy_pid, SIGKILL); + sleep(1); + } pid_t new_splashy_pid = fork(); if(new_splashy_pid == 0){ /* Child; will become new splashy process */ - while(kill(splashy_pid, 0)){ - sleep(2); - kill(splashy_pid, SIGKILL); - sleep(1); + + /* Make the effective user ID (root) the only user ID instead of + the real user ID (mandos) */ + ret = setuid(geteuid()); + if(ret == -1){ + perror("setuid"); } + + setsid(); + ret = chdir("/"); +/* if(fork() != 0){ */ +/* _exit(EXIT_SUCCESS); */ +/* } */ ret = dup2(STDERR_FILENO, STDOUT_FILENO); /* replace our stdout */ if(ret == -1){ perror("dup2"); _exit(EXIT_FAILURE); } + execl("/sbin/splashy", "/sbin/splashy", "boot", (char *)NULL); + if(not interrupted_by_signal){ + perror("execl"); + } + _exit(EXIT_FAILURE); } return EXIT_FAILURE; === modified file 'plugins.d/usplash.c' --- plugins.d/usplash.c 2008-09-26 19:27:46 +0000 +++ plugins.d/usplash.c 2008-10-03 09:32:30 +0000 @@ -5,9 +5,10 @@ SIG_IGN, kill(), SIGKILL */ #include /* bool, false, true */ #include /* open(), O_WRONLY, O_RDONLY */ +#include /* and, or, not*/ #include /* errno, EINTR */ -#include /* size_t, ssize_t, pid_t, DIR, - struct dirent */ +#include /* size_t, ssize_t, pid_t, DIR, struct + dirent */ #include /* NULL */ #include /* strlen(), memcmp() */ #include /* asprintf(), perror() */ @@ -21,12 +22,7 @@ _exit() */ #include /* getenv() */ #include /* opendir(), readdir(), closedir() */ - - - -#include /* and */ -#include /* waitpid(), WIFEXITED(), - WEXITSTATUS() */ +#include /* struct stat, lstat(), S_ISLNK */ sig_atomic_t interrupted_by_signal = 0; @@ -36,8 +32,8 @@ static bool usplash_write(const char *cmd, const char *arg){ /* - * usplash_write("TIMEOUT", "15"); -> "TIMEOUT 15\0" - * usplash_write("PULSATE", NULL); -> "PULSATE\0" + * usplash_write("TIMEOUT", "15") will write "TIMEOUT 15\0" + * usplash_write("PULSATE", NULL) will write "PULSATE\0" * SEE ALSO * usplash_write(8) */ @@ -157,6 +153,7 @@ /proc//exe link */ char exe_target[sizeof(usplash_name)]; { + /* create file name string */ char *exe_link; ret = asprintf(&exe_link, "/proc/%s/exe", proc_ent->d_name); if(ret == -1){ @@ -165,6 +162,24 @@ closedir(proc_dir); return EXIT_FAILURE; } + + /* Check that it refers to a symlink owned by root:root */ + struct stat exe_stat; + ret = lstat(exe_link, &exe_stat); + if(ret == -1){ + perror("lstat"); + free(exe_link); + free(prompt); + closedir(proc_dir); + return EXIT_FAILURE; + } + if(not S_ISLNK(exe_stat.st_mode) + or exe_stat.st_uid != 0 + or exe_stat.st_gid != 0){ + free(exe_link); + continue; + } + sret = readlink(exe_link, exe_target, sizeof(exe_target)); free(exe_link); if(sret == -1){ @@ -253,7 +268,7 @@ free(prompt); return EXIT_FAILURE; } - if (old_action.sa_handler != SIG_IGN){ + if(old_action.sa_handler != SIG_IGN){ ret = sigaction(SIGINT, &new_action, NULL); if(ret == -1){ perror("sigaction"); @@ -267,7 +282,7 @@ free(prompt); return EXIT_FAILURE; } - if (old_action.sa_handler != SIG_IGN){ + if(old_action.sa_handler != SIG_IGN){ ret = sigaction(SIGHUP, &new_action, NULL); if(ret == -1){ perror("sigaction"); @@ -281,7 +296,7 @@ free(prompt); return EXIT_FAILURE; } - if (old_action.sa_handler != SIG_IGN){ + if(old_action.sa_handler != SIG_IGN){ ret = sigaction(SIGTERM, &new_action, NULL); if(ret == -1){ perror("sigaction"); @@ -407,13 +422,13 @@ return EXIT_SUCCESS; } break; /* Big */ - } + } /* end of non-loop while() */ /* If we got here, an error or interrupt must have happened */ + /* Create argc and argv for new usplash*/ int cmdline_argc = 0; char **cmdline_argv = malloc(sizeof(char *)); - /* Create argv and argc for new usplash*/ { size_t position = 0; while(position < cmdline_len){ @@ -433,8 +448,8 @@ cmdline_argv[cmdline_argc] = NULL; } /* Kill old usplash */ - kill(usplash_pid, SIGTERM); - sleep(2); + kill(usplash_pid, SIGTERM); + sleep(2); while(kill(usplash_pid, 0) == 0){ kill(usplash_pid, SIGKILL); sleep(1); @@ -446,7 +461,7 @@ /* Make the effective user ID (root) the only user ID instead of the real user ID (mandos) */ ret = setuid(geteuid()); - if (ret == -1){ + if(ret == -1){ perror("setuid"); } @@ -462,7 +477,9 @@ } execv(usplash_name, cmdline_argv); - perror("execv"); + if(not interrupted_by_signal){ + perror("execv"); + } free(cmdline); free(cmdline_argv); _exit(EXIT_FAILURE);