CMSDK 2.0.1
Cross-platform C++ base library and SDK for the Psyclone AIOS platform
Loading...
Searching...
No Matches
PsySSL.cpp
Go to the documentation of this file.
1
7#include "PsySSL.h"
8
9namespace cmlabs{
10
11#ifdef _USE_SSL_
12
13SSLServer::SSLServer(const char *cFile, const char *kFile, int port) {
14
15 PORT = port;
16 CreateCTX();
17 LoadCerts(cFile, kFile);
18
19 // Get the server started.
20 BindPort();
21}
22
23void SSLServer::CheckClients(int wait_t) {
24 struct timeval tv;
25
26 // Set how long to block.
27 tv.tv_sec = wait_t;
28 tv.tv_usec = 0;
29
30 FD_ZERO(&fdset);
31 FD_SET(master, &fdset);
32
33 select(master+1, &fdset, NULL, NULL, (struct timeval *)&tv);
34
35 // If master is set then someone is trying to connect
36 if(FD_ISSET(master, &fdset)) {
37 SSL *ssl;
38
39 // Open up new connection
40 // struct sockaddr_in addr;
41 // int len = sizeof(addr);
42 //int client = (int)accept(master, (struct sockaddr *)&addr, (int *)&len);
43 int client = (int)accept(master, NULL, NULL);
44
46
47
48#ifdef DEBUG
49 struct in_addr ip_address;
50 memcpy(&ip_address, &addr.sin_addr.s_addr, 4);
51
52 cout << "\n\n---------------------------------------------\n";
53 cout << "Connection from: " << inet_ntoa(ip_address) << " ("
54 << ntohs(addr.sin_port) << ")\n";
55#endif /* DEBUG */
56
57 if(client == -1)
58 perror("accept");
59
60 ssl = SSL_new(ctx);
61 SSL_set_fd(ssl, client);
62
63#ifdef DEBUG
64 cout << "Creating Thread\n";
65#endif /* DEBUG */
66
67 //pthread_t thread;
68 //if(pthread_create(&thread, NULL, pthr_f, (void *)ssl) != 0) {
69 // fprintf(stderr, "pthread_create() has failed.\n");
70 // exit(1);
71 //}
72#ifdef WINDOWS
73 DWORD dwThreadId;
74 HANDLE thread = ::CreateThread(
75 NULL, // no security attributes
76 0, // use default stack size
77 (LPTHREAD_START_ROUTINE) pthr_f, // thread function
78 (void *)ssl, // argument to thread function
79 0, // use default creation flags
80 &dwThreadId); // returns the thread identifier
81 utils::Sleep(10);
82#endif
83 }
84}
85
86void SSLServer::BindPort(void) {
87#ifdef WINDOWS
88 WSADATA info;
89 WSAStartup(MAKEWORD(1,1), &info);
90#endif
91
92 struct sockaddr_in addr;
93
94// master = socket(PF_INET, SOCK_STREAM, 0);
95 master = (int)socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
96 memset(&addr, 0, sizeof(addr));
97
98 addr.sin_family = AF_INET;
99 addr.sin_port = htons(PORT);
100 addr.sin_addr.s_addr = INADDR_ANY;
101
102 // Open the socket
103 if(::bind(master, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
104 perror("bind");
105 _exit(1);
106 }
107
108// unsigned long parm = 1; // 1 = Non-blocking, 0 = Blocking
109// ioctlsocket(master, FIONBIO, &parm);
110
111 // Set a limit on connection queue.
112 if(listen(master, 5) != 0) {
113 perror("listen");
114 _exit(1);
115 }
116
117}
118
119void SSLServer::CreateCTX(void) {
120 // The method describes which SSL protocol we will be using.
121 const SSL_METHOD *method;
122
123 SSL_library_init();
124 // Load algorithms and error strings.
125 OpenSSL_add_all_algorithms();
126 SSL_load_error_strings();
127
128 // Compatible with SSLv2, SSLv3 and TLSv1
129 method = SSLv23_server_method();
130
131 // Create new context from method.
132 ctx = SSL_CTX_new(method);
133 if(ctx == NULL) {
134 ERR_print_errors_fp(stderr);
135 _exit(1);
136 }
137}
138
139/* Load the certification files, ie the public and private keys. */
140void SSLServer::LoadCerts(const char *cFile, const char *kFile) {
141 if ( SSL_CTX_use_certificate_chain_file(ctx, cFile) <= 0) {
142 ERR_print_errors_fp(stderr);
143 _exit(1);
144 }
145 if ( SSL_CTX_use_PrivateKey_file(ctx, kFile, SSL_FILETYPE_PEM) <= 0) {
146 ERR_print_errors_fp(stderr);
147 _exit(1);
148 }
149
150 // Verify that the two keys goto together.
151 if ( !SSL_CTX_check_private_key(ctx) ) {
152 fprintf(stderr, "Private key is invalid.\n");
153 _exit(1);
154 }
155}
156
157
158
159
160#define REPLY "<html><body>Metalshell.com OpenSSL Server</body></html>"
161#define MAX_PACKET_SIZE 1024
162
163// Called when a new connection is made.
164void *conn_thread(void *ssl) {
165 int fd = SSL_get_fd((SSL *)ssl);
166
167 bool success = true;
168 int c = 0;
169 while(SSL_accept((SSL *)ssl) == -1) {
170 if (++c > 100) {
171 success = false;
172 break;
173 }
174 utils::Sleep(10);
175 }
176
177
178 if(!success) {
179 ERR_print_errors_fp(stderr);
180 } else {
181 char cipdesc[128];
182 const SSL_CIPHER *sslciph = SSL_get_current_cipher((SSL *)ssl);
183
184 cout << "Encryption Description:\n";
185 cout << SSL_CIPHER_description(sslciph, cipdesc, sizeof(cipdesc)) << endl;
186
187 int bytes;
188 char* buff = new char[MAX_PACKET_SIZE];
189 // Wait for data to be sent.
190 while ((bytes = SSL_read((SSL *)ssl, buff, sizeof(buff))) <= 0) {
191 utils::Sleep(10);
192 }
193 buff[bytes] = '\0';
194
195 // Show the browser request.
196 cout << "Recieved: \n" << buff << endl;
197
198 // Send the html reply.
199 SSL_write((SSL *)ssl, REPLY, (int)strlen(REPLY));
200 delete [] buff;
201 }
202
203 // Tell the client we are closing the connection.
204 SSL_shutdown((SSL *)ssl);
205
206 // We do not wait for a reply, just clear everything.
207 SSL_free((SSL *)ssl);
208 closesocket(fd);
209
210 cout << "Connection Closed\n";
211 cout << "---------------------------------------------\n";
212
213 //pthread_exit(NULL);
214 return NULL;
215}
216
217int TestSSL(int port) {
218 SSLServer server("cert", "pkey", port);
219
220 // Set the thread function.
221 server.SetPthread_F(conn_thread);
222
223 while(1) {
224 /* Wait for 10 seconds, and if no one trys
225 * to connect return back. This allows us to do
226 * other things while waiting.
227 */
228 server.CheckClients(10);
229 }
230
231 return 0;
232}
233
234#else // _USE_SSL_
235
236int TestSSL(int port) {return 0;}
237
238#endif //_USE_SSL_
239
240}
Minimal OpenSSL-based TLS server helpers for the CMSDK.
#define closesocket(X)
Definition Utils.h:138
bool Sleep(uint32 ms)
Suspend the calling thread.
Definition Utils.cpp:2802
bool SetSocketNonBlockingMode(SOCKET s)
Put a socket into non-blocking mode.
Definition Utils.cpp:5337
int TestSSL(int port)
Standalone smoke test for the SSL server functionality.
Definition PsySSL.cpp:236