00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef _WIN32
00024 #pragma warning(disable:4786)
00025 #endif
00026 #include "SSLInitializer.h"
00027 #ifdef HAVE_OPENSSL
00028 #include <map>
00029 #include "Utility.h"
00030 #include <openssl/rand.h>
00031 #include "Mutex.h"
00032
00033 #ifdef _DEBUG
00034 #define DEB(x) x
00035 #else
00036 #define DEB(x)
00037 #endif
00038
00039
00040 #ifdef SOCKETS_NAMESPACE
00041 namespace SOCKETS_NAMESPACE {
00042 #endif
00043
00044
00045 BIO *SSLInitializer::bio_err = NULL;
00046 std::string SSLInitializer::m_rand_file;
00047 long SSLInitializer::m_rand_size = 1024;
00048
00049
00050 SSLInitializer::SSLInitializer()
00051 {
00052 DEB( fprintf(stderr, "SSLInitializer()\n");)
00053
00054
00055 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
00056
00057
00058 SSL_library_init();
00059 SSL_load_error_strings();
00060 OpenSSL_add_all_algorithms();
00061 CRYPTO_set_locking_callback( SSL_locking_function );
00062 CRYPTO_set_id_callback( SSL_id_function );
00063
00064 char *randfile = getenv("RANDFILE");
00065 char *home = getenv("HOME");
00066 if (!randfile && !home)
00067 {
00068 char *homepath = getenv("HOMEPATH");
00069 if (homepath)
00070 {
00071 Utility::SetEnv("HOME", homepath);
00072 }
00073 }
00074 char path[512];
00075 *path = 0;
00076 RAND_file_name(path, 512);
00077 if (*path)
00078 {
00079 m_rand_file = path;
00080 m_rand_size = 1024;
00081 RAND_write_file(path);
00082 }
00083 else
00084 {
00085 DEB( fprintf(stderr, "SSLInitializer: no random file generated\n");)
00086 }
00087
00088
00089 if (!m_rand_file.size() || !RAND_load_file(m_rand_file.c_str(), m_rand_size))
00090 {
00091 DEB( fprintf(stderr, "SSLInitializer: PRNG not initialized\n");)
00092 }
00093
00094 }
00095
00096
00097 SSLInitializer::~SSLInitializer()
00098 {
00099 DEB( fprintf(stderr, "~SSLInitializer()\n");)
00100 DeleteRandFile();
00101
00102 }
00103
00104
00105 void SSLInitializer::DeleteRandFile()
00106 {
00107 if (m_rand_file.size())
00108 {
00109 unlink(m_rand_file.c_str());
00110 }
00111 }
00112
00113
00114 void SSLInitializer::SSL_locking_function(int mode, int n, const char *file, int line)
00115 {
00116 static std::map<int, Mutex *> mmap;
00117 if (mmap.find(n) == mmap.end())
00118 {
00119 mmap[n] = new Mutex;
00120 }
00121 if (mode & CRYPTO_LOCK)
00122 {
00123 mmap[n] -> Lock();
00124 }
00125 else
00126 {
00127 mmap[n] -> Unlock();
00128 }
00129 }
00130
00131
00132 unsigned long SSLInitializer::SSL_id_function()
00133 {
00134 return Utility::ThreadID();
00135 }
00136
00137
00138 #ifdef SOCKETS_NAMESPACE
00139 }
00140 #endif
00141 #endif // HAVE_OPENSSL