⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sslserversocket.cpp

📁 基本实现了数字证书的制作、SSL安全通讯、加解密操作等功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	SOCKADDR_IN client;
	int iAddrSize=sizeof(client);

	m_pSocket = new CSslServerSocket();//用于连接

	m_pSocket->m_pList=m_pList;
	m_pSocket->m_pObSock=m_pObSock;//公用一个链表
	m_pSocket->m_type=m_type;
	m_pSocket->m_pConnection=m_pConnection;

	if(Accept(*m_pSocket,(SOCKADDR *)&client,&iAddrSize))
	{
		CString str;
		str.Format("客户 %s TCP接入成功,等待握手......",inet_ntoa(client.sin_addr));
		m_pList->AddMsg(str,M_WARING);
		m_pSocket->m_Ssl = SSL_new (m_Ctx); 
		SSL_set_accept_state(m_pSocket->m_Ssl);
		sbio=BIO_new_socket(m_pSocket->m_hSocket,BIO_NOCLOSE);
		SSL_set_bio(m_pSocket->m_Ssl,sbio,sbio);
		
		for(;;)
		{
			if ((err = SSL_accept (m_pSocket->m_Ssl)) <= 0)
			{
				if (BIO_sock_should_retry(err))
				{
					continue;
				}
				int verify_error=SSL_get_verify_result(m_pSocket->m_Ssl);
				if (verify_error != X509_V_OK)//succeeded or no peer certificate was presented
				{
					sprintf(out,"verify error:%s\n",
						X509_verify_cert_error_string(verify_error));
					m_pList->AddMsg(out,M_ERROR);

				}
				else
				{
					m_pList->AddMsg("客户端没有证书,握手结束",M_WARING);
					m_pSocket->Close();
					delete m_pSocket;
					m_pSocket=NULL;
				}
				return ;
			}
			else
			{
				m_pSocket->AsyncSelect(FD_READ|FD_CLOSE);//选择读事件(OnReceive)
				str.Format("握手结束,客户%s接入成功",inet_ntoa(client.sin_addr));
				GetPeerInfo(m_pSocket->m_Ssl,&m_CLIENTINFO);
				m_pList->AddMsg(str,M_WARING);
				m_pObSock->AddTail(m_pSocket);
				break;
			}
		}
		
	}	
	else
	{	
		m_pList->AddMsg("TCP连接失败",M_ERROR);
		m_pSocket->Close();
		delete m_pSocket;
		m_pSocket=NULL;
	}					
	CAsyncSocket::OnAccept(nErrorCode);
}

void CSslServerSocket::OnClose(int nErrorCode) 
{
	// TODO: Add your specialized code here and/or call the base class
	CString clientIp;
	unsigned int port;
	POSITION pos;
	GetPeerName(clientIp,port);//得到用户ip,port
	clientIp+="已经断开连接!";
	clientIp="客户"+clientIp;
	m_pList->AddMsg(clientIp,M_WARING);

	pos=m_pObSock->Find(this);
	if(pos) m_pObSock->RemoveAt(pos);//客户端关闭

	if(m_Ssl!=NULL)
	{
		SSlShouDown();
	}
	delete this;
	CAsyncSocket::OnClose(nErrorCode);
}

int CSslServerSocket::SSlSend(char *buf, int len)
{
	if(m_Ssl==NULL)
		return -1;
	int k=0;//接收数量
	int offect=0;//偏移
	for(;0!=len;)//maximum record size of 16kB for SSLv3/TLSv1
	{
		k = SSL_write(m_Ssl,buf+offect,len);
		if (k <= 0)
		{
			if (BIO_sock_should_retry(k))
			{
				Sleep(100);
				continue;//重试
			}
			return k;//出错
		}
		offect+=k;
		len-=k;
	}
	AsyncSelect(FD_READ|FD_CLOSE);
	return offect;
}

int CSslServerSocket::SSlReceive(char *buf, int len)
{
	int k=0;
	do
	{
		for(;;)
		{
			k = SSL_read(m_Ssl,buf,len);
			if (k <= 0)
			{
				if (BIO_sock_should_retry(k))
				{
					Sleep(100);
					continue;//重试
				}
				return k;//错误退出
			}
			break;//成功
		}
	}while (SSL_pending(m_Ssl));

	return k;
}


void CSslServerSocket::DisplayError(_com_error &e)
{
	CString msgText;
	_bstr_t bstrSource(e.Source());
	_bstr_t bstrDescription(e.Description());
	
	msgText.Format("连接数据库错误\n错误代码 = %08lx\n", e.Error());
	msgText += " Msg: ";
	msgText += e.ErrorMessage();
	msgText += "\n 来源: ";
	msgText += bstrSource;
	msgText += "\n 内容: ";
	msgText += bstrDescription;
	m_pList->AddMsg(msgText,M_ERROR);

}

void CSslServerSocket::OnReceive(int nErrorCode) //与客户端交互
{
	// TODO: Add your specialized code here and/or call the base class
	if(m_type==0)//www
	{
		char buf[1024]={0};
		SSlReceive(buf,1024);
		AsyncSelect(FD_WRITE|FD_CLOSE);
	}
	else//ra
	{
		stuCA CA;//接收用结构
		if(SSlReceive((char *)&CA,sizeof(stuCA))<=0)//对方已经关闭
			return;
		stuRA RA;//用于发送的结构
		
		_variant_t Affected;//影响行数
		_RecordsetPtr m_pRecordset;
		m_pRecordset.CreateInstance(_uuidof(Recordset));
		
		switch(CA.Type)
		{
		case Input://录入证书
			{
				stuCERT sCERT;
				CString strSQL;
				if(SSlReceive((char * )&sCERT,sizeof(sCERT))<0)//接收客户信息
					return;
				char * p=(char *)&sCERT;
				VARIANT varBLOB;
				SAFEARRAY FAR *psa; 
				SAFEARRAYBOUND rgsabound[1];
				SYSTEMTIME tm;
				GetLocalTime(&tm);
				CString time;
				time.Format("%d-%d-%d", tm.wYear,tm.wMonth,tm.wDay);
				
				try
				{
					if (m_pConnection == NULL)
					{
						return;
					}		
					m_pRecordset->Open("CERTLIST",_variant_t((IDispatch*)m_pConnection,true),
						adOpenDynamic,adLockOptimistic,adCmdTable);//打开表
					
					m_pRecordset->AddNew(); ///添加新记录
					rgsabound[0].lLbound = 0;
					rgsabound[0].cElements = sizeof(stuCERT);
					psa = SafeArrayCreate(VT_UI1, 1, rgsabound); ///创建SAFEARRAY对象
					for (long i =0;i<sizeof(stuCERT); i++)
					{
						SafeArrayPutElement (psa, &i, p++); ///保存二进制数据
					}
					// 由于Variant没有SafeArray的构造函数,所以手工设置Variant的数据类型和值。
					varBLOB.vt = VT_ARRAY | VT_UI1;
					varBLOB.parray = psa; 
					m_pRecordset->Fields->GetItem("USERINFO")->AppendChunk(varBLOB); ///加入数据
					SafeArrayDestroy(psa);
					m_pRecordset->Fields->GetItem("INPUTTIME")->PutValue(_variant_t(time));
					_variant_t UserID=m_pRecordset->Fields->GetItem("ID")->Value;//得到id
					m_pRecordset->Update(); //更新
					RA.ID=UserID.lVal;//ID
					RA.Type=Input;//操作类型
					RA.State=TRUE;//操作状态
					SSlSend((char *)&RA,sizeof(RA));
				}
				catch (_com_error &e)
				{
					DisplayError(e);
					RA.Type=Input;//操作类型
					RA.State=FALSE;//操作状态
					SSlSend((char *)&RA,sizeof(RA));
				}
				break;
			}
		case FInputD://待审核
		case FAuditD://待制作
		case FMadeD://有效
		case FRevokeD://无效
			{
				try
				{
					if (m_pConnection == NULL)
					{
						return;
					}				
					m_pRecordset->Open((_bstr_t)CA.SQL,(IDispatch*)m_pConnection,adOpenStatic,//静态游标
						adLockOptimistic,adCmdText); 
					m_Rcount=m_pRecordset->RecordCount;//纪录条数--静态游标有效
					if(!m_pRecordset->adoEOF)//存在纪录
					{
						for(int index=0;!m_pRecordset->adoEOF;m_pRecordset->MoveNext(),index++)//遍历所有记录
						{
							//得到用户ID,个体信息
							_variant_t	varBLOB;
							varBLOB = m_pRecordset->Fields->GetItem("USERINFO")->GetChunk(sizeof(RA.SUBJECT));
							if(varBLOB.vt == (VT_ARRAY | VT_UI1))
							{
								char *pBuf = NULL;
								SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
								memcpy(&RA.SUBJECT,pBuf,sizeof(RA.SUBJECT));//个体信息
								SafeArrayUnaccessData(varBLOB.parray);
							}
							
							_variant_t UserID=m_pRecordset->Fields->GetItem("ID")->Value;
							RA.ID=UserID.lVal;//ID
							
							switch(CA.Type)
							{
							case FInputD://查询代审核
								{
									_bstr_t InputTime=m_pRecordset->Fields->GetItem("INPUTTIME")->Value;
									CString Input=InputTime.copy();
									strcpy(RA.Time,Input);//操作时间
									RA.Type=FInputD;//操作类型
									RA.State=TRUE;//操作状态
									if(index==0)//第一次发送总纪录数
									{
										RA.CertL=m_Rcount;//总纪录数
										RA.KeyL=1;//KeyL=1 -->总纪录数
									}
									if(index==m_Rcount-1)//最后一条纪录(一条纪录时候m_Rcount=1)
									{
										RA.CertL=m_Rcount;//总纪录数
										RA.KeyL=-1;
									}
									if(index!=0&&index!=m_Rcount-1)
									{
										RA.CertL=index;//其余发送纪录数
										RA.KeyL=0;
									}
									break;
									
								}
							case FAuditD://查询代制作
								{
									_bstr_t AuditTime=m_pRecordset->Fields->GetItem("AUDITIME")->Value;
									CString Audit=AuditTime.copy();
									strcpy(RA.Time,Audit);//操作时间
									RA.Type=FAuditD;//操作类型
									RA.State=TRUE;//操作状态
									if(index==0)//第一次发送总纪录数
									{
										RA.CertL=m_Rcount;//总纪录数
										RA.KeyL=1;//KeyL=1 -->总纪录数
									}
									if(index==m_Rcount-1)//最后一条纪录(一条纪录时候m_Rcount=1)
									{
										RA.CertL=m_Rcount;//总纪录数
										RA.KeyL=-1;
									}
									if(index!=0&&index!=m_Rcount-1)
									{
										RA.CertL=index;//其余发送纪录数
										RA.KeyL=0;
									}
									break;
									
								}
							case FMadeD://查询已经制作
								{
									_bstr_t MadeTime=m_pRecordset->Fields->GetItem("MADETIME")->Value;
									CString Made=MadeTime.copy();
									strcpy(RA.Time,Made);//操作时间
									RA.Type=FMadeD;//操作类型
									RA.State=TRUE;//操作状态
									if(index==0)//第一次发送总纪录数
									{
										RA.CertL=m_Rcount;//总纪录数
										RA.KeyL=1;//KeyL=1 -->总纪录数
									}
									if(index==m_Rcount-1)//最后一条纪录(一条纪录时候m_Rcount=1)
									{
										RA.CertL=m_Rcount;//总纪录数
										RA.KeyL=-1;
									}
									if(index!=0&&index!=m_Rcount-1)
									{
										RA.CertL=index;//其余发送纪录数
										RA.KeyL=0;
									}
									break;
									
								}
							case FRevokeD: //查询已经作废
								{
									_bstr_t DelTime=m_pRecordset->Fields->GetItem("REVOKETIME")->Value;
									CString Del=DelTime.copy();
									strcpy(RA.Time,Del);//操作时间
									RA.Type=FRevokeD;//操作类型
									RA.State=TRUE;//操作状态
									if(index==0)//第一次发送总纪录数
									{
										RA.CertL=m_Rcount;//总纪录数
										RA.KeyL=1;//KeyL=1 -->总纪录数
									}
									if(index==m_Rcount-1)//最后一条纪录(一条纪录时候m_Rcount=1)
									{
										RA.CertL=m_Rcount;//总纪录数
										RA.KeyL=-1;
									}
									if(index!=0&&index!=m_Rcount-1)
									{
										RA.CertL=index;//其余发送纪录数
										RA.KeyL=0;
									}
									break;
								}
							default:
								{
									m_pList->AddMsg("未知命令",M_ERROR);
									break;
								}
							}
							if(SSlSend((char *)&RA,sizeof(RA))<=0)//发送
								break;
					}
				}
				else//纪录为0
				{
					switch(CA.Type)
					{
					case FInputD://查询代审核
						{
							RA.Type=FInputD;//操作类型
							RA.State=TRUE;//操作状态
							RA.KeyL=1;
							break;
						}
					case FAuditD://查询代制作
						{
							RA.Type=FAuditD;//操作类型
							RA.State=TRUE;//操作状态
							RA.KeyL=1;
							break;
						}
					case FMadeD://查询已经制作
						{
							RA.Type=FMadeD;//操作类型
							RA.State=TRUE;//操作状态
							RA.KeyL=1;
							break;
						}
					case FRevokeD://查询已经作废
						{
							RA.Type=FRevokeD;//操作类型
							RA.State=TRUE;//操作状态
							RA.KeyL=1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -