00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _PASSENGER_RANDOM_GENERATOR_H_
00026 #define _PASSENGER_RANDOM_GENERATOR_H_
00027
00028 #include <string>
00029
00030 #include <boost/noncopyable.hpp>
00031 #include <boost/shared_ptr.hpp>
00032 #include <oxt/system_calls.hpp>
00033
00034 #include "StaticString.h"
00035 #include "Utils.h"
00036 #include "Exceptions.h"
00037
00038
00039
00040
00041
00042 namespace Passenger {
00043
00044 using namespace std;
00045 using namespace boost;
00046 using namespace oxt;
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 class RandomGenerator: public boost::noncopyable {
00061 private:
00062 FILE *handle;
00063
00064 public:
00065 RandomGenerator(bool open = true) {
00066 handle = NULL;
00067 if (open) {
00068 reopen();
00069 }
00070 }
00071
00072 ~RandomGenerator() {
00073 this_thread::disable_syscall_interruption dsi;
00074 close();
00075 }
00076
00077 void reopen() {
00078 close();
00079 handle = syscalls::fopen("/dev/urandom", "r");
00080 if (handle == NULL) {
00081 throw FileSystemException("Cannot open /dev/urandom",
00082 errno, "/dev/urandom");
00083 }
00084 }
00085
00086 void close() {
00087 if (handle != NULL) {
00088 syscalls::fclose(handle);
00089 handle = NULL;
00090 }
00091 }
00092
00093 StaticString generateBytes(void *buf, unsigned int size) {
00094 size_t ret = syscalls::fread(buf, 1, size, handle);
00095 if (ret != size) {
00096 throw IOException("Cannot read sufficient data from /dev/urandom");
00097 }
00098 return StaticString((const char *) buf, size);
00099 }
00100
00101 string generateByteString(unsigned int size) {
00102 char buf[size];
00103 generateBytes(buf, size);
00104 return string(buf, size);
00105 }
00106
00107 string generateHexString(unsigned int size) {
00108 char buf[size];
00109 generateBytes(buf, size);
00110 return toHex(StaticString(buf, size));
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 string generateAsciiString(unsigned int size) {
00125 static const char chars[] = {
00126 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
00127 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
00128 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
00129 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
00130 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
00131 };
00132 unsigned char buf[size];
00133 generateBytes(buf, size);
00134 for (unsigned int i = 0; i < size; i++) {
00135 buf[i] = chars[buf[i] % sizeof(chars)];
00136 }
00137 return string((const char *) buf, size);
00138 }
00139
00140 int generateInt() {
00141 int ret;
00142 generateBytes(&ret, sizeof(ret));
00143 return ret;
00144 }
00145
00146 unsigned int generateUint() {
00147 return (unsigned int) generateInt();
00148 }
00149 };
00150
00151 typedef shared_ptr<RandomGenerator> RandomGeneratorPtr;
00152
00153 }
00154
00155 #endif