Botan  1.10.9
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 
18 namespace Botan {
19 
20 namespace {
21 
22 /**
23 * Sort ordering by priority
24 */
25 bool 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 */
38 Unix_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 */
48 void 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 }
MemoryRegion< byte > & get_io_buffer(size_t size)
Definition: entropy_src.h:38
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:32
void add(const void *bytes, size_t length, double entropy_bits_per_byte)
Definition: entropy_src.h:70
size_t read(byte[], size_t)
Definition: unix_cmd.cpp:63
bool end_of_data() const
Definition: unix_cmd.cpp:105
Unix_EntropySource(const std::vector< std::string > &path)
Definition: es_unix.cpp:38
bool polling_goal_achieved() const
Definition: entropy_src.h:50
size_t size() const
Definition: secmem.h:29
void poll(Entropy_Accumulator &accum)
Definition: es_unix.cpp:60
void add_sources(const Unix_Program[], size_t)
Definition: es_unix.cpp:48