---------------------------------------------------
| Date: 2003-05-24 12:24:54 |
| Filename: main.cpp |
| Author: detour@metalshell.com |
| |
| http://www.metalshell.com/ |
---------------------------------------------------
/* osslserv.cpp by detour@metalshell.com
*
* A basic threaded OpenSSL server with non-blocking
* connection handling. When a connection is made the thread
* waits for data to be recieved, then sends an html response
* so it can be tested with a browser. The thread closes the
* connection and terminates without waiting for more data. The
* default keys are 'cert' and 'pkey' included.
*
* Creating New Keys:
* - Private Key
* openssl genrsa -out pkey 2048
* - Certificate
* openssl req -new -x509 -key pkey -out cert -days 365
*
* Compile:
* A Makefile is included to compile this example.
*
* Testing:
* https://www.yourhostorip.com:1420/
*
* http://www.metalshell.com/
*
*/
#include
#include
#include
#include
#include
#include
#include "sslserver.h"
#define REPLY "Metalshell.com OpenSSL Server"
#define MAX_PACKET_SIZE 1024
// Called when a new connection is made.
void *conn_thread(void *ssl) {
int fd = SSL_get_fd((SSL *)ssl);
if(SSL_accept((SSL *)ssl) == -1) {
ERR_print_errors_fp(stderr);
} else {
char cipdesc[128];
SSL_CIPHER *sslciph = SSL_get_current_cipher((SSL *)ssl);
cout << "Encryption Description:\n";
cout << SSL_CIPHER_description(sslciph, cipdesc, sizeof(cipdesc)) << endl;
char buff[MAX_PACKET_SIZE];
// Wait for data to be sent.
int bytes = SSL_read((SSL *)ssl, buff, sizeof(buff));
buff[bytes] = '\0';
// Show the browser request.
cout << "Recieved: \n" << buff << endl;
// Send the html reply.
SSL_write((SSL *)ssl, REPLY, strlen(REPLY));
}
// Tell the client we are closing the connection.
SSL_shutdown((SSL *)ssl);
// We do not wait for a reply, just clear everything.
SSL_free((SSL *)ssl);
close(fd);
cout << "Connection Closed\n";
cout << "---------------------------------------------\n";
pthread_exit(NULL);
}
int main() {
SSLServer server("cert", "pkey", 1420);
// Set the thread function.
server.SetPthread_F(conn_thread);
while(1) {
/* Wait for 10 seconds, and if no one trys
* to connect return back. This allows us to do
* other things while waiting.
*/
server.CheckClients(10);
}
return 0;
}
---------------------------------------------------
| Date: 2003-05-24 12:24:54 |
| Filename: sslserver.cpp |
| Author: detour@metalshell.com |
| |
| http://www.metalshell.com/ |
---------------------------------------------------
#include "sslserver.h"
SSLServer::SSLServer(char *cFile, char *kFile, int port) {
PORT = port;
CreateCTX();
LoadCerts(cFile, kFile);
// Get the server started.
BindPort();
}
void SSLServer::CheckClients(int wait_t) {
struct timeval tv;
// Set how long to block.
tv.tv_sec = wait_t;
tv.tv_usec = 0;
FD_ZERO(&fdset);
FD_SET(master, &fdset);
select(master+1, &fdset, NULL, NULL, (struct timeval *)&tv);
// If master is set then someone is trying to connect
if(FD_ISSET(master, &fdset)) {
SSL *ssl;
// Open up new connection
struct sockaddr_in addr;
int len = sizeof(addr);
int client = accept(master, (struct sockaddr *)&addr, (socklen_t *)&len);
#ifdef DEBUG
struct in_addr ip_address;
memcpy(&ip_address, &addr.sin_addr.s_addr, 4);
cout << "\n\n---------------------------------------------\n";
cout << "Connection from: " << inet_ntoa(ip_address) << " ("
<< ntohs(addr.sin_port) << ")\n";
#endif /* DEBUG */
if(client == -1)
perror("accept");
ssl = SSL_new(ctx);
SSL_set_fd(ssl, client);
#ifdef DEBUG
cout << "Creating Thread\n";
#endif /* DEBUG */
pthread_t thread;
if(pthread_create(&thread, NULL, pthr_f, (void *)ssl) != 0) {
fprintf(stderr, "pthread_create() has failed.\n");
exit(1);
}
}
}
void SSLServer::BindPort(void) {
struct sockaddr_in addr;
master = socket(PF_INET, SOCK_STREAM, 0);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = INADDR_ANY;
// Open the socket
if(bind(master, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
perror("bind");
_exit(1);
}
// Set a limit on connection queue.
if(listen(master, 5) != 0) {
perror("listen");
_exit(1);
}
}
void SSLServer::CreateCTX(void) {
// The method describes which SSL protocol we will be using.
SSL_METHOD *method;
// Load algorithms and error strings.
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
// Compatible with SSLv2, SSLv3 and TLSv1
method = SSLv23_server_method();
// Create new context from method.
ctx = SSL_CTX_new(method);
if(ctx == NULL) {
ERR_print_errors_fp(stderr);
_exit(1);
}
}
/* Load the certification files, ie the public and private keys. */
void SSLServer::LoadCerts(char *cFile, char *kFile) {
if ( SSL_CTX_use_certificate_chain_file(ctx, cFile) <= 0) {
ERR_print_errors_fp(stderr);
_exit(1);
}
if ( SSL_CTX_use_PrivateKey_file(ctx, kFile, SSL_FILETYPE_PEM) <= 0) {
ERR_print_errors_fp(stderr);
_exit(1);
}
// Verify that the two keys goto together.
if ( !SSL_CTX_check_private_key(ctx) ) {
fprintf(stderr, "Private key is invalid.\n");
_exit(1);
}
}
---------------------------------------------------
| Date: 2003-05-24 12:24:54 |
| Filename: sslserver.h |
| Author: detour@metalshell.com |
| |
| http://www.metalshell.com/ |
---------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef __SSL_SERVER_H__
#define __SSL_SERVER_H__
using namespace std;
typedef void *(*P_ARG)(void *);
class SSLServer {
// Private data
private:
SSL_CTX *ctx;
int PORT;
fd_set fdset;
// FD for server
int master;
// Thread function
P_ARG pthr_f;
// Private Functions
private:
// Load algorithms and create context.
void CreateCTX(void);
// Load certification files.
void LoadCerts(char *cFile, char *kFile);
// Create and attach socket.
void BindPort(void);
public:
// Set function for pthread to call.
void SetPthread_F(P_ARG fp) { pthr_f = fp; }
// Constructors
SSLServer(char *cFile, char *kFile, int port);
/* Check for new connections, block for wait_t amount of seconds,
if no connection is made within wait_t function returns. This must
be called regularly from within main */
void CheckClients(int wait_t = 0);
};
#endif
---------------------------------------------------
| Date: 2003-05-24 12:24:54 |
| Filename: Makefile |
| Author: detour@metalshell.com |
| |
| http://www.metalshell.com/ |
---------------------------------------------------
OBJS = sslserver.o main.o
EXECUTABLE = sslserver
CC=g++
CFLAGS=-Wall -ggdb -DDEBUG
COMPILE=$(CC) $(CFLAGS) -c
all: sslserver
sslserver: $(OBJS)
$(CC) -lpthread -lssl -o $(EXECUTABLE) $(OBJS)
main.o: main.cpp
$(COMPILE) -o main.o main.cpp
sslserver.o: sslserver.cpp
$(COMPILE) -o sslserver.o sslserver.cpp
clean:
-rm $(OBJS) $(EXECUTABLE)
---------------------------------------------------
| Date: 2003-05-24 12:24:54 |
| Filename: cert |
| Author: detour@metalshell.com |
| |
| http://www.metalshell.com/ |
---------------------------------------------------
-----BEGIN CERTIFICATE-----
MIIDpTCCAo2gAwIBAgIBADANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJVUzET
MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
dHkgTHRkMB4XDTAzMDUyNDE0NTI0MloXDTA2MDUyMzE0NTI0MlowRTELMAkGA1UE
BhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdp
ZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALr7
vaKNMG9FbtEya2+GIX7NGfzEUU/b7Pmt0SaC5bZn/Fo1JNlEPnAtFPqZyW6zcqM5
SrCNCVS0B4H3n2GygssPppa88IkM2FolKhlWjWi2k4b+MGuYWwRGu/UGhEK//ciC
S+fNTHS20+6U4XXLuPbEIv7TQk/GNF2rSNxTBtL/cp8rpIk+fIY59FymZx6/Gxrp
+5vlrbYZFZMPUUd2JgaAUxOy1schetQhoRzrjlDmX9+fmwqKJYQ+ZLb1aCGZZJuR
W/i29CyxQODm1fUBpb1WwEFjXUZb8j2iicLoS9s9nJaUFvd2fImWic/11iYi+ufF
cMRjakVKMYXF24+GZd8CAwEAAaOBnzCBnDAdBgNVHQ4EFgQU2Ejnhbxwj0yLEdaW
BfSbx+qAj2wwbQYDVR0jBGYwZIAU2Ejnhbxwj0yLEdaWBfSbx+qAj2yhSaRHMEUx
CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRl
cm5ldCBXaWRnaXRzIFB0eSBMdGSCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B
AQQFAAOCAQEAoYBkFbBwSO+Vn56ilNG+mOl5ryHAwtjCgqdl156N52ysUFq+qar2
WNbmD3ieDm+UrNqX4FcLV/CkZQAXWj3YHLyGbMCekLbpctjbfmCVTD3EQ+a7Rw1s
uQVyrzbLHggzhBuzQrjKflr42MnfNClQAiiM7kOyuo1pwVgWZ4GXIBOfazizG3Yh
If0p+MUKJk7maKgXoiu+NrZIu7jyB4lyqTVGh1fKr1rWrciK5xnC7mxkndGuzcGo
XM/ea0cPl79g8PRHAtgqLoqECP184HC4gR+AVLoonva4Yz3mI6BiRI0lrcjQLWEF
GmLEzRjFsm/tdyMSzH2eM7zp1ibogbSBiA==
-----END CERTIFICATE-----
---------------------------------------------------
| Date: 2003-05-24 12:24:54 |
| Filename: pkey |
| Author: detour@metalshell.com |
| |
| http://www.metalshell.com/ |
---------------------------------------------------
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAuvu9oo0wb0Vu0TJrb4Yhfs0Z/MRRT9vs+a3RJoLltmf8WjUk
2UQ+cC0U+pnJbrNyozlKsI0JVLQHgfefYbKCyw+mlrzwiQzYWiUqGVaNaLaThv4w
a5hbBEa79QaEQr/9yIJL581MdLbT7pThdcu49sQi/tNCT8Y0XatI3FMG0v9ynyuk
iT58hjn0XKZnHr8bGun7m+WtthkVkw9RR3YmBoBTE7LWxyF61CGhHOuOUOZf35+b
CoolhD5ktvVoIZlkm5Fb+Lb0LLFA4ObV9QGlvVbAQWNdRlvyPaKJwuhL2z2clpQW
93Z8iZaJz/XWJiL658VwxGNqRUoxhcXbj4Zl3wIDAQABAoIBAAWTL+pCz2jh5xXx
rOZcV29Sai3xJIN/CSfAmPXO/U5c91cxMnIP6NSrY269WxYj340iTinJarfNzlN/
sI7XJbMsOklQRNOxQFoftYuf2wN+PhPOTF9I4Z3VBhGeKh9bXhO2XtEAfAEW2mbI
pZg/hLpGysxSPC3ouPL6AmgfSZrM2e6Jqgo1OxZnkxsMYG1iLUdyA01P4IwbnIF1
zTEi+cpqBiaX9QR3Q5bkXIhyscmaLCeqvjiAhLZXqy2fRy+VW48T08JWoPjOh/vW
EzFOADYXf3bOEeKw62+iSGvF97J87iiqGn7+aMG3FT4YqZ5luu4D1o++xfPj8om/
Rjte4GECgYEA4Z2GzYmaldfcxV1vfoUQDlSmdpcJ3UM/gMew4fSH22obpM81krih
H84KMzCIBT1dTJWygSwsNbivhTclRseV/TJ2vN2OQOCk4jwgXjuKyqMVEv7UFVp0
2Z3KTI9+AOTplSRUUymka0dwLd0B7rhuqIfPWT6cC7pgpJCWR4JR3gkCgYEA1CpP
mwLhTsDhkjkwsEvIYTJPvKg1ch77Ck3RYQ01tAaJ0IMZfBMuVYAzzbgVrsTuxgMP
tAoHTw9fgk+KU0ksIWR3yxrYnFALN9DJvT4nyYjesF1Y83MAwhVE+REJ77efJV7T
IkB4OZgdljn5caPEZMAGQxLWFRaV6HHvYnGtnqcCgYEA3OcIHiclHKIGn5gkmpRe
bCml82dfWS2G9+iN4C809jimaHAZ3Fa6LBHpGsXh6H904o+P/7nob5EtCho8fVje
GtNWPwYPSqapynlkl99kvZOABuFLdrzivFAqy1uT2/xGWKkBh4u2WPPRepZyVfJv
JsQS2SbcUv9hsL+A5PNMhUECgYEAwoCbhB9K0HjxEq1NXoHLDJgkE28duCaAvHyE
s/V5QzYvR7G4PlATTRz/4NufPR6bS3po/gOnmaodRAiJZjsRsvc4/0D4Tazv69aD
6/K8ZP0OMh8RufW3PzZiifc95b6vroHVC3SRAzPaA+vYK38YP8jutLTjAGg5O+Sf
sd9HbMcCgYEAliEIS+BRsf7Uj6jZj+/n3LIiREbZ0Euhqbfh8ZWnFA6Qs64jMvRs
/XJgfK/4jYvVWyMsnPOBRnTvI83PiC12UV4yJP2SbyJFkynqcmQjU9tXJoxfTg8m
CayJ0aG8qGd2SWmJob8w8WIC+2k7Pt4Otcgfm0KxgJ3jNQ5bwHQ8Udo=
-----END RSA PRIVATE KEY-----