diff options
-rw-r--r-- | src/entropy/unix_procs/es_unix.cpp | 119 | ||||
-rw-r--r-- | src/entropy/unix_procs/es_unix.h | 39 | ||||
-rw-r--r-- | src/entropy/unix_procs/info.txt | 14 | ||||
-rw-r--r-- | src/entropy/unix_procs/unix_cmd.cpp | 246 | ||||
-rw-r--r-- | src/entropy/unix_procs/unix_cmd.h | 77 | ||||
-rw-r--r-- | src/entropy/unix_procs/unix_proc_sources.cpp | 65 | ||||
-rw-r--r-- | src/entropy/unix_procs/unix_procs.cpp | 277 | ||||
-rw-r--r-- | src/entropy/unix_procs/unix_procs.h | 83 | ||||
-rw-r--r-- | src/entropy/unix_procs/unix_src.cpp | 65 |
9 files changed, 429 insertions, 556 deletions
diff --git a/src/entropy/unix_procs/es_unix.cpp b/src/entropy/unix_procs/es_unix.cpp deleted file mode 100644 index 1c6b53ede..000000000 --- a/src/entropy/unix_procs/es_unix.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* -* Unix EntropySource -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/internal/es_unix.h> -#include <botan/internal/unix_cmd.h> -#include <botan/parsing.h> -#include <algorithm> - -#include <sys/time.h> -#include <sys/stat.h> -#include <sys/resource.h> -#include <unistd.h> - -namespace Botan { - -namespace { - -/** -* Sort ordering by priority -*/ -bool Unix_Program_Cmp(const Unix_Program& a, const Unix_Program& b) - { - if(a.priority == b.priority) - return (a.name_and_args < b.name_and_args); - - return (a.priority < b.priority); - } - -} - -/** -* Unix_EntropySource Constructor -*/ -Unix_EntropySource::Unix_EntropySource(const std::vector<std::string>& path) : - PATH(path) - { - std::vector<Unix_Program> default_sources = get_default_sources(); - add_sources(&default_sources[0], default_sources.size()); - } - -/** -* Add sources to the list -*/ -void Unix_EntropySource::add_sources(const Unix_Program srcs[], size_t count) - { - sources.insert(sources.end(), srcs, srcs + count); - std::sort(sources.begin(), sources.end(), Unix_Program_Cmp); - } - -/** -* Poll for entropy on a generic Unix system, first by grabbing various -* statistics (stat on common files, getrusage, etc), and then, if more -* is required, by exec'ing various programs like uname and rpcinfo and -* reading the output. -*/ -void Unix_EntropySource::poll(Entropy_Accumulator& accum) - { - const char* stat_targets[] = { - "/", - "/tmp", - "/var/tmp", - "/usr", - "/home", - "/etc/passwd", - ".", - "..", - nullptr }; - - for(size_t i = 0; stat_targets[i]; i++) - { - struct stat statbuf; - clear_mem(&statbuf, 1); - ::stat(stat_targets[i], &statbuf); - accum.add(&statbuf, sizeof(statbuf), .005); - } - - accum.add(::getpid(), 0); - accum.add(::getppid(), 0); - accum.add(::getuid(), 0); - accum.add(::getgid(), 0); - accum.add(::getpgrp(), 0); - - struct ::rusage usage; - ::getrusage(RUSAGE_SELF, &usage); - accum.add(usage, .005); - - ::getrusage(RUSAGE_CHILDREN, &usage); - accum.add(usage, .005); - - const size_t MINIMAL_WORKING = 16; - - secure_vector<byte>& io_buffer = accum.get_io_buffer(4*1024); - - for(size_t i = 0; i != sources.size(); i++) - { - DataSource_Command pipe(sources[i].name_and_args, PATH); - - size_t got_from_src = 0; - - while(!pipe.end_of_data()) - { - size_t got_this_loop = pipe.read(&io_buffer[0], io_buffer.size()); - got_from_src += got_this_loop; - - accum.add(&io_buffer[0], got_this_loop, .005); - } - - sources[i].working = (got_from_src >= MINIMAL_WORKING) ? true : false; - - if(accum.polling_goal_achieved()) - break; - } - } - -} diff --git a/src/entropy/unix_procs/es_unix.h b/src/entropy/unix_procs/es_unix.h deleted file mode 100644 index 9c217ebe7..000000000 --- a/src/entropy/unix_procs/es_unix.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* Unix EntropySource -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_ENTROPY_SRC_UNIX_H__ -#define BOTAN_ENTROPY_SRC_UNIX_H__ - -#include <botan/entropy_src.h> -#include <botan/internal/unix_cmd.h> -#include <vector> - -namespace Botan { - -/** -* Unix Entropy Source -*/ -class Unix_EntropySource : public EntropySource - { - public: - std::string name() const { return "Unix Entropy Source"; } - - void poll(Entropy_Accumulator& accum); - - void add_sources(const Unix_Program[], size_t); - Unix_EntropySource(const std::vector<std::string>& path); - private: - static std::vector<Unix_Program> get_default_sources(); - void fast_poll(Entropy_Accumulator& accum); - - const std::vector<std::string> PATH; - std::vector<Unix_Program> sources; - }; - -} - -#endif diff --git a/src/entropy/unix_procs/info.txt b/src/entropy/unix_procs/info.txt index d2a15f13d..dc086a5fa 100644 --- a/src/entropy/unix_procs/info.txt +++ b/src/entropy/unix_procs/info.txt @@ -1,14 +1,12 @@ -define ENTROPY_SRC_UNIX +define ENTROPY_SRC_UNIX_PROCESS_RUNNER <source> -es_unix.cpp -unix_cmd.cpp -unix_src.cpp +unix_procs.cpp +unix_proc_sources.cpp </source> <header:internal> -es_unix.h -unix_cmd.h +unix_procs.h </header:internal> <os> @@ -25,7 +23,3 @@ qnx solaris tru64 </os> - -<requires> -filters -</requires> diff --git a/src/entropy/unix_procs/unix_cmd.cpp b/src/entropy/unix_procs/unix_cmd.cpp deleted file mode 100644 index 07386dbc5..000000000 --- a/src/entropy/unix_procs/unix_cmd.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* -* Unix Command Execution -* (C) 1999-2007 Jack Lloyd -* 2012 Markus Wanner -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/internal/unix_cmd.h> -#include <botan/parsing.h> -#include <botan/exceptn.h> - -#include <sys/time.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> - -namespace Botan { - -namespace { - -/** -* Attempt to execute the command -*/ -void do_exec(const std::vector<std::string>& arg_list, - const std::vector<std::string>& paths) - { - const size_t args = arg_list.size() - 1; - - const char* arg1 = (args >= 1) ? arg_list[1].c_str() : nullptr; - const char* arg2 = (args >= 2) ? arg_list[2].c_str() : nullptr; - const char* arg3 = (args >= 3) ? arg_list[3].c_str() : nullptr; - const char* arg4 = (args >= 4) ? arg_list[4].c_str() : nullptr; - - for(size_t j = 0; j != paths.size(); j++) - { - const std::string full_path = paths[j] + "/" + arg_list[0]; - const char* fsname = full_path.c_str(); - - ::execl(fsname, fsname, arg1, arg2, arg3, arg4, NULL); - } - } - -} - -/** -* Local information about the pipe -*/ -struct pipe_wrapper - { - int fd; - pid_t pid; - - pipe_wrapper(int f, pid_t p) : fd(f), pid(p) {} - ~pipe_wrapper() { ::close(fd); } - }; - -/** -* Read from the pipe -*/ -size_t DataSource_Command::read(byte buf[], size_t length) - { - if(end_of_data()) - return 0; - - fd_set set; - FD_ZERO(&set); - FD_SET(pipe->fd, &set); - - struct ::timeval tv; - tv.tv_sec = 0; - tv.tv_usec = MAX_BLOCK_USECS; - - ssize_t got = 0; - if(::select(pipe->fd + 1, &set, nullptr, nullptr, &tv) == 1) - { - if(FD_ISSET(pipe->fd, &set)) - got = ::read(pipe->fd, buf, length); - } - - if(got <= 0) - { - shutdown_pipe(); - return 0; - } - - bytes_read += got; - return static_cast<size_t>(got); - } - -/** -* Peek at the pipe contents -*/ -size_t DataSource_Command::peek(byte[], size_t, size_t) const - { - if(end_of_data()) - throw Invalid_State("DataSource_Command: Cannot peek when out of data"); - throw Stream_IO_Error("Cannot peek/seek on a command pipe"); - } - -/** -* Check if we reached EOF -*/ -bool DataSource_Command::end_of_data() const - { - return (pipe) ? false : true; - } - -size_t DataSource_Command::get_bytes_read() const - { - return bytes_read; - } - -/** -* Return the Unix file descriptor of the pipe -*/ -int DataSource_Command::fd() const - { - if(!pipe) - return -1; - return pipe->fd; - } - -/** -* Return a human-readable ID for this stream -*/ -std::string DataSource_Command::id() const - { - return "Unix command: " + arg_list[0]; - } - -/** -* Create the pipe -*/ -void DataSource_Command::create_pipe(const std::vector<std::string>& paths) - { - bool found_something = false; - - for(size_t j = 0; j != paths.size(); j++) - { - const std::string full_path = paths[j] + "/" + arg_list[0]; - if(::access(full_path.c_str(), X_OK) == 0) - { - found_something = true; - break; - } - } - - if(!found_something) - return; - - int pipe_fd[2]; - if(::pipe(pipe_fd) != 0) - return; - - pid_t pid = ::fork(); - - if(pid == -1) - { - ::close(pipe_fd[0]); - ::close(pipe_fd[1]); - } - else if(pid > 0) - { - pipe = new pipe_wrapper(pipe_fd[0], pid); - ::close(pipe_fd[1]); - } - else - { - if(dup2(pipe_fd[1], STDOUT_FILENO) == -1) - ::exit(127); - if(close(pipe_fd[0]) != 0 || close(pipe_fd[1]) != 0) - ::exit(127); - if(close(STDERR_FILENO) != 0) - ::exit(127); - - do_exec(arg_list, paths); - ::exit(127); - } - } - -/** -* Shutdown the pipe -*/ -void DataSource_Command::shutdown_pipe() - { - if(pipe) - { - pid_t reaped = waitpid(pipe->pid, nullptr, WNOHANG); - - if(reaped == 0) - { - kill(pipe->pid, SIGTERM); - - struct ::timeval tv; - tv.tv_sec = 0; - tv.tv_usec = KILL_WAIT; - select(0, nullptr, nullptr, nullptr, &tv); - - reaped = ::waitpid(pipe->pid, nullptr, WNOHANG); - - if(reaped == 0) - { - ::kill(pipe->pid, SIGKILL); - do - reaped = ::waitpid(pipe->pid, nullptr, 0); - while(reaped == -1); - } - } - - delete pipe; - pipe = nullptr; - } - } - -/** -* DataSource_Command Constructor -*/ -DataSource_Command::DataSource_Command(const std::string& prog_and_args, - const std::vector<std::string>& paths) : - MAX_BLOCK_USECS(100000), KILL_WAIT(10000) - { - arg_list = split_on(prog_and_args, ' '); - - if(arg_list.size() == 0) - throw Invalid_Argument("DataSource_Command: No command given"); - if(arg_list.size() > 5) - throw Invalid_Argument("DataSource_Command: Too many args"); - - pipe = nullptr; - create_pipe(paths); - } - -/** -* DataSource_Command Destructor -*/ -DataSource_Command::~DataSource_Command() - { - if(!end_of_data()) - shutdown_pipe(); - } - -} diff --git a/src/entropy/unix_procs/unix_cmd.h b/src/entropy/unix_procs/unix_cmd.h deleted file mode 100644 index 7c2483c10..000000000 --- a/src/entropy/unix_procs/unix_cmd.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -* Unix Command Execution -* (C) 1999-2007 Jack Lloyd -* 2012 Markus Wanner -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_UNIX_CMD_H__ -#define BOTAN_UNIX_CMD_H__ - -#include <botan/types.h> -#include <botan/data_src.h> -#include <string> -#include <vector> - -namespace Botan { - -/** -* Unix Program Info -*/ -struct Unix_Program - { - /** - * @param n is the name and arguments of what we are going run - * @param p is the priority level (lower prio numbers get polled first) - */ - Unix_Program(const char* n, size_t p) - { name_and_args = n; priority = p; working = true; } - - /** - * The name and arguments for this command - */ - std::string name_and_args; - - /** - * Priority: we scan from low to high - */ - size_t priority; - - /** - * Does this source seem to be working? - */ - bool working; - }; - -/** -* Command Output DataSource -*/ -class DataSource_Command : public DataSource - { - public: - size_t read(byte[], size_t); - size_t peek(byte[], size_t, size_t) const; - bool end_of_data() const; - std::string id() const; - size_t get_bytes_read() const; - - int fd() const; - - DataSource_Command(const std::string&, - const std::vector<std::string>& paths); - ~DataSource_Command(); - private: - void create_pipe(const std::vector<std::string>&); - void shutdown_pipe(); - - const size_t MAX_BLOCK_USECS, KILL_WAIT; - - std::vector<std::string> arg_list; - struct pipe_wrapper* pipe; - size_t bytes_read; - }; - -} - -#endif diff --git a/src/entropy/unix_procs/unix_proc_sources.cpp b/src/entropy/unix_procs/unix_proc_sources.cpp new file mode 100644 index 000000000..6cf185064 --- /dev/null +++ b/src/entropy/unix_procs/unix_proc_sources.cpp @@ -0,0 +1,65 @@ +/* +* Program List for Unix_EntropySource +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/internal/unix_procs.h> + +namespace Botan { + +/** +* Default Commands for Entropy Gathering +*/ +std::vector<std::vector<std::string>> Unix_EntropySource::get_default_sources() + { + std::vector<std::vector<std::string>> srcs; + + srcs.push_back({ "netstat", "-in" }); + srcs.push_back({ "pfstat" }); + srcs.push_back({ "vmstat", "-s" }); + srcs.push_back({ "vmstat" }); + + srcs.push_back({ "arp", "-a", "-n" }); + srcs.push_back({ "ifconfig", "-a" }); + srcs.push_back({ "iostat" }); + srcs.push_back({ "ipcs", "-a" }); + srcs.push_back({ "mpstat" }); + srcs.push_back({ "netstat", "-an" }); + srcs.push_back({ "netstat", "-s" }); + srcs.push_back({ "nfsstat" }); + srcs.push_back({ "portstat" }); + srcs.push_back({ "procinfo", "-a" }); + srcs.push_back({ "pstat", "-T" }); + srcs.push_back({ "pstat", "-s" }); + srcs.push_back({ "uname", "-a" }); + srcs.push_back({ "uptime" }); + + srcs.push_back({ "listarea" }); + srcs.push_back({ "listdev" }); + srcs.push_back({ "ps", "-A" }); + srcs.push_back({ "sysinfo" }); + + srcs.push_back({ "finger" }); + srcs.push_back({ "mailstats" }); + srcs.push_back({ "rpcinfo", "-p", "localhost" }); + srcs.push_back({ "who" }); + + srcs.push_back({ "df", "-l" }); + srcs.push_back({ "dmesg" }); + srcs.push_back({ "last", "-5" }); + srcs.push_back({ "ls", "-alni", "/proc" }); + srcs.push_back({ "ls", "-alni", "/tmp" }); + srcs.push_back({ "pstat", "-f" }); + + srcs.push_back({ "ps", "-elf" }); + srcs.push_back({ "ps", "aux" }); + + srcs.push_back({ "lsof", "-n" }); + srcs.push_back({ "sar", "-A" }); + + return srcs; + } + +} diff --git a/src/entropy/unix_procs/unix_procs.cpp b/src/entropy/unix_procs/unix_procs.cpp new file mode 100644 index 000000000..8d7bf4e48 --- /dev/null +++ b/src/entropy/unix_procs/unix_procs.cpp @@ -0,0 +1,277 @@ +/* +* Gather entropy by running various system commands in the hopes that +* some of the output cannot be guessed by a remote attacker. +* +* (C) 1999-2009,2013 Jack Lloyd +* 2012 Markus Wanner +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/internal/unix_procs.h> +#include <botan/parsing.h> +#include <algorithm> + +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <sys/resource.h> +#include <unistd.h> + +namespace Botan { + +namespace { + +std::string find_full_path_if_exists(const std::vector<std::string>& trusted_path, + const std::string& proc) + { + for(auto dir : trusted_path) + { + const std::string full_path = dir + "/" + proc; + if(::access(full_path.c_str(), X_OK) == 0) + return full_path; + } + + return ""; + } + +size_t concurrent_processes(size_t user_request) + { + const size_t DEFAULT_CONCURRENT = 2; + const size_t MAX_CONCURRENT = 8; + + if(user_request > 0 && user_request < MAX_CONCURRENT) + return user_request; + + const long online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN); + + if(online_cpus > 0) + return static_cast<size_t>(online_cpus); // maybe fewer? + + return DEFAULT_CONCURRENT; + } + +} + +/** +* Unix_EntropySource Constructor +*/ +Unix_EntropySource::Unix_EntropySource(const std::vector<std::string>& trusted_path, + size_t proc_cnt) : + m_trusted_paths(trusted_path), + m_concurrent(concurrent_processes(proc_cnt)) + { + } + +void Unix_EntropySource::fast_poll(Entropy_Accumulator& accum) + { + const char* stat_targets[] = { + "/", + "/tmp", + "/var/tmp", + "/usr", + "/home", + "/etc/passwd", + ".", + "..", + nullptr + }; + + for(size_t i = 0; stat_targets[i]; i++) + { + struct stat statbuf; + clear_mem(&statbuf, 1); + ::stat(stat_targets[i], &statbuf); + accum.add(&statbuf, sizeof(statbuf), 0.0); + } + + accum.add(::getpid(), 0.0); + accum.add(::getppid(), 0.0); + accum.add(::getuid(), 0.0); + accum.add(::getgid(), 0.0); + accum.add(::getpgrp(), 0.0); + + struct ::rusage usage; + ::getrusage(RUSAGE_SELF, &usage); + accum.add(usage, 0.0); + + ::getrusage(RUSAGE_CHILDREN, &usage); + accum.add(usage, 0.0); + } + +namespace { + +void do_exec(const std::vector<std::string>& args) + { + // cleaner way to do this? + const char* arg0 = (args.size() > 0) ? args[0].c_str() : nullptr; + const char* arg1 = (args.size() > 1) ? args[1].c_str() : nullptr; + const char* arg2 = (args.size() > 2) ? args[2].c_str() : nullptr; + const char* arg3 = (args.size() > 3) ? args[3].c_str() : nullptr; + const char* arg4 = (args.size() > 4) ? args[4].c_str() : nullptr; + + ::execl(arg0, arg0, arg1, arg2, arg3, arg4, NULL); + } + +} + +void Unix_EntropySource::Unix_Process::spawn(const std::vector<std::string>& args) + { + shutdown(); + + int pipe[2]; + if(::pipe(pipe) != 0) + return; + + pid_t pid = ::fork(); + + if(pid == -1) + { + ::close(pipe[0]); + ::close(pipe[1]); + } + else if(pid > 0) // in parent + { + m_pid = pid; + m_fd = pipe[0]; + ::close(pipe[1]); + } + else // in child + { + if(::dup2(pipe[1], STDOUT_FILENO) == -1) + ::exit(127); + if(::close(pipe[0]) != 0 || ::close(pipe[1]) != 0) + ::exit(127); + if(close(STDERR_FILENO) != 0) + ::exit(127); + + do_exec(args); + ::exit(127); + } + } + +void Unix_EntropySource::Unix_Process::shutdown() + { + if(m_pid == -1) + return; + + ::close(m_fd); + m_fd = -1; + + pid_t reaped = waitpid(m_pid, nullptr, WNOHANG); + + if(reaped == 0) + { + /* + * Child is still alive - send it SIGTERM, sleep for a bit and + * try to reap again, if still alive send SIGKILL + */ + kill(m_pid, SIGTERM); + + struct ::timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 1000; + select(0, nullptr, nullptr, nullptr, &tv); + + reaped = ::waitpid(m_pid, nullptr, WNOHANG); + + if(reaped == 0) + { + ::kill(m_pid, SIGKILL); + do + reaped = ::waitpid(m_pid, nullptr, 0); + while(reaped == -1); + } + } + + m_pid = -1; + } + +const std::vector<std::string>& Unix_EntropySource::next_source() + { + const auto& src = m_sources.at(m_sources_idx); + m_sources_idx = (m_sources_idx + 1) % m_sources.size(); + return src; + } + +void Unix_EntropySource::poll(Entropy_Accumulator& accum) + { + //fast_poll(accum); + + // refuse to run as root (maybe instead setuid to nobody before exec?) + // fixme: this should also check for setgid + if(::getuid() == 0 || ::geteuid() == 0) + return; + + if(m_sources.empty()) + { + auto sources = get_default_sources(); + + for(auto src : sources) + { + const std::string path = find_full_path_if_exists(m_trusted_paths, src[0]); + if(path != "") + { + src[0] = path; + m_sources.push_back(src); + } + } + } + + if(m_sources.empty()) + return; // still empty, really nothing to try + + const size_t MS_WAIT_TIME = 32; + const double ENTROPY_ESTIMATE = 1.0 / 1024; + + secure_vector<byte>& io_buffer = accum.get_io_buffer(4*1024); // page + + while(!accum.polling_goal_achieved()) + { + while(m_procs.size() < m_concurrent) + m_procs.emplace_back(Unix_Process(next_source())); + + fd_set read_set; + FD_ZERO(&read_set); + + std::vector<int> fds; + + for(auto& proc : m_procs) + { + int fd = proc.fd(); + if(fd > 0) + { + fds.push_back(fd); + FD_SET(fd, &read_set); + } + } + + if(fds.empty()) + break; + + const int max_fd = *std::max_element(fds.begin(), fds.end()); + + struct ::timeval timeout; + timeout.tv_sec = (MS_WAIT_TIME / 1000); + timeout.tv_usec = (MS_WAIT_TIME % 1000) * 1000; + + if(::select(max_fd + 1, &read_set, 0, 0, &timeout) < 0) + return; // or continue? + + for(auto& proc : m_procs) + { + int fd = proc.fd(); + + if(FD_ISSET(fd, &read_set)) + { + const ssize_t got = ::read(fd, &io_buffer[0], io_buffer.size()); + if(got > 0) + accum.add(&io_buffer[0], got, ENTROPY_ESTIMATE); + else + proc.spawn(next_source()); + } + } + } + } + +} diff --git a/src/entropy/unix_procs/unix_procs.h b/src/entropy/unix_procs/unix_procs.h new file mode 100644 index 000000000..fa92fbe20 --- /dev/null +++ b/src/entropy/unix_procs/unix_procs.h @@ -0,0 +1,83 @@ +/* +* Unix EntropySource +* (C) 1999-2009,2013 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_ENTROPY_SRC_UNIX_H__ +#define BOTAN_ENTROPY_SRC_UNIX_H__ + +#include <botan/entropy_src.h> +#include <vector> +#include <sys/types.h> + +namespace Botan { + +/** +* Entropy source for generic Unix. Runs various programs trying to +* gather data hard for a remote attacker to guess. Probably not too +* effective against local attackers as they can sample from the same +* distribution. +*/ +class Unix_EntropySource : public EntropySource + { + public: + std::string name() const { return "Unix Process Runner"; } + + void poll(Entropy_Accumulator& accum) override; + + void fast_poll(Entropy_Accumulator& accum); + + /** + * @param trusted_paths is a list of directories that are assumed + * to contain only 'safe' binaries. If an attacker can write + * an executable to one of these directories then we will + * run arbitrary code. + */ + Unix_EntropySource(const std::vector<std::string>& trusted_paths, + size_t concurrent_processes = 0); + private: + static std::vector<std::vector<std::string>> get_default_sources(); + + class Unix_Process + { + public: + int fd() const { return m_fd; } + + void spawn(const std::vector<std::string>& args); + void shutdown(); + + Unix_Process() {} + + Unix_Process(const std::vector<std::string>& args) { spawn(args); } + + ~Unix_Process() { shutdown(); } + + Unix_Process(Unix_Process&& other) + { + std::swap(m_fd, other.m_fd); + std::swap(m_pid, other.m_pid); + } + + Unix_Process(const Unix_Process&) = delete; + Unix_Process& operator=(const Unix_Process&) = delete; + private: + int m_fd = -1; + pid_t m_pid = -1; + }; + + const std::vector<std::string>& next_source(); + + const std::vector<std::string> m_trusted_paths; + const size_t m_concurrent; + + std::vector<std::vector<std::string>> m_sources; + size_t m_sources_idx = 0; + + std::vector<Unix_Process> m_procs; + }; + +} + +#endif diff --git a/src/entropy/unix_procs/unix_src.cpp b/src/entropy/unix_procs/unix_src.cpp deleted file mode 100644 index 51af6bd40..000000000 --- a/src/entropy/unix_procs/unix_src.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* -* Program List for Unix_EntropySource -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/internal/es_unix.h> - -namespace Botan { - -/** -* Default Commands for Entropy Gathering -*/ -std::vector<Unix_Program> Unix_EntropySource::get_default_sources() - { - std::vector<Unix_Program> srcs; - - srcs.push_back(Unix_Program("netstat -in", 1)); - srcs.push_back(Unix_Program("pfstat", 1)); - srcs.push_back(Unix_Program("vmstat -s", 1)); - srcs.push_back(Unix_Program("vmstat", 1)); - - srcs.push_back(Unix_Program("arp -a -n", 2)); - srcs.push_back(Unix_Program("ifconfig -a", 2)); - srcs.push_back(Unix_Program("iostat", 2)); - srcs.push_back(Unix_Program("ipcs -a", 2)); - srcs.push_back(Unix_Program("mpstat", 2)); - srcs.push_back(Unix_Program("netstat -an", 2)); - srcs.push_back(Unix_Program("netstat -s", 2)); - srcs.push_back(Unix_Program("nfsstat", 2)); - srcs.push_back(Unix_Program("portstat", 2)); - srcs.push_back(Unix_Program("procinfo -a", 2)); - srcs.push_back(Unix_Program("pstat -T", 2)); - srcs.push_back(Unix_Program("pstat -s", 2)); - srcs.push_back(Unix_Program("uname -a", 2)); - srcs.push_back(Unix_Program("uptime", 2)); - - srcs.push_back(Unix_Program("listarea", 3)); - srcs.push_back(Unix_Program("listdev", 3)); - srcs.push_back(Unix_Program("ps -A", 3)); - srcs.push_back(Unix_Program("sysinfo", 3)); - - srcs.push_back(Unix_Program("finger", 4)); - srcs.push_back(Unix_Program("mailstats", 4)); - srcs.push_back(Unix_Program("rpcinfo -p localhost", 4)); - srcs.push_back(Unix_Program("who", 4)); - - srcs.push_back(Unix_Program("df -l", 4)); - srcs.push_back(Unix_Program("dmesg", 4)); - srcs.push_back(Unix_Program("last -5", 4)); - srcs.push_back(Unix_Program("ls -alni /proc", 4)); - srcs.push_back(Unix_Program("ls -alni /tmp", 4)); - srcs.push_back(Unix_Program("pstat -f", 4)); - - srcs.push_back(Unix_Program("ps -elf", 5)); - srcs.push_back(Unix_Program("ps aux", 5)); - - srcs.push_back(Unix_Program("lsof -n", 6)); - srcs.push_back(Unix_Program("sar -A", 6)); - - return srcs; - } - -} |