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