=== modified file 'Makefile' --- Makefile 2011-07-13 01:11:12 +0000 +++ Makefile 2011-07-13 02:24:39 +0000 @@ -210,7 +210,7 @@ $@) plugins.d/mandos-client: plugins.d/mandos-client.c - $(LINK.c) $^ $(GNUTLS_LIBS) $(AVAHI_LIBS) $(strip\ + $(LINK.c) $^ -lrt $(GNUTLS_LIBS) $(AVAHI_LIBS) $(strip\ ) $(GPGME_LIBS) $(LOADLIBES) $(LDLIBS) -o $@ .PHONY : all doc html clean distclean run-client run-server install \ === modified file 'TODO' --- TODO 2011-07-13 01:11:12 +0000 +++ TODO 2011-07-13 02:24:39 +0000 @@ -7,13 +7,7 @@ * Convert README into intro(8mandos) man page * mandos-client -** TODO [#B] use scandir(3) instead of readdir(3) -** TODO [#B] Prefix all debug output with "Mandos plugin " + program_invocation_short_name -** TODO [#B] Retry a server which has a non-definite reply: -*** A closed connection during the TLS handshake -*** A TCP timeout ** TODO [#B] Use capabilities instead of seteuid(). -** TODO [#A] Retry --connect forever ** TODO [#B] Use struct sockaddr_storage instead of a union ** TODO [#B] Use getaddrinfo(hints=AI_NUMERICHOST) instead of inet_pton() ** TODO [#B] Use getnameinfo(serv=NULL, NI_NUMERICHOST) instead of inet_ntop() @@ -21,20 +15,16 @@ * splashy ** TODO [#B] use scandir(3) instead of readdir(3) -** TODO [#B] Prefix all debug output with "Mandos plugin " + program_invocation_short_name * usplash ** TODO [#A] Make it work again ** TODO [#B] use scandir(3) instead of readdir(3) -** TODO [#B] Prefix all debug output with "Mandos plugin " + program_invocation_short_name ** TODO Use [[info:libc:Argz%20Functions][argz_extract]] * askpass-fifo -** TODO [#B] Prefix all debug output with "Mandos plugin " + program_invocation_short_name ** TODO [#B] Drop privileges after opening FIFO. * password-prompt -** TODO [#B] Prefix all debug output with "Mandos plugin " + program_invocation_short_name ** TODO [#B] lock stdin (with flock()?) ** TODO [#A] Free direntries after scandir() @@ -44,6 +34,8 @@ * TODO [#B] passdev * plugin-runner +** TODO handle printing for errors for plugins +*** Hook up stderr of plugins, buffer them, and prepend mandos pluig [plugin name] ** TODO [#B] use scandir(3) instead of readdir(3) ** TODO [#C] use same file name rules as run-parts(8) ** kernel command line option for debug info @@ -110,7 +102,7 @@ arguments. * mandos-monitor -** TODO help should be toggable +** TODO help should be toggleable ** Urwid client data displayer Better view of client data in the listing *** Properties popup === modified file 'mandos' --- mandos 2011-04-03 00:46:51 +0000 +++ mandos 2011-06-23 22:27:15 +0000 @@ -1268,7 +1268,7 @@ while True: if not client.enabled: - logger.warning("Client %s is disabled", + logger.info("Client %s is disabled", client.name) if self.server.use_dbus: # Emit D-Bus signal @@ -1569,8 +1569,8 @@ client = c break else: - logger.warning("Client not found for fingerprint: %s, ad" - "dress: %s", fpr, address) + logger.info("Client not found for fingerprint: %s, ad" + "dress: %s", fpr, address) if self.use_dbus: # Emit D-Bus signal mandos_dbus_service.ClientNotFound(fpr, address[0]) === modified file 'plugins.d/askpass-fifo.c' --- plugins.d/askpass-fifo.c 2011-03-17 18:28:22 +0000 +++ plugins.d/askpass-fifo.c 2011-07-13 02:24:39 +0000 @@ -32,6 +32,8 @@ ENFILE, ENOMEM, EBADF, EINVAL, EIO, EISDIR, EFBIG */ #include /* error() */ +#include /* fprintf(), vfprintf(), + vasprintf() */ #include /* EXIT_FAILURE, NULL, size_t, free(), realloc(), EXIT_SUCCESS */ #include /* open(), O_RDONLY */ @@ -39,7 +41,32 @@ STDOUT_FILENO */ #include /* EX_OSERR, EX_OSFILE, EX_UNAVAILABLE, EX_IOERR */ - +#include /* strerror() */ +#include /* va_list, va_start(), ... */ + + +/* Function to use when printing errors */ +void error_plus(int status, int errnum, const char *formatstring, + ...){ + va_list ap; + char *text; + int ret; + + va_start(ap, formatstring); + ret = vasprintf(&text, formatstring, ap); + if (ret == -1){ + fprintf(stderr, "Mandos plugin %s: ", + program_invocation_short_name); + vfprintf(stderr, formatstring, ap); + fprintf(stderr, ": "); + fprintf(stderr, "%s\n", strerror(errnum)); + error(status, errno, "vasprintf while printing error"); + return; + } + fprintf(stderr, "Mandos plugin "); + error(status, errnum, "%s", text); + free(text); +} int main(__attribute__((unused))int argc, __attribute__((unused))char **argv){ @@ -55,15 +82,15 @@ case EACCES: case ENOTDIR: case ELOOP: - error(EX_OSFILE, errno, "mkfifo"); + error_plus(EX_OSFILE, errno, "mkfifo"); case ENAMETOOLONG: case ENOSPC: case EROFS: default: - error(EX_OSERR, errno, "mkfifo"); + error_plus(EX_OSERR, errno, "mkfifo"); case ENOENT: /* no "/lib/cryptsetup"? */ - error(EX_UNAVAILABLE, errno, "mkfifo"); + error_plus(EX_UNAVAILABLE, errno, "mkfifo"); case EEXIST: break; /* not an error */ } @@ -73,7 +100,7 @@ int fifo_fd = open(passfifo, O_RDONLY); if(fifo_fd == -1){ int e = errno; - error(0, errno, "open"); + error_plus(0, errno, "open"); switch(e){ case EACCES: case ENOENT: @@ -101,7 +128,7 @@ if(buf_len + blocksize > buf_allocated){ char *tmp = realloc(buf, buf_allocated + blocksize); if(tmp == NULL){ - error(0, errno, "realloc"); + error_plus(0, errno, "realloc"); free(buf); return EX_OSERR; } @@ -113,7 +140,7 @@ int e = errno; free(buf); errno = e; - error(0, errno, "read"); + error_plus(0, errno, "read"); switch(e){ case EBADF: case EFAULT: @@ -141,7 +168,7 @@ int e = errno; free(buf); errno = e; - error(0, errno, "write"); + error_plus(0, errno, "write"); switch(e){ case EBADF: case EFAULT: @@ -161,7 +188,7 @@ ret = close(STDOUT_FILENO); if(ret == -1){ int e = errno; - error(0, errno, "close"); + error_plus(0, errno, "close"); switch(e){ case EBADF: return EX_OSFILE; === modified file 'plugins.d/mandos-client.c' --- plugins.d/mandos-client.c 2011-07-13 01:11:12 +0000 +++ plugins.d/mandos-client.c 2011-07-13 02:24:39 +0000 @@ -62,7 +62,8 @@ #include /* PRIu16, PRIdMAX, intmax_t, strtoimax() */ #include /* assert() */ -#include /* perror(), errno */ +#include /* perror(), errno, + program_invocation_short_name */ #include /* nanosleep(), time(), sleep() */ #include /* ioctl, ifreq, SIOCGIFFLAGS, IFF_UP, SIOCSIFFLAGS, if_indextoname(), @@ -130,6 +131,17 @@ static const char sys_class_net[] = "/sys/class/net"; char *connect_to = NULL; +/* Doubly linked list that need to be circularly linked when used */ +typedef struct server{ + const char *ip; + uint16_t port; + AvahiIfIndex if_index; + int af; + struct timespec last_seen; + struct server *next; + struct server *prev; +} server; + /* Used for passing in values through the Avahi callback functions */ typedef struct { AvahiSimplePoll *simple_poll; @@ -139,16 +151,25 @@ gnutls_dh_params_t dh_params; const char *priority; gpgme_ctx_t ctx; + server *current_server; } mandos_context; /* global context so signal handler can reach it*/ mandos_context mc = { .simple_poll = NULL, .server = NULL, .dh_bits = 1024, .priority = "SECURE256" - ":!CTYPE-X.509:+CTYPE-OPENPGP" }; + ":!CTYPE-X.509:+CTYPE-OPENPGP", + .current_server = NULL }; sig_atomic_t quit_now = 0; int signal_received = 0; +/* Function to use when printing errors */ +void perror_plus(const char *print_text){ + fprintf(stderr, "Mandos plugin %s: ", + program_invocation_short_name); + perror(print_text); +} + /* * Make additional room in "buffer" for at least BUFFER_SIZE more * bytes. "buffer_capacity" is how much is currently allocated, @@ -166,6 +187,43 @@ return buffer_capacity; } +int add_server(const char *ip, uint16_t port, + AvahiIfIndex if_index, + int af){ + int ret; + server *new_server = malloc(sizeof(server)); + if(new_server == NULL){ + perror_plus("malloc"); + return -1; + } + *new_server = (server){ .ip = strdup(ip), + .port = port, + .if_index = if_index, + .af = af }; + if(new_server->ip == NULL){ + perror_plus("strdup"); + return -1; + } + /* unique case of first server */ + if (mc.current_server == NULL){ + new_server->next = new_server; + new_server->prev = new_server; + mc.current_server = new_server; + /* Placing the new server last in the list */ + } else { + new_server->next = mc.current_server; + new_server->prev = mc.current_server->prev; + new_server->prev->next = new_server; + mc.current_server->prev = new_server; + } + ret = clock_gettime(CLOCK_MONOTONIC, &mc.current_server->last_seen); + if(ret == -1){ + perror_plus("clock_gettime"); + return -1; + } + return 0; +} + /* * Initialize GPGME. */ @@ -185,7 +243,7 @@ fd = (int)TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); if(fd == -1){ - perror("open"); + perror_plus("open"); return false; } @@ -205,7 +263,7 @@ ret = (int)TEMP_FAILURE_RETRY(close(fd)); if(ret == -1){ - perror("close"); + perror_plus("close"); } gpgme_data_release(pgp_data); return true; @@ -336,7 +394,7 @@ /* Seek back to the beginning of the GPGME plaintext data buffer */ if(gpgme_data_seek(dh_plain, (off_t)0, SEEK_SET) == -1){ - perror("gpgme_data_seek"); + perror_plus("gpgme_data_seek"); plaintext_length = -1; goto decrypt_end; } @@ -347,7 +405,7 @@ (size_t)plaintext_length, plaintext_capacity); if(plaintext_capacity == 0){ - perror("incbuffer"); + perror_plus("incbuffer"); plaintext_length = -1; goto decrypt_end; } @@ -360,7 +418,7 @@ break; } if(ret < 0){ - perror("gpgme_data_read"); + perror_plus("gpgme_data_read"); plaintext_length = -1; goto decrypt_end; } @@ -586,7 +644,7 @@ tcp_sd = socket(pf, SOCK_STREAM, 0); if(tcp_sd < 0){ int e = errno; - perror("socket"); + perror_plus("socket"); errno = e; goto mandos_end; } @@ -606,7 +664,7 @@ } if(ret < 0 ){ int e = errno; - perror("inet_pton"); + perror_plus("inet_pton"); errno = e; goto mandos_end; } @@ -648,7 +706,7 @@ if(af == AF_INET6 and if_index != AVAHI_IF_UNSPEC){ char interface[IF_NAMESIZE]; if(if_indextoname((unsigned int)if_index, interface) == NULL){ - perror("if_indextoname"); + perror_plus("if_indextoname"); } else { fprintf(stderr, "Connection to: %s%%%s, port %" PRIu16 "\n", ip, interface, port); @@ -668,7 +726,7 @@ sizeof(addrstr)); } if(pcret == NULL){ - perror("inet_ntop"); + perror_plus("inet_ntop"); } else { if(strcmp(addrstr, ip) != 0){ fprintf(stderr, "Canonical address form: %s\n", addrstr); @@ -689,7 +747,7 @@ if(ret < 0){ if ((errno != ECONNREFUSED and errno != ENETUNREACH) or debug){ int e = errno; - perror("connect"); + perror_plus("connect"); errno = e; } goto mandos_end; @@ -708,7 +766,7 @@ out_size - written)); if(ret == -1){ int e = errno; - perror("write"); + perror_plus("write"); errno = e; goto mandos_end; } @@ -739,6 +797,7 @@ goto mandos_end; } + /* Spurious warning from -Wint-to-pointer-cast */ gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) tcp_sd); if(quit_now){ @@ -781,7 +840,7 @@ buffer_capacity); if(buffer_capacity == 0){ int e = errno; - perror("incbuffer"); + perror_plus("incbuffer"); errno = e; goto mandos_end; } @@ -892,14 +951,14 @@ if(e == 0){ e = errno; } - perror("close"); + perror_plus("close"); } gnutls_deinit(session); + errno = e; if(quit_now){ - e = EINTR; + errno = EINTR; retval = -1; } - errno = e; } return retval; } @@ -948,6 +1007,9 @@ avahi_proto_to_af(proto)); if(ret == 0){ avahi_simple_poll_quit(mc.simple_poll); + } else { + ret = add_server(ip, port, interface, + avahi_proto_to_af(proto)); } } } @@ -1007,7 +1069,7 @@ } } -/* stop main loop after sigterm has been called */ +/* Signal handler that stops main loop after SIGTERM */ static void handle_sigterm(int sig){ if(quit_now){ return; @@ -1015,6 +1077,7 @@ quit_now = 1; signal_received = sig; int old_errno = errno; + /* set main loop to exit */ if(mc.simple_poll != NULL){ avahi_simple_poll_quit(mc.simple_poll); } @@ -1035,12 +1098,12 @@ int ret = asprintf(&flagname, "%s/%s/flags", sys_class_net, if_entry->d_name); if(ret < 0){ - perror("asprintf"); + perror_plus("asprintf"); return 0; } int flags_fd = (int)TEMP_FAILURE_RETRY(open(flagname, O_RDONLY)); if(flags_fd == -1){ - perror("open"); + perror_plus("open"); free(flagname); return 0; } @@ -1051,7 +1114,7 @@ char *flagstring = malloc((size_t)to_read+1); /* +1 for final \0 */ flagstring[(size_t)to_read] = '\0'; if(flagstring == NULL){ - perror("malloc"); + perror_plus("malloc"); close(flags_fd); return 0; } @@ -1059,7 +1122,7 @@ ssret = (ssize_t)TEMP_FAILURE_RETRY(read(flags_fd, flagstring, (size_t)to_read)); if(ssret == -1){ - perror("read"); + perror_plus("read"); free(flagstring); close(flags_fd); return 0; @@ -1126,6 +1189,88 @@ return 1; } +int notdotentries(const struct dirent *direntry){ + /* Skip "." and ".." */ + if(direntry->d_name[0] == '.' + and (direntry->d_name[1] == '\0' + or (direntry->d_name[1] == '.' + and direntry->d_name[2] == '\0'))){ + return 0; + } + return 1; +} + +int avahi_loop_with_timeout(AvahiSimplePoll *s, int retry_interval){ + int ret; + struct timespec now; + struct timespec waited_time; + intmax_t block_time; + + while(true){ + if(mc.current_server == NULL){ + if (debug){ + fprintf(stderr, + "Wait until first server is found. No timeout!\n"); + } + ret = avahi_simple_poll_iterate(s, -1); + } else { + if (debug){ + fprintf(stderr, "Check current_server if we should run it," + " or wait\n"); + } + /* the current time */ + ret = clock_gettime(CLOCK_MONOTONIC, &now); + if(ret == -1){ + perror_plus("clock_gettime"); + return -1; + } + /* Calculating in ms how long time between now and server + who we visted longest time ago. Now - last seen. */ + waited_time.tv_sec = (now.tv_sec + - mc.current_server->last_seen.tv_sec); + waited_time.tv_nsec = (now.tv_nsec + - mc.current_server->last_seen.tv_nsec); + /* total time is 10s/10,000ms. + Converting to s from ms by dividing by 1,000, + and ns to ms by dividing by 1,000,000. */ + block_time = ((retry_interval + - ((intmax_t)waited_time.tv_sec * 1000)) + - ((intmax_t)waited_time.tv_nsec / 1000000)); + + if (debug){ + fprintf(stderr, "Blocking for %ld ms\n", block_time); + } + + if(block_time <= 0){ + ret = start_mandos_communication(mc.current_server->ip, + mc.current_server->port, + mc.current_server->if_index, + mc.current_server->af); + if(ret == 0){ + avahi_simple_poll_quit(mc.simple_poll); + return 0; + } + ret = clock_gettime(CLOCK_MONOTONIC, + &mc.current_server->last_seen); + if(ret == -1){ + perror_plus("clock_gettime"); + return -1; + } + mc.current_server = mc.current_server->next; + block_time = 0; /* Call avahi to find new Mandos + servers, but don't block */ + } + + ret = avahi_simple_poll_iterate(s, (int)block_time); + } + if(ret != 0){ + if (ret > 0 or errno != EINTR) { + return (ret != 1) ? ret : 0; + } + } + } +} + int main(int argc, char *argv[]){ AvahiSServiceBrowser *sb = NULL; int error; @@ -1148,6 +1293,8 @@ bool gnutls_initialized = false; bool gpgme_initialized = false; float delay = 2.5f; + double retry_interval = 10; /* 10s between trying a server and + retrying the same server again */ struct sigaction old_sigterm_action = { .sa_handler = SIG_DFL }; struct sigaction sigterm_action = { .sa_handler = handle_sigterm }; @@ -1159,14 +1306,14 @@ errno = 0; ret = setgid(gid); if(ret == -1){ - perror("setgid"); + perror_plus("setgid"); } /* Lower user privileges (temporarily) */ errno = 0; ret = seteuid(uid); if(ret == -1){ - perror("seteuid"); + perror_plus("seteuid"); } if(quit_now){ @@ -1207,6 +1354,10 @@ .arg = "SECONDS", .doc = "Maximum delay to wait for interface startup", .group = 2 }, + { .name = "retry", .key = 132, + .arg = "SECONDS", + .doc = "Retry interval used when denied by the mandos server", + .group = 2 }, /* * These reproduce what we would get without ARGP_NO_HELP */ @@ -1256,6 +1407,13 @@ if(errno != 0 or tmp == arg or *tmp != '\0'){ argp_error(state, "Bad delay"); } + case 132: /* --retry */ + errno = 0; + retry_interval = strtod(arg, &tmp); + if(errno != 0 or tmp == arg or *tmp != '\0' + or (retry_interval * 1000) > INT_MAX){ + argp_error(state, "Bad retry interval"); + } break; /* * These reproduce what we would get without ARGP_NO_HELP @@ -1289,7 +1447,7 @@ case ENOMEM: default: errno = ret; - perror("argp_parse"); + perror_plus("argp_parse"); exitcode = EX_OSERR; goto end; case EINVAL: @@ -1313,7 +1471,7 @@ fprintf(stderr, "Using interface \"%s\"\n", interface); } if(interface == NULL){ - perror("malloc"); + perror_plus("malloc"); free(direntries); exitcode = EXIT_FAILURE; goto end; @@ -1341,19 +1499,19 @@ sigemptyset(&sigterm_action.sa_mask); ret = sigaddset(&sigterm_action.sa_mask, SIGINT); if(ret == -1){ - perror("sigaddset"); + perror_plus("sigaddset"); exitcode = EX_OSERR; goto end; } ret = sigaddset(&sigterm_action.sa_mask, SIGHUP); if(ret == -1){ - perror("sigaddset"); + perror_plus("sigaddset"); exitcode = EX_OSERR; goto end; } ret = sigaddset(&sigterm_action.sa_mask, SIGTERM); if(ret == -1){ - perror("sigaddset"); + perror_plus("sigaddset"); exitcode = EX_OSERR; goto end; } @@ -1363,39 +1521,39 @@ */ ret = sigaction(SIGINT, NULL, &old_sigterm_action); if(ret == -1){ - perror("sigaction"); + perror_plus("sigaction"); return EX_OSERR; } if(old_sigterm_action.sa_handler != SIG_IGN){ ret = sigaction(SIGINT, &sigterm_action, NULL); if(ret == -1){ - perror("sigaction"); + perror_plus("sigaction"); exitcode = EX_OSERR; goto end; } } ret = sigaction(SIGHUP, NULL, &old_sigterm_action); if(ret == -1){ - perror("sigaction"); + perror_plus("sigaction"); return EX_OSERR; } if(old_sigterm_action.sa_handler != SIG_IGN){ ret = sigaction(SIGHUP, &sigterm_action, NULL); if(ret == -1){ - perror("sigaction"); + perror_plus("sigaction"); exitcode = EX_OSERR; goto end; } } ret = sigaction(SIGTERM, NULL, &old_sigterm_action); if(ret == -1){ - perror("sigaction"); + perror_plus("sigaction"); return EX_OSERR; } if(old_sigterm_action.sa_handler != SIG_IGN){ ret = sigaction(SIGTERM, &sigterm_action, NULL); if(ret == -1){ - perror("sigaction"); + perror_plus("sigaction"); exitcode = EX_OSERR; goto end; } @@ -1418,7 +1576,7 @@ errno = 0; ret = seteuid(0); if(ret == -1){ - perror("seteuid"); + perror_plus("seteuid"); } #ifdef __linux__ @@ -1428,19 +1586,19 @@ bool restore_loglevel = true; if(ret == -1){ restore_loglevel = false; - perror("klogctl"); + perror_plus("klogctl"); } #endif /* __linux__ */ sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP); if(sd < 0){ - perror("socket"); + perror_plus("socket"); exitcode = EX_OSERR; #ifdef __linux__ if(restore_loglevel){ ret = klogctl(7, NULL, 0); if(ret == -1){ - perror("klogctl"); + perror_plus("klogctl"); } } #endif /* __linux__ */ @@ -1448,19 +1606,19 @@ errno = 0; ret = seteuid(uid); if(ret == -1){ - perror("seteuid"); + perror_plus("seteuid"); } goto end; } strcpy(network.ifr_name, interface); ret = ioctl(sd, SIOCGIFFLAGS, &network); if(ret == -1){ - perror("ioctl SIOCGIFFLAGS"); + perror_plus("ioctl SIOCGIFFLAGS"); #ifdef __linux__ if(restore_loglevel){ ret = klogctl(7, NULL, 0); if(ret == -1){ - perror("klogctl"); + perror_plus("klogctl"); } } #endif /* __linux__ */ @@ -1469,7 +1627,7 @@ errno = 0; ret = seteuid(uid); if(ret == -1){ - perror("seteuid"); + perror_plus("seteuid"); } goto end; } @@ -1479,13 +1637,13 @@ ret = ioctl(sd, SIOCSIFFLAGS, &network); if(ret == -1){ take_down_interface = false; - perror("ioctl SIOCSIFFLAGS +IFF_UP"); + perror_plus("ioctl SIOCSIFFLAGS +IFF_UP"); exitcode = EX_OSERR; #ifdef __linux__ if(restore_loglevel){ ret = klogctl(7, NULL, 0); if(ret == -1){ - perror("klogctl"); + perror_plus("klogctl"); } } #endif /* __linux__ */ @@ -1493,30 +1651,31 @@ errno = 0; ret = seteuid(uid); if(ret == -1){ - perror("seteuid"); + perror_plus("seteuid"); } goto end; } } - /* sleep checking until interface is running */ + /* Sleep checking until interface is running. + Check every 0.25s, up to total time of delay */ for(int i=0; i < delay * 4; i++){ ret = ioctl(sd, SIOCGIFFLAGS, &network); if(ret == -1){ - perror("ioctl SIOCGIFFLAGS"); + perror_plus("ioctl SIOCGIFFLAGS"); } else if(network.ifr_flags & IFF_RUNNING){ break; } struct timespec sleeptime = { .tv_nsec = 250000000 }; ret = nanosleep(&sleeptime, NULL); if(ret == -1 and errno != EINTR){ - perror("nanosleep"); + perror_plus("nanosleep"); } } if(not take_down_interface){ /* We won't need the socket anymore */ ret = (int)TEMP_FAILURE_RETRY(close(sd)); if(ret == -1){ - perror("close"); + perror_plus("close"); } } #ifdef __linux__ @@ -1524,7 +1683,7 @@ /* Restores kernel loglevel to default */ ret = klogctl(7, NULL, 0); if(ret == -1){ - perror("klogctl"); + perror_plus("klogctl"); } } #endif /* __linux__ */ @@ -1534,13 +1693,13 @@ /* Lower privileges */ ret = seteuid(uid); if(ret == -1){ - perror("seteuid"); + perror_plus("seteuid"); } } else { /* Lower privileges permanently */ ret = setuid(uid); if(ret == -1){ - perror("setuid"); + perror_plus("setuid"); } } } @@ -1562,12 +1721,11 @@ goto end; } + if(mkdtemp(tempdir) == NULL){ + perror_plus("mkdtemp"); + goto end; + } tempdir_created = true; - if(mkdtemp(tempdir) == NULL){ - tempdir_created = false; - perror("mkdtemp"); - goto end; - } if(quit_now){ goto end; @@ -1633,7 +1791,7 @@ if(quit_now or ret == 0){ break; } - sleep(15); + sleep((int)retry_interval or 1); }; if (not quit_now){ @@ -1697,8 +1855,13 @@ if(debug){ fprintf(stderr, "Starting Avahi loop search\n"); } - - avahi_simple_poll_loop(mc.simple_poll); + + ret = avahi_loop_with_timeout(mc.simple_poll, + (int)(retry_interval * 1000)); + if(debug){ + fprintf(stderr, "avahi_loop_with_timeout exited %s\n", + (ret == 0) ? "successfully" : "with error"); + } end: @@ -1725,6 +1888,17 @@ if(gpgme_initialized){ gpgme_release(mc.ctx); } + + /* Cleans up the circular linked list of Mandos servers the client + has seen */ + if(mc.current_server != NULL){ + mc.current_server->prev->next = NULL; + while(mc.current_server != NULL){ + server *next = mc.current_server->next; + free(mc.current_server); + mc.current_server = next; + } + } /* Take down the network interface */ if(take_down_interface){ @@ -1732,59 +1906,45 @@ errno = 0; ret = seteuid(0); if(ret == -1){ - perror("seteuid"); + perror_plus("seteuid"); } if(geteuid() == 0){ ret = ioctl(sd, SIOCGIFFLAGS, &network); if(ret == -1){ - perror("ioctl SIOCGIFFLAGS"); + perror_plus("ioctl SIOCGIFFLAGS"); } else if(network.ifr_flags & IFF_UP) { network.ifr_flags &= ~(short)IFF_UP; /* clear flag */ ret = ioctl(sd, SIOCSIFFLAGS, &network); if(ret == -1){ - perror("ioctl SIOCSIFFLAGS -IFF_UP"); + perror_plus("ioctl SIOCSIFFLAGS -IFF_UP"); } } ret = (int)TEMP_FAILURE_RETRY(close(sd)); if(ret == -1){ - perror("close"); + perror_plus("close"); } /* Lower privileges permanently */ errno = 0; ret = setuid(uid); if(ret == -1){ - perror("setuid"); + perror_plus("setuid"); } } } - /* Removes the temp directory used by GPGME */ + /* Removes the GPGME temp directory and all files inside */ if(tempdir_created){ - DIR *d; - struct dirent *direntry; - d = opendir(tempdir); - if(d == NULL){ - if(errno != ENOENT){ - perror("opendir"); - } - } else { - while(true){ - direntry = readdir(d); - if(direntry == NULL){ - break; - } - /* Skip "." and ".." */ - if(direntry->d_name[0] == '.' - and (direntry->d_name[1] == '\0' - or (direntry->d_name[1] == '.' - and direntry->d_name[2] == '\0'))){ - continue; - } + struct dirent **direntries = NULL; + struct dirent *direntry = NULL; + ret = scandir(tempdir, &direntries, notdotentries, alphasort); + if (ret > 0){ + for(int i = 0; i < ret; i++){ + direntry = direntries[i]; char *fullname = NULL; ret = asprintf(&fullname, "%s/%s", tempdir, direntry->d_name); if(ret < 0){ - perror("asprintf"); + perror_plus("asprintf"); continue; } ret = remove(fullname); @@ -1794,11 +1954,17 @@ } free(fullname); } - closedir(d); + } + + /* need to be cleaned even if ret == 0 because man page doesn't + specify */ + free(direntries); + if (ret == -1){ + perror_plus("scandir"); } ret = rmdir(tempdir); if(ret == -1 and errno != ENOENT){ - perror("rmdir"); + perror_plus("rmdir"); } } @@ -1809,13 +1975,13 @@ &old_sigterm_action, NULL)); if(ret == -1){ - perror("sigaction"); + perror_plus("sigaction"); } do { ret = raise(signal_received); } while(ret != 0 and errno == EINTR); if(ret != 0){ - perror("raise"); + perror_plus("raise"); abort(); } TEMP_FAILURE_RETRY(pause()); === modified file 'plugins.d/mandos-client.xml' --- plugins.d/mandos-client.xml 2010-09-26 18:32:58 +0000 +++ plugins.d/mandos-client.xml 2011-06-23 22:27:15 +0000 @@ -97,6 +97,10 @@ + + + + @@ -293,6 +297,19 @@ + + + + + + All Mandos servers servers are tried repeatedly until a + password is received. This value specifies, in seconds, + how long between each successive try for the + same server. The default is 10 seconds. + + + === modified file 'plugins.d/password-prompt.c' --- plugins.d/password-prompt.c 2011-03-17 18:19:08 +0000 +++ plugins.d/password-prompt.c 2011-07-13 02:24:39 +0000 @@ -41,8 +41,8 @@ getenv(), free() */ #include /* scandir(), alphasort() */ #include /* fprintf(), stderr, getline(), - stdin, feof(), fputc() - */ + stdin, feof(), fputc(), vfprintf(), + vasprintf() */ #include /* errno, EBADF, ENOTTY, EINVAL, EFAULT, EFBIG, EIO, ENOSPC, EINTR */ @@ -51,7 +51,8 @@ #include /* bool, false, true */ #include /* strtoumax() */ #include /* struct stat, lstat(), open() */ -#include /* strlen, rindex, memcmp */ +#include /* strlen, rindex, memcmp, strerror() + */ #include /* struct argp_option, struct argp_state, struct argp, argp_parse(), error_t, @@ -60,6 +61,7 @@ #include /* EX_SOFTWARE, EX_OSERR, EX_UNAVAILABLE, EX_IOERR, EX_OK */ #include /* open() */ +#include /* va_list, va_start(), ... */ volatile sig_atomic_t quit_now = 0; int signal_received; @@ -70,6 +72,29 @@ /* Needed for conflict resolution */ const char plymouth_name[] = "plymouthd"; +/* Function to use when printing errors */ +void error_plus(int status, int errnum, const char *formatstring, + ...){ + va_list ap; + char *text; + int ret; + + va_start(ap, formatstring); + ret = vasprintf(&text, formatstring, ap); + if (ret == -1){ + fprintf(stderr, "Mandos plugin %s: ", + program_invocation_short_name); + vfprintf(stderr, formatstring, ap); + fprintf(stderr, ": "); + fprintf(stderr, "%s\n", strerror(errnum)); + error(status, errno, "vasprintf while printing error"); + return; + } + fprintf(stderr, "Mandos plugin "); + error(status, errnum, "%s", text); + free(text); +} + static void termination_handler(int signum){ if(quit_now){ return; === modified file 'plugins.d/plymouth.c' --- plugins.d/plymouth.c 2011-02-27 17:26:35 +0000 +++ plugins.d/plymouth.c 2011-07-13 02:24:39 +0000 @@ -36,7 +36,8 @@ #include /* NULL */ #include /* strchr(), memcmp() */ #include /* asprintf(), perror(), fopen(), - fscanf() */ + fscanf(), vasprintf(), fprintf(), + vfprintf() */ #include /* close(), readlink(), read(), fork(), setsid(), chdir(), dup2(), STDERR_FILENO, execv(), access() */ @@ -50,6 +51,7 @@ #include /* error() */ #include /* TEMP_FAILURE_RETRY */ #include /* argz_count(), argz_extract() */ +#include /* va_list, va_start(), ... */ sig_atomic_t interrupted_by_signal = 0; const char plymouth_pid[] = "/dev/.initramfs/plymouth.pid"; @@ -70,6 +72,29 @@ interrupted_by_signal = 1; } +/* Function to use when printing errors */ +void error_plus(int status, int errnum, const char *formatstring, + ...){ + va_list ap; + char *text; + int ret; + + va_start(ap, formatstring); + ret = vasprintf(&text, formatstring, ap); + if (ret == -1){ + fprintf(stderr, "Mandos plugin %s: ", + program_invocation_short_name); + vfprintf(stderr, formatstring, ap); + fprintf(stderr, ": "); + fprintf(stderr, "%s\n", strerror(errnum)); + error(status, errno, "vasprintf while printing error"); + return; + } + fprintf(stderr, "Mandos plugin "); + error(status, errnum, "%s", text); + free(text); +} + /* Create prompt string */ char *makeprompt(void){ int ret = 0; @@ -109,18 +134,18 @@ bool become_a_daemon(void){ int ret = setuid(geteuid()); if(ret == -1){ - error(0, errno, "setuid"); + error_plus(0, errno, "setuid"); } setsid(); ret = chdir("/"); if(ret == -1){ - error(0, errno, "chdir"); + error_plus(0, errno, "chdir"); return false; } ret = dup2(STDERR_FILENO, STDOUT_FILENO); /* replace our stdout */ if(ret == -1){ - error(0, errno, "dup2"); + error_plus(0, errno, "dup2"); return false; } return true; @@ -134,7 +159,7 @@ pid_t pid; pid = fork(); if(pid == -1){ - error(0, errno, "fork"); + error_plus(0, errno, "fork"); return false; } if(pid == 0){ @@ -151,7 +176,7 @@ for (; argv[i]!=NULL; i++){ tmp = realloc(new_argv, sizeof(const char *) * ((size_t)i + 1)); if (tmp == NULL){ - error(0, errno, "realloc"); + error_plus(0, errno, "realloc"); free(new_argv); _exit(EX_OSERR); } @@ -161,7 +186,7 @@ new_argv[i] = NULL; execv(path, (char *const *)new_argv); - error(0, errno, "execv"); + error_plus(0, errno, "execv"); _exit(EXIT_FAILURE); } if(pid_return != NULL){ @@ -176,7 +201,7 @@ return false; } if(ret == -1){ - error(0, errno, "waitpid"); + error_plus(0, errno, "waitpid"); return false; } if(WIFEXITED(status) and (WEXITSTATUS(status) == 0)){ @@ -202,7 +227,7 @@ char *exe_link; ret = asprintf(&exe_link, "/proc/%s/exe", proc_entry->d_name); if(ret == -1){ - error(0, errno, "asprintf"); + error_plus(0, errno, "asprintf"); return 0; } @@ -211,7 +236,7 @@ if(ret == -1){ free(exe_link); if(errno != ENOENT){ - error(0, errno, "lstat"); + error_plus(0, errno, "lstat"); } return 0; } @@ -245,17 +270,20 @@ fclose(pidfile); } if(maxvalue == 0){ - struct dirent **direntries; + struct dirent **direntries = NULL; ret = scandir("/proc", &direntries, is_plymouth, alphasort); if (ret == -1){ - error(0, errno, "scandir"); + error_plus(0, errno, "scandir"); } if (ret > 0){ ret = sscanf(direntries[0]->d_name, "%" SCNuMAX, &maxvalue); if (ret < 0){ - error(0, errno, "sscanf"); + error_plus(0, errno, "sscanf"); } } + /* scandir might preallocate for this variable (man page unclear). + even if ret == 0, therefore we need to free it. */ + free(direntries); } pid_t pid; pid = (pid_t)maxvalue; @@ -275,7 +303,7 @@ ret = asprintf(&cmdline_filename, "/proc/%" PRIuMAX "/cmdline", (uintmax_t)pid); if(ret == -1){ - error(0, errno, "asprintf"); + error_plus(0, errno, "asprintf"); return NULL; } @@ -283,7 +311,7 @@ cl_fd = open(cmdline_filename, O_RDONLY); free(cmdline_filename); if(cl_fd == -1){ - error(0, errno, "open"); + error_plus(0, errno, "open"); return NULL; } @@ -297,7 +325,7 @@ if(cmdline_len + blocksize > cmdline_allocated){ tmp = realloc(cmdline, cmdline_allocated + blocksize); if(tmp == NULL){ - error(0, errno, "realloc"); + error_plus(0, errno, "realloc"); free(cmdline); close(cl_fd); return NULL; @@ -310,7 +338,7 @@ sret = read(cl_fd, cmdline + cmdline_len, cmdline_allocated - cmdline_len); if(sret == -1){ - error(0, errno, "read"); + error_plus(0, errno, "read"); free(cmdline); close(cl_fd); return NULL; @@ -319,7 +347,7 @@ } while(sret != 0); ret = close(cl_fd); if(ret == -1){ - error(0, errno, "close"); + error_plus(0, errno, "close"); free(cmdline); return NULL; } @@ -328,7 +356,7 @@ char **argv = malloc((argz_count(cmdline, cmdline_len) + 1) * sizeof(char *)); /* Get number of args */ if(argv == NULL){ - error(0, errno, "argv = malloc()"); + error_plus(0, errno, "argv = malloc()"); free(cmdline); return NULL; } @@ -361,16 +389,16 @@ *sig != 0; sig++){ ret = sigaddset(&new_action.sa_mask, *sig); if(ret == -1){ - error(EX_OSERR, errno, "sigaddset"); + error_plus(EX_OSERR, errno, "sigaddset"); } ret = sigaction(*sig, NULL, &old_action); if(ret == -1){ - error(EX_OSERR, errno, "sigaction"); + error_plus(EX_OSERR, errno, "sigaction"); } if(old_action.sa_handler != SIG_IGN){ ret = sigaction(*sig, &new_action, NULL); if(ret == -1){ - error(EX_OSERR, errno, "sigaction"); + error_plus(EX_OSERR, errno, "sigaction"); } } } @@ -395,7 +423,7 @@ ret = asprintf(&prompt_arg, "--prompt=%s", prompt); free(prompt); if(ret == -1){ - error(EX_OSERR, errno, "asprintf"); + error_plus(EX_OSERR, errno, "asprintf"); } /* plymouth ask-for-password --prompt="$prompt" */ @@ -417,7 +445,7 @@ const char **plymouthd_argv; pid_t pid = get_pid(); if(pid == 0){ - error(0, 0, "plymouthd pid not found"); + error_plus(0, 0, "plymouthd pid not found"); plymouthd_argv = plymouthd_default_argv; } else { plymouthd_argv = getargv(pid); === modified file 'plugins.d/splashy.c' --- plugins.d/splashy.c 2011-02-27 17:26:35 +0000 +++ plugins.d/splashy.c 2011-07-13 02:24:39 +0000 @@ -29,7 +29,8 @@ SIG_IGN, kill(), SIGKILL */ #include /* NULL */ #include /* getenv() */ -#include /* asprintf() */ +#include /* asprintf(), vasprintf(), vprintf(), + fprintf() */ #include /* EXIT_FAILURE, free(), EXIT_SUCCESS */ #include /* pid_t, DIR, struct dirent, @@ -42,7 +43,7 @@ sleep(), dup2() STDERR_FILENO, STDOUT_FILENO, _exit(), pause() */ -#include /* memcmp() */ +#include /* memcmp(), strerror() */ #include /* errno, EACCES, ENOTDIR, ELOOP, ENOENT, ENAMETOOLONG, EMFILE, ENFILE, ENOMEM, ENOEXEC, EINVAL, @@ -54,10 +55,35 @@ WEXITSTATUS() */ #include /* EX_OSERR, EX_OSFILE, EX_UNAVAILABLE */ +#include /* va_list, va_start(), ... */ sig_atomic_t interrupted_by_signal = 0; int signal_received; +/* Function to use when printing errors */ +void error_plus(int status, int errnum, const char *formatstring, + ...){ + va_list ap; + char *text; + int ret; + + va_start(ap, formatstring); + ret = vasprintf(&text, formatstring, ap); + if (ret == -1){ + fprintf(stderr, "Mandos plugin %s: ", + program_invocation_short_name); + vfprintf(stderr, formatstring, ap); + fprintf(stderr, ": "); + fprintf(stderr, "%s\n", strerror(errnum)); + error(status, errno, "vasprintf while printing error"); + return; + } + fprintf(stderr, "Mandos plugin "); + error(status, errnum, "%s", text); + free(text); +} + + static void termination_handler(int signum){ if(interrupted_by_signal){ return; @@ -110,7 +136,7 @@ proc_dir = opendir("/proc"); if(proc_dir == NULL){ int e = errno; - error(0, errno, "opendir"); + error_plus(0, errno, "opendir"); switch(e){ case EACCES: case ENOTDIR: @@ -152,7 +178,7 @@ char *exe_link; ret = asprintf(&exe_link, "/proc/%s/exe", proc_ent->d_name); if(ret == -1){ - error(0, errno, "asprintf"); + error_plus(0, errno, "asprintf"); exitstatus = EX_OSERR; goto failure; } @@ -166,7 +192,7 @@ continue; } int e = errno; - error(0, errno, "lstat"); + error_plus(0, errno, "lstat"); free(exe_link); switch(e){ case EACCES: @@ -214,60 +240,60 @@ sigemptyset(&new_action.sa_mask); ret = sigaddset(&new_action.sa_mask, SIGINT); if(ret == -1){ - error(0, errno, "sigaddset"); + error_plus(0, errno, "sigaddset"); exitstatus = EX_OSERR; goto failure; } ret = sigaddset(&new_action.sa_mask, SIGHUP); if(ret == -1){ - error(0, errno, "sigaddset"); + error_plus(0, errno, "sigaddset"); exitstatus = EX_OSERR; goto failure; } ret = sigaddset(&new_action.sa_mask, SIGTERM); if(ret == -1){ - error(0, errno, "sigaddset"); + error_plus(0, errno, "sigaddset"); exitstatus = EX_OSERR; goto failure; } ret = sigaction(SIGINT, NULL, &old_action); if(ret == -1){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); exitstatus = EX_OSERR; goto failure; } if(old_action.sa_handler != SIG_IGN){ ret = sigaction(SIGINT, &new_action, NULL); if(ret == -1){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); exitstatus = EX_OSERR; goto failure; } } ret = sigaction(SIGHUP, NULL, &old_action); if(ret == -1){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); exitstatus = EX_OSERR; goto failure; } if(old_action.sa_handler != SIG_IGN){ ret = sigaction(SIGHUP, &new_action, NULL); if(ret == -1){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); exitstatus = EX_OSERR; goto failure; } } ret = sigaction(SIGTERM, NULL, &old_action); if(ret == -1){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); exitstatus = EX_OSERR; goto failure; } if(old_action.sa_handler != SIG_IGN){ ret = sigaction(SIGTERM, &new_action, NULL); if(ret == -1){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); exitstatus = EX_OSERR; goto failure; } @@ -284,7 +310,7 @@ goto failure; } if(splashy_command_pid == -1){ - error(0, errno, "fork"); + error_plus(0, errno, "fork"); exitstatus = EX_OSERR; goto failure; } @@ -294,7 +320,7 @@ const char splashy_command[] = "/sbin/splashy_update"; execl(splashy_command, splashy_command, prompt, (char *)NULL); int e = errno; - error(0, errno, "execl"); + error_plus(0, errno, "execl"); switch(e){ case EACCES: case ENOENT: @@ -344,7 +370,7 @@ goto failure; } if(ret == -1){ - error(0, errno, "waitpid"); + error_plus(0, errno, "waitpid"); if(errno == ECHILD){ splashy_command_pid = 0; } @@ -382,27 +408,27 @@ the real user ID (_mandos) */ ret = setuid(geteuid()); if(ret == -1){ - error(0, errno, "setuid"); + error_plus(0, errno, "setuid"); } setsid(); ret = chdir("/"); if(ret == -1){ - error(0, errno, "chdir"); + error_plus(0, errno, "chdir"); } /* if(fork() != 0){ */ /* _exit(EXIT_SUCCESS); */ /* } */ ret = dup2(STDERR_FILENO, STDOUT_FILENO); /* replace stdout */ if(ret == -1){ - error(0, errno, "dup2"); + error_plus(0, errno, "dup2"); _exit(EX_OSERR); } execl("/sbin/splashy", "/sbin/splashy", "boot", (char *)NULL); { int e = errno; - error(0, errno, "execl"); + error_plus(0, errno, "execl"); switch(e){ case EACCES: case ENOENT: @@ -428,13 +454,13 @@ ret = (int)TEMP_FAILURE_RETRY(sigaction(signal_received, &signal_action, NULL)); if(ret == -1){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); } do { ret = raise(signal_received); } while(ret != 0 and errno == EINTR); if(ret != 0){ - error(0, errno, "raise"); + error_plus(0, errno, "raise"); abort(); } TEMP_FAILURE_RETRY(pause()); === modified file 'plugins.d/usplash.c' --- plugins.d/usplash.c 2011-02-27 17:26:35 +0000 +++ plugins.d/usplash.c 2011-07-13 02:24:39 +0000 @@ -35,8 +35,9 @@ #include /* size_t, ssize_t, pid_t, DIR, struct dirent */ #include /* NULL */ -#include /* strlen(), memcmp() */ -#include /* asprintf()*/ +#include /* strlen(), memcmp(), strerror() */ +#include /* asprintf(), vasprintf(), vprintf(), + fprintf() */ #include /* close(), write(), readlink(), read(), STDOUT_FILENO, sleep(), fork(), setuid(), geteuid(), @@ -50,11 +51,35 @@ #include /* struct stat, lstat(), S_ISLNK */ #include /* EX_OSERR, EX_UNAVAILABLE */ #include /* argz_count(), argz_extract() */ +#include /* va_list, va_start(), ... */ sig_atomic_t interrupted_by_signal = 0; int signal_received; const char usplash_name[] = "/sbin/usplash"; +/* Function to use when printing errors */ +void error_plus(int status, int errnum, const char *formatstring, + ...){ + va_list ap; + char *text; + int ret; + + va_start(ap, formatstring); + ret = vasprintf(&text, formatstring, ap); + if (ret == -1){ + fprintf(stderr, "Mandos plugin %s: ", + program_invocation_short_name); + vfprintf(stderr, formatstring, ap); + fprintf(stderr, ": "); + fprintf(stderr, "%s\n", strerror(errnum)); + error(status, errno, "vasprintf while printing error"); + return; + } + fprintf(stderr, "Mandos plugin "); + error(status, errnum, "%s", text); + free(text); +} + static void termination_handler(int signum){ if(interrupted_by_signal){ return; @@ -155,7 +180,7 @@ size_t cmdline_len = 0; DIR *proc_dir = opendir("/proc"); if(proc_dir == NULL){ - error(0, errno, "opendir"); + error_plus(0, errno, "opendir"); return -1; } errno = 0; @@ -183,7 +208,7 @@ char *exe_link; ret = asprintf(&exe_link, "/proc/%s/exe", proc_ent->d_name); if(ret == -1){ - error(0, errno, "asprintf"); + error_plus(0, errno, "asprintf"); goto fail_find_usplash; } @@ -195,7 +220,7 @@ free(exe_link); continue; } - error(0, errno, "lstat"); + error_plus(0, errno, "lstat"); free(exe_link); goto fail_find_usplash; } @@ -226,13 +251,13 @@ ret = asprintf(&cmdline_filename, "/proc/%s/cmdline", proc_ent->d_name); if(ret == -1){ - error(0, errno, "asprintf"); + error_plus(0, errno, "asprintf"); goto fail_find_usplash; } cl_fd = open(cmdline_filename, O_RDONLY); free(cmdline_filename); if(cl_fd == -1){ - error(0, errno, "open"); + error_plus(0, errno, "open"); goto fail_find_usplash; } } @@ -244,7 +269,7 @@ if(cmdline_len + blocksize > cmdline_allocated){ tmp = realloc(cmdline, cmdline_allocated + blocksize); if(tmp == NULL){ - error(0, errno, "realloc"); + error_plus(0, errno, "realloc"); close(cl_fd); goto fail_find_usplash; } @@ -255,7 +280,7 @@ sret = read(cl_fd, cmdline + cmdline_len, cmdline_allocated - cmdline_len); if(sret == -1){ - error(0, errno, "read"); + error_plus(0, errno, "read"); close(cl_fd); goto fail_find_usplash; } @@ -263,14 +288,14 @@ } while(sret != 0); ret = close(cl_fd); if(ret == -1){ - error(0, errno, "close"); + error_plus(0, errno, "close"); goto fail_find_usplash; } } /* Close directory */ ret = closedir(proc_dir); if(ret == -1){ - error(0, errno, "closedir"); + error_plus(0, errno, "closedir"); goto fail_find_usplash; } /* Success */ @@ -325,26 +350,26 @@ sigemptyset(&new_action.sa_mask); ret = sigaddset(&new_action.sa_mask, SIGINT); if(ret == -1){ - error(0, errno, "sigaddset"); + error_plus(0, errno, "sigaddset"); status = EX_OSERR; goto failure; } ret = sigaddset(&new_action.sa_mask, SIGHUP); if(ret == -1){ - error(0, errno, "sigaddset"); + error_plus(0, errno, "sigaddset"); status = EX_OSERR; goto failure; } ret = sigaddset(&new_action.sa_mask, SIGTERM); if(ret == -1){ - error(0, errno, "sigaddset"); + error_plus(0, errno, "sigaddset"); status = EX_OSERR; goto failure; } ret = sigaction(SIGINT, NULL, &old_action); if(ret == -1){ if(errno != EINTR){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); status = EX_OSERR; } goto failure; @@ -353,7 +378,7 @@ ret = sigaction(SIGINT, &new_action, NULL); if(ret == -1){ if(errno != EINTR){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); status = EX_OSERR; } goto failure; @@ -362,7 +387,7 @@ ret = sigaction(SIGHUP, NULL, &old_action); if(ret == -1){ if(errno != EINTR){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); status = EX_OSERR; } goto failure; @@ -371,7 +396,7 @@ ret = sigaction(SIGHUP, &new_action, NULL); if(ret == -1){ if(errno != EINTR){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); status = EX_OSERR; } goto failure; @@ -380,7 +405,7 @@ ret = sigaction(SIGTERM, NULL, &old_action); if(ret == -1){ if(errno != EINTR){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); status = EX_OSERR; } goto failure; @@ -389,7 +414,7 @@ ret = sigaction(SIGTERM, &new_action, NULL); if(ret == -1){ if(errno != EINTR){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); status = EX_OSERR; } goto failure; @@ -401,7 +426,7 @@ /* Write command to FIFO */ if(not usplash_write(&fifo_fd, "TIMEOUT", "0")){ if(errno != EINTR){ - error(0, errno, "usplash_write"); + error_plus(0, errno, "usplash_write"); status = EX_OSERR; } goto failure; @@ -413,7 +438,7 @@ if(not usplash_write(&fifo_fd, "INPUTQUIET", prompt)){ if(errno != EINTR){ - error(0, errno, "usplash_write"); + error_plus(0, errno, "usplash_write"); status = EX_OSERR; } goto failure; @@ -431,7 +456,7 @@ outfifo_fd = open("/dev/.initramfs/usplash_outfifo", O_RDONLY); if(outfifo_fd == -1){ if(errno != EINTR){ - error(0, errno, "open"); + error_plus(0, errno, "open"); status = EX_OSERR; } goto failure; @@ -450,7 +475,7 @@ char *tmp = realloc(buf, buf_allocated + blocksize); if(tmp == NULL){ if(errno != EINTR){ - error(0, errno, "realloc"); + error_plus(0, errno, "realloc"); status = EX_OSERR; } goto failure; @@ -462,7 +487,7 @@ buf_allocated - buf_len); if(sret == -1){ if(errno != EINTR){ - error(0, errno, "read"); + error_plus(0, errno, "read"); status = EX_OSERR; } TEMP_FAILURE_RETRY(close(outfifo_fd)); @@ -477,7 +502,7 @@ ret = close(outfifo_fd); if(ret == -1){ if(errno != EINTR){ - error(0, errno, "close"); + error_plus(0, errno, "close"); status = EX_OSERR; } goto failure; @@ -490,7 +515,7 @@ if(not usplash_write(&fifo_fd, "TIMEOUT", "15")){ if(errno != EINTR){ - error(0, errno, "usplash_write"); + error_plus(0, errno, "usplash_write"); status = EX_OSERR; } goto failure; @@ -503,7 +528,7 @@ ret = close(fifo_fd); if(ret == -1){ if(errno != EINTR){ - error(0, errno, "close"); + error_plus(0, errno, "close"); status = EX_OSERR; } goto failure; @@ -517,7 +542,7 @@ sret = write(STDOUT_FILENO, buf + written, buf_len - written); if(sret == -1){ if(errno != EINTR){ - error(0, errno, "write"); + error_plus(0, errno, "write"); status = EX_OSERR; } goto failure; @@ -554,7 +579,7 @@ if(fifo_fd != -1){ ret = (int)TEMP_FAILURE_RETRY(close(fifo_fd)); if(ret == -1 and errno != EINTR){ - error(0, errno, "close"); + error_plus(0, errno, "close"); } fifo_fd = -1; } @@ -563,7 +588,7 @@ if(outfifo_fd != -1){ ret = (int)TEMP_FAILURE_RETRY(close(outfifo_fd)); if(ret == -1){ - error(0, errno, "close"); + error_plus(0, errno, "close"); } } @@ -571,7 +596,7 @@ char **cmdline_argv = malloc((argz_count(cmdline, cmdline_len) + 1) * sizeof(char *)); /* Count args */ if(cmdline_argv == NULL){ - error(0, errno, "malloc"); + error_plus(0, errno, "malloc"); return status; } argz_extract(cmdline, cmdline_len, cmdline_argv); /* Create argv */ @@ -592,13 +617,13 @@ the real user ID (_mandos) */ ret = setuid(geteuid()); if(ret == -1){ - error(0, errno, "setuid"); + error_plus(0, errno, "setuid"); } setsid(); ret = chdir("/"); if(ret == -1){ - error(0, errno, "chdir"); + error_plus(0, errno, "chdir"); _exit(EX_OSERR); } /* if(fork() != 0){ */ @@ -606,13 +631,13 @@ /* } */ ret = dup2(STDERR_FILENO, STDOUT_FILENO); /* replace our stdout */ if(ret == -1){ - error(0, errno, "dup2"); + error_plus(0, errno, "dup2"); _exit(EX_OSERR); } execv(usplash_name, cmdline_argv); if(not interrupted_by_signal){ - error(0, errno, "execv"); + error_plus(0, errno, "execv"); } free(cmdline); free(cmdline_argv); @@ -623,7 +648,7 @@ sleep(2); if(not usplash_write(&fifo_fd, "PULSATE", NULL)){ if(errno != EINTR){ - error(0, errno, "usplash_write"); + error_plus(0, errno, "usplash_write"); } } @@ -631,7 +656,7 @@ if(fifo_fd != -1){ ret = (int)TEMP_FAILURE_RETRY(close(fifo_fd)); if(ret == -1 and errno != EINTR){ - error(0, errno, "close"); + error_plus(0, errno, "close"); } fifo_fd = -1; } @@ -642,13 +667,13 @@ ret = (int)TEMP_FAILURE_RETRY(sigaction(signal_received, &signal_action, NULL)); if(ret == -1){ - error(0, errno, "sigaction"); + error_plus(0, errno, "sigaction"); } do { ret = raise(signal_received); } while(ret != 0 and errno == EINTR); if(ret != 0){ - error(0, errno, "raise"); + error_plus(0, errno, "raise"); abort(); } TEMP_FAILURE_RETRY(pause());