Botan
1.11.15
|
#include <unix_procs.h>
Classes | |
class | Unix_Process |
Public Member Functions | |
std::string | name () const |
void | poll (Entropy_Accumulator &accum) override |
Unix_EntropySource (const std::vector< std::string > &trusted_paths, size_t concurrent_processes=0) | |
Static Public Member Functions | |
static void | poll_available_sources (class Entropy_Accumulator &accum) |
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.
Definition at line 23 of file unix_procs.h.
Botan::Unix_EntropySource::Unix_EntropySource | ( | const std::vector< std::string > & | trusted_path, |
size_t | proc_cnt = 0 |
||
) |
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 Constructor
Definition at line 62 of file unix_procs.cpp.
: m_trusted_paths(trusted_path), m_concurrent(concurrent_processes(proc_cnt)) { }
std::string Botan::Unix_EntropySource::name | ( | ) | const [inline, virtual] |
Implements Botan::EntropySource.
Definition at line 26 of file unix_procs.h.
{ return "Unix Process Runner"; }
void Botan::Unix_EntropySource::poll | ( | Entropy_Accumulator & | accum | ) | [override, virtual] |
Perform an entropy gathering poll
accum | is an accumulator object that will be given entropy |
Implements Botan::EntropySource.
Definition at line 187 of file unix_procs.cpp.
References Botan::Entropy_Accumulator::add(), Botan::Entropy_Accumulator::get_io_buffer(), and Botan::Entropy_Accumulator::polling_goal_achieved().
{ // refuse to run setuid or setgid, or as root if((getuid() != geteuid()) || (getgid() != getegid()) || (geteuid() == 0)) return; std::lock_guard<std::mutex> lock(m_mutex); 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, nullptr, nullptr, &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()); } } } }
void Botan::EntropySource::poll_available_sources | ( | class Entropy_Accumulator & | accum | ) | [static, inherited] |
Definition at line 108 of file entropy_srcs.cpp.
References Botan::Entropy_Accumulator::polling_goal_achieved().
Referenced by Botan::HMAC_RNG::reseed().
{ static std::vector<std::unique_ptr<EntropySource>> g_sources(get_default_entropy_sources()); if(g_sources.empty()) throw std::runtime_error("No entropy sources enabled at build time, poll failed"); size_t poll_attempt = 0; while(!accum.polling_goal_achieved() && poll_attempt < 16) { const size_t src_idx = poll_attempt % g_sources.size(); g_sources[src_idx]->poll(accum); ++poll_attempt; } }