=== modified file 'TODO' --- TODO 2009-09-06 05:37:34 +0000 +++ TODO 2009-09-07 07:48:59 +0000 @@ -4,9 +4,12 @@ ** TODO [#A] Clean up /tmp directory and take down interface on signal :test: ** TODO [#B] use scandir(3) instead of readdir(3) ** TODO [#B] Prefix all debug output with argv[0] +** TODO [#B] Retry a server which has a non-definite reply. +*** A closed connection during the TLS handshake +*** A TCP timeout * splashy -** TODO [#A] Re-raise signal received when exiting due to handled signal. +** TODO [#A] Re-raise signal received when exiting due to handled signal :test: ** TODO [#B] use scandir(3) instead of readdir(3) ** TODO [#B] Prefix all debug output with argv[0] === modified file 'plugin-runner.c' --- plugin-runner.c 2009-09-06 05:37:34 +0000 +++ plugin-runner.c 2009-09-07 07:48:59 +0000 @@ -111,17 +111,17 @@ } /* Create a new plugin */ plugin *new_plugin = NULL; - do{ + do { new_plugin = malloc(sizeof(plugin)); - }while(new_plugin == NULL and errno == EINTR); + } while(new_plugin == NULL and errno == EINTR); if(new_plugin == NULL){ return NULL; } char *copy_name = NULL; if(name != NULL){ - do{ + do { copy_name = strdup(name); - }while(copy_name == NULL and errno == EINTR); + } while(copy_name == NULL and errno == EINTR); if(copy_name == NULL){ free(new_plugin); return NULL; @@ -133,9 +133,9 @@ .disabled = false, .next = plugin_list }; - do{ + do { new_plugin->argv = malloc(sizeof(char *) * 2); - }while(new_plugin->argv == NULL and errno == EINTR); + } while(new_plugin->argv == NULL and errno == EINTR); if(new_plugin->argv == NULL){ free(copy_name); free(new_plugin); @@ -144,9 +144,9 @@ new_plugin->argv[0] = copy_name; new_plugin->argv[1] = NULL; - do{ + do { new_plugin->environ = malloc(sizeof(char *)); - }while(new_plugin->environ == NULL and errno == EINTR); + } while(new_plugin->environ == NULL and errno == EINTR); if(new_plugin->environ == NULL){ free(copy_name); free(new_plugin->argv); @@ -164,19 +164,19 @@ static bool add_to_char_array(const char *new, char ***array, int *len){ /* Resize the pointed-to array to hold one more pointer */ - do{ + do { *array = realloc(*array, sizeof(char *) * (size_t) ((*len) + 2)); - }while(*array == NULL and errno == EINTR); + } while(*array == NULL and errno == EINTR); /* Malloc check */ if(*array == NULL){ return false; } /* Make a copy of the new string */ char *copy; - do{ + do { copy = strdup(new); - }while(copy == NULL and errno == EINTR); + } while(copy == NULL and errno == EINTR); if(copy == NULL){ return false; } @@ -209,9 +209,9 @@ /* It already exists */ if(replace){ char *new; - do{ + do { new = realloc(*e, strlen(def) + 1); - }while(new == NULL and errno == EINTR); + } while(new == NULL and errno == EINTR); if(new == NULL){ return false; } @@ -634,9 +634,9 @@ custom_argv[custom_argc] = NULL; } } - do{ + do { ret = fclose(conffp); - }while(ret == EOF and errno == EINTR); + } while(ret == EOF and errno == EINTR); if(ret == EOF){ perror("fclose"); exitstatus = EXIT_FAILURE; @@ -726,9 +726,9 @@ /* Read and execute any executable in the plugin directory*/ while(true){ - do{ + do { dirst = readdir(dir); - }while(dirst == NULL and errno == EINTR); + } while(dirst == NULL and errno == EINTR); /* All directory entries have been processed */ if(dirst == NULL){ @@ -890,9 +890,9 @@ } /* Starting a new process to be watched */ pid_t pid; - do{ + do { pid = fork(); - }while(pid == -1 and errno == EINTR); + } while(pid == -1 and errno == EINTR); if(pid == -1){ perror("fork"); exitstatus = EXIT_FAILURE; @@ -1159,7 +1159,7 @@ } /* Wait for any remaining child processes to terminate */ - do{ + do { ret = wait(NULL); } while(ret >= 0); if(errno != ECHILD){ === modified file 'plugins.d/askpass-fifo.c' --- plugins.d/askpass-fifo.c 2009-08-30 03:10:29 +0000 +++ plugins.d/askpass-fifo.c 2009-09-07 07:48:59 +0000 @@ -19,8 +19,7 @@ * along with this program. If not, see * . * - * Contact the authors at and - * . + * Contact the authors at . */ #define _GNU_SOURCE /* TEMP_FAILURE_RETRY() */ @@ -62,7 +61,7 @@ { size_t buf_allocated = 0; const size_t blocksize = 1024; - do{ + do { if(buf_len + blocksize > buf_allocated){ char *tmp = realloc(buf, buf_allocated + blocksize); if(tmp == NULL){ @@ -81,7 +80,7 @@ return EXIT_FAILURE; } buf_len += (size_t)sret; - }while(sret != 0); + } while(sret != 0); } /* Close FIFO */ === modified file 'plugins.d/mandos-client.c' --- plugins.d/mandos-client.c 2009-09-06 05:37:34 +0000 +++ plugins.d/mandos-client.c 2009-09-07 07:48:59 +0000 @@ -711,7 +711,7 @@ goto mandos_end; } - do{ + do { ret = gnutls_handshake(session); if(quit_now){ goto mandos_end; @@ -763,7 +763,7 @@ case GNUTLS_E_AGAIN: break; case GNUTLS_E_REHANDSHAKE: - do{ + do { ret = gnutls_handshake(session); if(quit_now){ === modified file 'plugins.d/password-prompt.c' --- plugins.d/password-prompt.c 2009-09-05 01:05:25 +0000 +++ plugins.d/password-prompt.c 2009-09-07 07:48:59 +0000 @@ -19,8 +19,7 @@ * along with this program. If not, see * . * - * Contact the authors at and - * . + * Contact the authors at . */ #define _GNU_SOURCE /* getline() */ === modified file 'plugins.d/splashy.c' --- plugins.d/splashy.c 2009-09-06 05:37:34 +0000 +++ plugins.d/splashy.c 2009-09-07 07:48:59 +0000 @@ -19,11 +19,10 @@ * along with this program. If not, see * . * - * Contact the authors at and - * . + * Contact the authors at . */ -#define _GNU_SOURCE /* asprintf() */ +#define _GNU_SOURCE /* TEMP_FAILURE_RETRY(), asprintf() */ #include /* sig_atomic_t, struct sigaction, sigemptyset(), sigaddset(), SIGINT, SIGHUP, SIGTERM, sigaction, @@ -41,7 +40,8 @@ #include /* not, or, and */ #include /* readlink(), fork(), execl(), sleep(), dup2() STDERR_FILENO, - STDOUT_FILENO, _exit() */ + STDOUT_FILENO, _exit(), + pause() */ #include /* memcmp() */ #include /* errno */ #include /* waitpid(), WIFEXITED(), @@ -61,9 +61,12 @@ int main(__attribute__((unused))int argc, __attribute__((unused))char **argv){ int ret = 0; + char *prompt = NULL; + DIR *proc_dir = NULL; + pid_t splashy_pid = 0; + pid_t splashy_command_pid = 0; /* Create prompt string */ - char *prompt = NULL; { const char *const cryptsource = getenv("cryptsource"); const char *const crypttarget = getenv("crypttarget"); @@ -86,19 +89,18 @@ } } if(ret == -1){ - return EXIT_FAILURE; + prompt = NULL; + goto failure; } } /* Find splashy process */ - pid_t splashy_pid = 0; { const char splashy_name[] = "/sbin/splashy"; - DIR *proc_dir = opendir("/proc"); + proc_dir = opendir("/proc"); if(proc_dir == NULL){ - free(prompt); perror("opendir"); - return EXIT_FAILURE; + goto failure; } for(struct dirent *proc_ent = readdir(proc_dir); proc_ent != NULL; @@ -125,9 +127,7 @@ ret = asprintf(&exe_link, "/proc/%s/exe", proc_ent->d_name); if(ret == -1){ perror("asprintf"); - free(prompt); - closedir(proc_dir); - return EXIT_FAILURE; + goto failure; } /* Check that it refers to a symlink owned by root:root */ @@ -140,9 +140,7 @@ } perror("lstat"); free(exe_link); - free(prompt); - closedir(proc_dir); - return EXIT_FAILURE; + goto failure; } if(not S_ISLNK(exe_stat.st_mode) or exe_stat.st_uid != 0 @@ -162,10 +160,10 @@ } } closedir(proc_dir); + proc_dir = NULL; } if(splashy_pid == 0){ - free(prompt); - return EXIT_FAILURE; + goto failure; } /* Set up the signal handler */ @@ -177,147 +175,177 @@ sigaddset(&new_action.sa_mask, SIGINT); if(ret == -1){ perror("sigaddset"); - free(prompt); - return EXIT_FAILURE; + goto failure; } sigaddset(&new_action.sa_mask, SIGHUP); if(ret == -1){ perror("sigaddset"); - free(prompt); - return EXIT_FAILURE; + goto failure; } sigaddset(&new_action.sa_mask, SIGTERM); if(ret == -1){ perror("sigaddset"); - free(prompt); - return EXIT_FAILURE; + goto failure; } ret = sigaction(SIGINT, NULL, &old_action); if(ret == -1){ perror("sigaction"); - free(prompt); - return EXIT_FAILURE; + goto failure; } if(old_action.sa_handler != SIG_IGN){ ret = sigaction(SIGINT, &new_action, NULL); if(ret == -1){ perror("sigaction"); - free(prompt); - return EXIT_FAILURE; + goto failure; } } ret = sigaction(SIGHUP, NULL, &old_action); if(ret == -1){ perror("sigaction"); - free(prompt); - return EXIT_FAILURE; + goto failure; } if(old_action.sa_handler != SIG_IGN){ ret = sigaction(SIGHUP, &new_action, NULL); if(ret == -1){ perror("sigaction"); - free(prompt); - return EXIT_FAILURE; + goto failure; } } ret = sigaction(SIGTERM, NULL, &old_action); if(ret == -1){ perror("sigaction"); - free(prompt); - return EXIT_FAILURE; + goto failure; } if(old_action.sa_handler != SIG_IGN){ ret = sigaction(SIGTERM, &new_action, NULL); if(ret == -1){ perror("sigaction"); - free(prompt); - return EXIT_FAILURE; + goto failure; } } } + if(interrupted_by_signal){ + goto failure; + } + /* Fork off the splashy command to prompt for password */ - pid_t splashy_command_pid = 0; - if(not interrupted_by_signal){ - splashy_command_pid = fork(); - if(splashy_command_pid == -1){ - if(not interrupted_by_signal){ - perror("fork"); - } - return EXIT_FAILURE; - } - /* Child */ - if(splashy_command_pid == 0){ + splashy_command_pid = fork(); + if(splashy_command_pid != 0 and interrupted_by_signal){ + goto failure; + } + if(splashy_command_pid == -1){ + perror("fork"); + goto failure; + } + /* Child */ + if(splashy_command_pid == 0){ + if(not interrupted_by_signal){ const char splashy_command[] = "/sbin/splashy_update"; - ret = execl(splashy_command, splashy_command, prompt, - (char *)NULL); - if(not interrupted_by_signal){ - perror("execl"); - } - free(prompt); - _exit(EXIT_FAILURE); + execl(splashy_command, splashy_command, prompt, (char *)NULL); + perror("execl"); } + free(prompt); + _exit(EXIT_FAILURE); } /* Parent */ free(prompt); + prompt = NULL; + + if(interrupted_by_signal){ + goto failure; + } /* Wait for command to complete */ - if(not interrupted_by_signal and splashy_command_pid != 0){ + { int status; - ret = waitpid(splashy_command_pid, &status, 0); + do { + ret = waitpid(splashy_command_pid, &status, 0); + } while(ret == -1 and errno == EINTR + and not interrupted_by_signal); + if(interrupted_by_signal){ + goto failure; + } if(ret == -1){ - if(errno != EINTR){ - perror("waitpid"); - } + 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){ + if(WIFEXITED(status) and WEXITSTATUS(status) == 0){ return EXIT_SUCCESS; } } } - kill(splashy_pid, SIGTERM); - 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 */ + + failure: + + free(prompt); + + if(proc_dir != NULL){ + TEMP_FAILURE_RETRY(closedir(proc_dir)); + } + + if(splashy_command_pid != 0){ + TEMP_FAILURE_RETRY(kill(splashy_command_pid, SIGTERM)); - /* 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"); + TEMP_FAILURE_RETRY(kill(splashy_pid, SIGTERM)); + sleep(2); + while(TEMP_FAILURE_RETRY(kill(splashy_pid, 0)) == 0){ + TEMP_FAILURE_RETRY(kill(splashy_pid, SIGKILL)); + sleep(1); } + pid_t new_splashy_pid = TEMP_FAILURE_RETRY(fork()); + if(new_splashy_pid == 0){ + /* Child; will become new splashy process */ + + /* 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(ret == -1){ + perror("chdir"); + } +/* if(fork() != 0){ */ +/* _exit(EXIT_SUCCESS); */ +/* } */ + ret = dup2(STDERR_FILENO, STDOUT_FILENO); /* replace stdout */ + if(ret == -1){ + perror("dup2"); + _exit(EXIT_FAILURE); + } - setsid(); - ret = chdir("/"); -/* if(fork() != 0){ */ -/* _exit(EXIT_SUCCESS); */ -/* } */ - ret = dup2(STDERR_FILENO, STDOUT_FILENO); /* replace our stdout */ - if(ret == -1){ - perror("dup2"); + execl("/sbin/splashy", "/sbin/splashy", "boot", (char *)NULL); + perror("execl"); _exit(EXIT_FAILURE); } - - execl("/sbin/splashy", "/sbin/splashy", "boot", (char *)NULL); - if(not interrupted_by_signal){ - perror("execl"); - } - _exit(EXIT_FAILURE); + } + + if(interrupted_by_signal){ + struct sigaction signal_action; + sigemptyset(&signal_action.sa_mask); + signal_action.sa_handler = SIG_DFL; + ret = TEMP_FAILURE_RETRY(sigaction(signal_received, + &signal_action, NULL)); + if(ret == -1){ + perror("sigaction"); + } + do { + ret = raise(signal_received); + } while(ret != 0 and errno == EINTR); + if(ret != 0){ + perror("raise"); + abort(); + } + TEMP_FAILURE_RETRY(pause()); } return EXIT_FAILURE; === modified file 'plugins.d/usplash.c' --- plugins.d/usplash.c 2009-02-12 18:56:52 +0000 +++ plugins.d/usplash.c 2009-09-07 07:48:59 +0000 @@ -19,8 +19,7 @@ * along with this program. If not, see * . * - * Contact the authors at and - * . + * Contact the authors at . */ #define _GNU_SOURCE /* asprintf() */ @@ -64,12 +63,12 @@ */ int ret; int fifo_fd; - do{ + do { fifo_fd = open("/dev/.initramfs/usplash_fifo", O_WRONLY); if(fifo_fd == -1 and (errno != EINTR or interrupted_by_signal)){ return false; } - }while(fifo_fd == -1); + } while(fifo_fd == -1); const char *cmd_line; size_t cmd_line_len; @@ -77,8 +76,8 @@ if(arg == NULL){ cmd_line = cmd; cmd_line_len = strlen(cmd); - }else{ - do{ + } else { + do { ret = asprintf(&cmd_line_alloc, "%s %s", cmd, arg); if(ret == -1 and (errno != EINTR or interrupted_by_signal)){ int e = errno; @@ -86,7 +85,7 @@ errno = e; return false; } - }while(ret == -1); + } while(ret == -1); cmd_line = cmd_line_alloc; cmd_line_len = (size_t)ret + 1; } @@ -110,12 +109,12 @@ written += (size_t)sret; } free(cmd_line_alloc); - do{ + do { ret = close(fifo_fd); if(ret == -1 and (errno != EINTR or interrupted_by_signal)){ return false; } - }while(ret == -1); + } while(ret == -1); if(interrupted_by_signal){ return false; } @@ -252,7 +251,7 @@ size_t cmdline_allocated = 0; char *tmp; const size_t blocksize = 1024; - do{ + do { if(cmdline_len + blocksize > cmdline_allocated){ tmp = realloc(cmdline, cmdline_allocated + blocksize); if(tmp == NULL){ @@ -366,7 +365,7 @@ /* Open FIFO */ int fifo_fd; - do{ + do { fifo_fd = open("/dev/.initramfs/usplash_outfifo", O_RDONLY); if(fifo_fd == -1){ if(errno != EINTR){ @@ -378,7 +377,7 @@ break; } } - }while(fifo_fd == -1); + } while(fifo_fd == -1); if(interrupted_by_signal or an_error_occured){ break; /* Big */ } @@ -386,7 +385,7 @@ /* Read from FIFO */ size_t buf_allocated = 0; const size_t blocksize = 1024; - do{ + do { if(buf_len + blocksize > buf_allocated){ char *tmp = realloc(buf, buf_allocated + blocksize); if(tmp == NULL){ @@ -397,7 +396,7 @@ buf = tmp; buf_allocated += blocksize; } - do{ + do { sret = read(fifo_fd, buf + buf_len, buf_allocated - buf_len); if(sret == -1){ if(errno != EINTR){ @@ -409,13 +408,13 @@ break; } } - }while(sret == -1); + } while(sret == -1); if(interrupted_by_signal or an_error_occured){ break; } buf_len += (size_t)sret; - }while(sret != 0); + } while(sret != 0); close(fifo_fd); if(interrupted_by_signal or an_error_occured){ break; /* Big */ @@ -433,7 +432,7 @@ /* Print password to stdout */ size_t written = 0; while(written < buf_len){ - do{ + do { sret = write(STDOUT_FILENO, buf + written, buf_len - written); if(sret == -1){ if(errno != EINTR){ @@ -445,7 +444,7 @@ break; } } - }while(sret == -1); + } while(sret == -1); if(interrupted_by_signal or an_error_occured){ break; }