source: nscp/include/SSLSocket.cpp @ 65a2940

0.4.00.4.10.4.2
Last change on this file since 65a2940 was 1d84e57, checked in by Michael Medin <michael@…>, 5 years ago

x64 build fixes (as well as bundling of some libraries)

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/**************************************************************************
2*   Copyright (C) 2004-2007 by Michael Medin <michael@medin.name>         *
3*                                                                         *
4*   This code is part of NSClient++ - http://trac.nakednuns.org/nscp      *
5*                                                                         *
6*   This program is free software; you can redistribute it and/or modify  *
7*   it under the terms of the GNU General Public License as published by  *
8*   the Free Software Foundation; either version 2 of the License, or     *
9*   (at your option) any later version.                                   *
10*                                                                         *
11*   This program is distributed in the hope that it will be useful,       *
12*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14*   GNU General Public License for more details.                          *
15*                                                                         *
16*   You should have received a copy of the GNU General Public License     *
17*   along with this program; if not, write to the                         *
18*   Free Software Foundation, Inc.,                                       *
19*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20***************************************************************************/
21//#include "stdafx.h"
22#include <SSLSocket.h>
23
24
25void* simpleSSL::Crypto::malloc(int num)
26{
27        return OPENSSL_malloc(num);
28}
29void simpleSSL::Crypto::free(void *addr)
30{
31        return OPENSSL_free(addr);
32}
33int simpleSSL::Crypto::getNumberOfLocks() {
34        return CRYPTO_num_locks();
35}
36
37void simpleSSL::Crypto::setLockingCallback(void (*locking_function)(int mode,int type, const char *file,int line)) {
38        CRYPTO_set_locking_callback(locking_function);
39}
40void simpleSSL::Crypto::setIDCallback(unsigned long (*id_function)(void)) {
41        CRYPTO_set_id_callback(id_function);
42}
43
44void simpleSSL::SSL_init() {
45        SSL_load_error_strings();
46        SSL_library_init();
47}
48void simpleSSL::SSL_deinit() {
49        /*
50        SSL_library_init, leaks memory but apparently OPEN-SSL is crap, so there is not much to do AFAIK! :)
51        EVP_cleanup();
52        CRYPTO_cleanup_all_ex_data();
53        ERR_remove_state(0);
54        */
55        ERR_free_strings();
56}
57
58void simpleSSL::count_socket(bool add) {
59        static int count = 0;
60        if (add) {
61                count++;
62                std::wcout << "+++SSSL::Socket" << count << std::endl;
63        } else {
64                count--;
65                std::wcout << "---SSSL::Socket" << count << std::endl;
66        }
67}
68
69
70bool simpleSSL::sSSL::readAll(simpleSocket::DataBuffer &buffer, unsigned int tmpBufferLength /* = 1024*/, int maxLength /*= -1*/) {
71        char *tmpBuffer = new char[tmpBufferLength+1];
72        if (!ssl_)
73                create();
74        int n= SSL_read(ssl_,tmpBuffer,tmpBufferLength);
75        if (n > 0) {
76                buffer.append(tmpBuffer, n);
77        }
78        delete [] tmpBuffer;
79        if (n <= 0) {
80                int rc = getError(n);
81                if ((rc == SSL_ERROR_WANT_READ) || (rc == SSL_ERROR_WANT_WRITE))
82                        return true;
83                throw simpleSocket::SocketException(_T("Could not read from socket: ") + strEx::itos(rc));
84        }
85        return n>0;
86}
87
88bool simpleSSL::sSSL::sendAll(const char * buffer, unsigned int len) {
89        if (!ssl_)
90                create();
91        int n = SSL_write(ssl_, buffer, len);
92        if (n <= 0) {
93                int rc = getError(n);
94                if ((rc == SSL_ERROR_WANT_READ) || (rc == SSL_ERROR_WANT_WRITE))
95                        return true;
96                throw simpleSocket::SocketException(_T("Could not write to socket: ") + strEx::itos(rc));
97        }
98        return false;
99}
100
101bool simpleSSL::Listener::accept(tSocket &client) {
102        client.setContext(context);
103        return simpleSocket::Socket::accept(client);
104}
105
106
107
108static HANDLE *lock_cs = NULL;
109
110
111void locking_function(int mode, int n, const char *file, int line)
112{
113        if (mode & CRYPTO_LOCK) {
114                WaitForSingleObject(lock_cs[n], INFINITE);
115        }
116        else {
117                ReleaseMutex(lock_cs[n]);
118        }
119}
120
121void setupDH(simpleSSL::DH &dh) {
122        unsigned char dh512_p[] = {
123                0xCF, 0xFF, 0x65, 0xC2, 0xC8, 0xB4, 0xD2, 0x68, 0x8C, 0xC1, 0x80, 0xB1,
124                        0x7B, 0xD6, 0xE8, 0xB3, 0x62, 0x59, 0x62, 0xED, 0xA7, 0x45, 0x6A, 0xF8,
125                        0xE9, 0xD8, 0xBE, 0x3F, 0x38, 0x42, 0x5F, 0xB2, 0xA5, 0x36, 0x03, 0xD3,
126                        0x06, 0x27, 0x81, 0xC8, 0x9B, 0x88, 0x50, 0x3B, 0x82, 0x3D, 0x31, 0x45,
127                        0x2C, 0xB4, 0xC5, 0xA5, 0xBE, 0x6A, 0xE3, 0x2E, 0xA6, 0x86, 0xFD, 0x6A,
128                        0x7E, 0x1E, 0x6A, 0x73,
129        };
130        unsigned char dh512_g[] = { 0x02, };
131
132        dh.bin2bn_p(dh512_p, sizeof(dh512_p));
133        dh.bin2bn_g(dh512_g, sizeof(dh512_g));
134}
135
136int simpleSSL::Socket::connect_() {
137        Context context;
138        context.createSSLv23Client();
139        context.setCipherList();
140        /*
141        simpleSSL::DH dh;
142        dh.create();
143        setupDH(dh);
144        context.setTmpDH(dh.getDH());
145        dh.free();
146        */
147        if (tBase::connect_() == SOCKET_ERROR) {
148                throw simpleSocket::SocketException(_T("Failed to connect to host: ") + inet_ntoa(to_.sin_addr.s_addr), WSAGetLastError());
149        }
150        ssl.setContext(context);
151        ssl.set_fd(socket_);
152        ssl.connect();
153        return 0;
154}
155
156
157void simpleSSL::Listener::StartListener(std::wstring host, int port, unsigned int listenQue) {
158        simpleSSL::SSL_init();
159        context.createSSLv23Server();
160        context.setCipherList();
161        simpleSSL::DH dh;
162        dh.create();
163        setupDH(dh);
164        context.setTmpDH(dh.getDH());
165        dh.free();
166        if (!lock_cs) {
167                lock_cs_count = simpleSSL::Crypto::getNumberOfLocks();
168                lock_cs = reinterpret_cast<HANDLE*>(simpleSSL::Crypto::malloc(lock_cs_count * sizeof(HANDLE)));
169                if (!lock_cs)
170                        throw simpleSocket::SocketException(_T("Could not create SSL handles."));
171                for (int i = 0; i < lock_cs_count; i++) {
172                        lock_cs[i] = CreateMutex(NULL, FALSE, NULL);
173                }
174                simpleSSL::Crypto::setLockingCallback(locking_function);
175        }
176        tBase::StartListener(host, port, listenQue);
177}
178void simpleSSL::Listener::StopListener() {
179        tBase::StopListener();
180
181        context.destroy();
182        if (lock_cs) {
183                simpleSSL::Crypto::setLockingCallback(NULL);
184
185                for (int i = 0; i < lock_cs_count; i++)
186                        CloseHandle(lock_cs[i]);
187                simpleSSL::Crypto::free(lock_cs);
188        }
189        simpleSSL::SSL_deinit();
190}
Note: See TracBrowser for help on using the repository browser.