Botan 1.10.17
es_unix.cpp
Go to the documentation of this file.
1/*
2* Unix EntropySource
3* (C) 1999-2009 Jack Lloyd
4*
5* Distributed under the terms of the Botan license
6*/
7
8#include <botan/internal/es_unix.h>
9#include <botan/internal/unix_cmd.h>
10#include <botan/parsing.h>
11#include <algorithm>
12
13#include <sys/time.h>
14#include <sys/stat.h>
15#include <sys/resource.h>
16#include <unistd.h>
17
18namespace Botan {
19
20namespace {
21
22/**
23* Sort ordering by priority
24*/
25bool Unix_Program_Cmp(const Unix_Program& a, const Unix_Program& b)
26 {
27 if(a.priority == b.priority)
28 return (a.name_and_args < b.name_and_args);
29
30 return (a.priority < b.priority);
31 }
32
33}
34
35/**
36* Unix_EntropySource Constructor
37*/
38Unix_EntropySource::Unix_EntropySource(const std::vector<std::string>& path) :
39 PATH(path)
40 {
41 std::vector<Unix_Program> default_sources = get_default_sources();
42 add_sources(&default_sources[0], default_sources.size());
43 }
44
45/**
46* Add sources to the list
47*/
48void Unix_EntropySource::add_sources(const Unix_Program srcs[], size_t count)
49 {
50 sources.insert(sources.end(), srcs, srcs + count);
51 std::sort(sources.begin(), sources.end(), Unix_Program_Cmp);
52 }
53
54/**
55* Poll for entropy on a generic Unix system, first by grabbing various
56* statistics (stat on common files, getrusage, etc), and then, if more
57* is required, by exec'ing various programs like uname and rpcinfo and
58* reading the output.
59*/
61 {
62 const char* stat_targets[] = {
63 "/",
64 "/tmp",
65 "/var/tmp",
66 "/usr",
67 "/home",
68 "/etc/passwd",
69 ".",
70 "..",
71 0 };
72
73 for(size_t i = 0; stat_targets[i]; i++)
74 {
75 struct stat statbuf;
76 clear_mem(&statbuf, 1);
77 if(::stat(stat_targets[i], &statbuf) == 0)
78 accum.add(&statbuf, sizeof(statbuf), .005);
79 }
80
81 accum.add(::getpid(), 0);
82 accum.add(::getppid(), 0);
83 accum.add(::getuid(), 0);
84 accum.add(::getgid(), 0);
85 accum.add(::getpgrp(), 0);
86
87 struct ::rusage usage;
88 ::getrusage(RUSAGE_SELF, &usage);
89 accum.add(usage, .005);
90
91 ::getrusage(RUSAGE_CHILDREN, &usage);
92 accum.add(usage, .005);
93
94 const size_t MINIMAL_WORKING = 16;
95
96 MemoryRegion<byte>& io_buffer = accum.get_io_buffer(DEFAULT_BUFFERSIZE);
97
98 for(size_t i = 0; i != sources.size(); i++)
99 {
100 DataSource_Command pipe(sources[i].name_and_args, PATH);
101
102 size_t got_from_src = 0;
103
104 while(!pipe.end_of_data())
105 {
106 size_t got_this_loop = pipe.read(&io_buffer[0], io_buffer.size());
107 got_from_src += got_this_loop;
108
109 accum.add(&io_buffer[0], got_this_loop, .005);
110 }
111
112 sources[i].working = (got_from_src >= MINIMAL_WORKING) ? true : false;
113
114 if(accum.polling_goal_achieved())
115 break;
116 }
117 }
118
119}
size_t read(byte[], size_t)
Definition unix_cmd.cpp:63
bool polling_goal_achieved() const
Definition entropy_src.h:50
MemoryRegion< byte > & get_io_buffer(size_t size)
Definition entropy_src.h:38
void add(const void *bytes, size_t length, double entropy_bits_per_byte)
Definition entropy_src.h:70
size_t size() const
Definition secmem.h:29
Unix_EntropySource(const std::vector< std::string > &path)
Definition es_unix.cpp:38
void add_sources(const Unix_Program[], size_t)
Definition es_unix.cpp:48
void poll(Entropy_Accumulator &accum)
Definition es_unix.cpp:60
void clear_mem(T *ptr, size_t n)
Definition mem_ops.h:32