// SSLServer.cpp: implementation of the CSSLServer class.
//
//////////////////////////////////////////////////////////////////////
#include "SSLServer.h"
#include <fstream>
using namespace std;
#define BUFSIZZ 1024
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
char CSSLServer::pass[1024] = {0};
// 格林威治时间的星期转换
char *week[] = {
"Sun,",
"Mon,",
"Tue,",
"Wed,",
"Thu,",
"Fri,",
"Sat,",
};
// 格林威治时间的月份转换
char *month[] =
{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
};
CSSLServer::CSSLServer()
{
m_bRunning = false;
m_socket = NULL;
m_TmpSocket = NULL;
m_nPort = 8000;
m_keyfile = "";
m_dhfile = "";
m_ca_list = "";
m_ctx = NULL;
m_ListenThread = NULL;
m_RootDir = "F:\\code\\VC6.0\\SSL\\Web Server Root Directory";
CreateTypeMap();
}
CSSLServer::~CSSLServer()
{
if (m_socket != NULL)
{
closesocket(m_socket);
m_socket = NULL;
}
if (m_ctx != NULL)
{
SSL_CTX_free(m_ctx);
m_ctx = NULL;
}
}
DWORD WINAPI CSSLServer::ListenThread(LPVOID lpParameter)
{
CSSLServer *pInfo = (CSSLServer*)lpParameter;
SOCKET SocketClient;
SOCKADDR_IN SockAddr;
int nLen = sizeof(SOCKADDR_IN);
for (;;)
{
SocketClient = accept(pInfo->m_socket, (LPSOCKADDR)&SockAddr, &nLen);
if (INVALID_SOCKET == SocketClient)
{
cout << "ERROR: accepted a invalid socket" <<endl;
break;
}
//print the Client connect information
cout << inet_ntoa(SockAddr.sin_addr) << " connected Socket=" << (int)SocketClient << endl;
pInfo->m_TmpSocket = SocketClient;
HANDLE ThreadHandle;
ThreadHandle = ::CreateThread(NULL, 0, ClientThread, (LPVOID)pInfo, 0, NULL);
::CloseHandle(ThreadHandle);
}
return 0;
}
DWORD WINAPI CSSLServer::ClientThread(LPVOID lpParameter)
{
SSL *ssl;
BIO *sbio;
CSSLServer *pClientInfo = (CSSLServer*)lpParameter;
SOCKET sock = pClientInfo->m_TmpSocket;
sbio = BIO_new_socket(sock, BIO_NOCLOSE);
ssl = SSL_new(pClientInfo->m_ctx);
SSL_set_bio(ssl, sbio, sbio);
if (SSL_accept(ssl) <= 0)
{
cout << "SSL accept error" << endl;
}
else
{
pClientInfo->http_serve(ssl,sock);
}
cout << "Socket=" << (int)sock << " exit the server" << endl;
return 0;
}
int CSSLServer::http_serve(SSL *ssl, SOCKET s)
{
char buf[BUFSIZZ] = {0};
int r,len;
BIO *io,*ssl_bio;
ULONG errocode = 0;
io=BIO_new(BIO_f_buffer());
ssl_bio=BIO_new(BIO_f_ssl());
BIO_set_ssl(ssl_bio,ssl,BIO_CLOSE);
BIO_push(io,ssl_bio);
while(1)
{
r=BIO_gets(io,buf,BUFSIZZ-1);
int nR = SSL_get_error(ssl,r);
switch(nR)
{
case SSL_ERROR_NONE:
len=r;
break;
default:
cout << "SSL read problem" << endl;
errocode = ERR_peek_last_error();
ERR_error_string(errocode, buf);
cout << buf <<endl;
break;
}
if (SSL_ERROR_NONE != nR)
{
break;
}
/* Look for the blank line that signals
the end of the HTTP headers */
if (strcmp(buf, "\r\n") == 0
|| strcmp(buf, "\n") == 0)
{
break;
}
char szSeps[] = " \n";
char *cpToken;
// 防止非法请求
if (strstr((const char *)buf, "..") != NULL)
{
cout << "requested illegally" << endl;
break;
}
// 判断请求的命令
cpToken = strtok((char *)buf, szSeps); // 缓存中字符串分解为一组标记串。
if (!_stricmp(cpToken, "GET")) // GET命令
{
//发送头部
string strFile = m_RootDir + "\\index.html";
SendHead(io, (char*)strFile.c_str());
//发送文件内容
ifstream ifile(strFile.c_str(), ios_base::in);
char filebuff[1024] = {0};
while (!ifile.eof())
{
ifile.read(filebuff, 1023);
if((r=BIO_puts(io,filebuff))<=0)
{
cout << "Write error" << endl;
}
}
}
else if (!_stricmp(cpToken, "HEAD")) // HEAD命令
{
string strFile = m_RootDir + "\\index.html";
SendHead(io, (char*)strFile.c_str());
printf("Write error\n");
}
else if (cpToken == NULL)
{
if((r=BIO_puts(io,"bad request\r\n\r\n"))<=0)
printf("Write error\n");
printf("bad request\n");
}
else
{
if((r=BIO_puts(io,"Sorry, this requirement is untreated\r\n\r\n"))<=0)
printf("Write error\n");
printf("Sorry, this requirement is untreated\n");
}
}
if((r=BIO_flush(io))<0)
printf("Error flushing BIO\n");
r=SSL_shutdown(ssl);
if(!r)
{
/* If we called SSL_shutdown() first then
we always get return value of '0'. In
this case, try again, but first send a
TCP FIN to trigger the other side's
close_notify*/
shutdown(s,1);
r=SSL_shutdown(ssl);
}
switch(r)
{
case 1:
break; /* Success */
case 0:
case -1:
default:
printf("Shutdown failed");
break;
}
SSL_free(ssl);
closesocket(s);
return(0);
}
int CSSLServer::password_cb(char *buf,int num, int rwflag,void *userdata)
{
if( num < (int)(strlen(pass)+1) )
return(0);
strcpy(buf,pass);
return(strlen(pass));
}
void CSSLServer::load_dh_params(SSL_CTX *ctx, char *file)
{
BIO *bio = NULL;
DH *ret = NULL;
if ( (bio = BIO_new_file(file, "r")) == NULL )
{
printf("WARNING:Couldn't open DH file\n");
}
ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
BIO_free(bio);
if ( SSL_CTX_set_tmp_dh(ctx, ret) < 0)
{
printf("WARNING:Couldn't set DH parameters\n");
}
}
SOCKET CSSLServer::tcp_listen()
{
SOCKET sock;
struct sockaddr_in sin;
int val=1;
if((sock=socket(AF_INET,SOCK_STREAM,0))<0)
printf("Couldn't make socket");
memset(&sin,0,sizeof(sin));
sin.sin_addr.s_addr=INADDR_ANY;
sin.sin_family=AF_INET;
sin.sin_port=htons(m_nPort);
// setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&val,sizeof(val));
if(bind(sock,(struct sockaddr *)&sin,sizeof(sin))<0)
printf("Couldn't bind");
listen(sock,5);
return(sock);
}
SSL_CTX *CSSLServer::initialize_ctx(char *crtfile, char *keyfile, char *password)
{
SSL_METHOD *meth;
SSL_CTX *ctx;
/* Global system initialization*/
SSL_library_init();
SSL_load_error_strings();
/* Create our context*/
//meth=SSLv23_server_method();
meth=SSLv23_method();
ctx=SSL_CTX_new(meth);
/* Load our keys and certificates*/
if(!(SSL_CTX_use_certificate_chain_file(ctx, crtfile)))
{
printf("Can't read certificate file\n");
}
SSL_CTX_set_default_passwd_cb(ctx, password_cb);
if(!(SSL_CTX_use_PrivateKey_file(ctx, keyfile,SSL_FILETYPE_PEM)))
{
printf("Can't read key file\n");
}
/* Load the CAs we trust*/
if(!(SSL_CTX_load_verify_locations(ctx, m_ca_list.c_str(),0)))
{
printf("Can't read CA list\n");
}
#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
SSL_CTX_set_verify_depth(ctx,1);
#endif
return ctx;
}
bool CSSLServer::Initialize(int nPort, char *crtfile, char *keyfile, char *password, char *dhfile, char *ca_list)
{
m_nPort = nPort;
m_keyfile = keyfile;
m_dhfile = dhfile;
m_ca_list = ca_list;
strcpy(pass, password);
if (!InitSocket())
{
cout << "Failed to initialize the socket environment!" <<endl;
return false;
}
m_socket = tcp_listen();
m_ctx = initialize_ctx(crtfile, keyfile, password);
load_dh_params(m_ctx, dhfile);
return true;
}
bool CSSLServer::InitSocket()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
/*
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
OpenSSL.rar (34个子文件)
SSLClient
root.pem 802B
client.pem 2KB
tmp.html 13KB
SSLClient.cpp 6KB
SSLClient.dsw 541B
SSLClient.plg 1KB
server.pem 2KB
dh1024.pem 245B
SSLClient.dsp 4KB
SSLClient.opt 53KB
SSLClient.ncb 49KB
SSL
root.pem 802B
SSL.dsw 529B
SSLServer.cpp 14KB
ca.crt 1KB
SSL.plg 20KB
SSL.CPP 2KB
Web Server Root Directory
index.files
winpcap.css 2KB
cace_logo.gif 5KB
New.gif 435B
airpcap.gif 4KB
curvedown.gif 905B
curve.gif 904B
index.html 12KB
server.key 963B
SSL.opt 54KB
server.pem 2KB
dh1024.pem 245B
SSL.ncb 57KB
server.crt 3KB
ca.key 963B
SSLServer.h 2KB
SSL.dsp 4KB
server.csr 688B
共 34 条
- 1
zqlong_sunday
- 粉丝: 12
- 资源: 11
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
- 4
- 5
- 6
前往页