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

📄 minisapi.cpp

📁 MiniCA V2.0版本源码。《小型CA系统V2.1含源码》发表以来
💻 CPP
字号:
// MINISAPI.CPP - Implementation file for your Internet Server
//    MiniSapi Extension

#include "stdafx.h"
#include "MiniSapi.h"
#include "..\CA\ca.h"
#include <afxdisp.h>

///////////////////////////////////////////////////////////////////////
// command-parsing map

BEGIN_PARSE_MAP(CMiniSapiExtension, CHttpServer)
	// TODO: insert your ON_PARSE_COMMAND() and 
	// ON_PARSE_COMMAND_PARAMS() here to hook up your commands.
	// For example:
	ON_PARSE_COMMAND(CertReq, CMiniSapiExtension, ITS_PSTR ITS_PSTR ITS_PSTR ITS_PSTR ITS_I2 ITS_I2 ITS_I2)
	ON_PARSE_COMMAND_PARAMS("UserInfo KeyUsage EkeyUsage FriendName CertKeyLen CertValidity CertType")

	ON_PARSE_COMMAND(Query, CMiniSapiExtension, ITS_PSTR)
	ON_PARSE_COMMAND_PARAMS("QueryPwd")

	ON_PARSE_COMMAND(Default, CMiniSapiExtension, ITS_EMPTY)
	DEFAULT_PARSE_COMMAND(Default, CMiniSapiExtension)
END_PARSE_MAP(CMiniSapiExtension)


///////////////////////////////////////////////////////////////////////
// The one and only CMiniSapiExtension object

CMiniSapiExtension theExtension;


///////////////////////////////////////////////////////////////////////
// CMiniSapiExtension implementation

CMiniSapiExtension::CMiniSapiExtension()
{
	m_Title = "MiniCA 在线证书发放系统";
}

CMiniSapiExtension::~CMiniSapiExtension()
{
}

/*
ISA(Internet Server Application)也可称为ISAPI DLL,
其功能和CGI程序的功能直接相对应,使用方法和CGI也类似,
由客户端在URL中指定其名称而激活。
例如下面的请求将调用服务器的虚拟可执行目录Scripts下的function.dll
(ISAPI DLL必须放在服务器的虚拟可执行目录下): 
http://www.abc.com/Scripts/function.dll?

ISA和服务器之间的接口主要有两个:
GetExtentionVersion( )和HttpExtentionProc( )。
任何ISA都必须在其PE文件头的引出表中定义这两个引出函数,
以供Web服务器在适当的时候调用。 

1、当服务器刚加载ISA时,它会调用ISA提供的GetExtentionVersion( )
来获得该ISA所需要的服务器版本,并与自己的版本相比较,以保证版本兼容*/

BOOL CMiniSapiExtension::GetExtensionVersion(HSE_VERSION_INFO* pVer)
{
	// Call default implementation for initialization
/*
	typedef struct _HSE_VERSION_INFO 
	{ 
		DWORD dwExtensionVersion; //版本号 
		CHAR lpszExtensionDesc[HSE_MAX_EXT_DLL_NAME_LEN]; //关于ISA的描述字符串 
	} HSE_VERSION_INFO, *LPHSE_VERSION_INFO; 
*/
	CHttpServer::GetExtensionVersion(pVer);

	HMODULE hMiniCA = GetModuleHandle("MiniCA.exe");
	CString strMiniPath;
	if(hMiniCA)
	{
		GetModuleFileName(hMiniCA, strMiniPath.GetBuffer(MAX_PATH), MAX_PATH);
		strMiniPath.ReleaseBuffer();
		int nPos;
		nPos = strMiniPath.ReverseFind ('\\');
		CString strMdbPath = strMiniPath.Left (nPos);
		strMdbPath += "\\MiniCA.mdb";

		CString Msg;
		if(!ConnectDB(strMdbPath, Msg))//连接数据库失败
		{
			//	return FALSE;无法显示网页HTTP 500 - 内部服务器错误 
		}
	}
	else	//MiniCA外的调用
	{
		return FALSE;
	}

	//通过可执行文件路径得到数据库路径

	// Load description string
	TCHAR sz[HSE_MAX_EXT_DLL_NAME_LEN+1];
	ISAPIVERIFY(::LoadString(AfxGetResourceHandle(),
			IDS_SERVER, sz, HSE_MAX_EXT_DLL_NAME_LEN));
	_tcscpy(pVer->lpszExtensionDesc, sz);
	return TRUE;
}

BOOL CMiniSapiExtension::TerminateExtension(DWORD dwFlags)
{
	// extension is being terminated
	//TODO: Clean up any per-instance resources
	return TRUE;
}

///////////////////////////////////////////////////////////////////////
// CMiniSapiExtension command handlers

void CMiniSapiExtension::Default(CHttpServerContext* pCtxt)
{
	StartContent(pCtxt);
	SetTitle("默认页面");
	WriteTitle(pCtxt);
	*pCtxt << _T("欢迎来到数字证书自作-CERTSELF\r\n<P>");
	*pCtxt << _T(" 填写个人信息后,选择需要的证书类型就可以自作您需要的证书了.\r\n");
	EndContent(pCtxt);
}

// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CMiniSapiExtension, CHttpServer)
	//{{AFX_MSG_MAP(CMiniSapiExtension)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0



///////////////////////////////////////////////////////////////////////
// If your extension will not use MFC, you'll need this code to make
// sure the extension objects can find the resource handle for the
// module.  If you convert your extension to not be dependent on MFC,
// remove the comments arounn the following AfxGetResourceHandle()
// and DllMain() functions, as well as the g_hInstance global.

/****

static HINSTANCE g_hInstance;

HINSTANCE AFXISAPI AfxGetResourceHandle()
{
	return g_hInstance;
}

BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ulReason,
					LPVOID lpReserved)
{
	if (ulReason == DLL_PROCESS_ATTACH)
	{
		g_hInstance = hInst;
	}

	return TRUE;
}

****/
void CMiniSapiExtension::Query(CHttpServerContext* pCtxt, LPCSTR sQueryPwd)
{
	StartContent(pCtxt);
	SetTitle("用户查询");
	WriteTitle(pCtxt);

	if (!m_pDb.IsOpen())
	{
		*pCtxt<< "连接数据库错误,服务器发生故障";
		return;
	}
	CADORecordset* pRs = new CADORecordset(&m_pDb);
	try
	{
		CString strSQL;
		strSQL.Format("Select CERTSTATE From WEBCERT Where QUERYPWD = '%s'", sQueryPwd);
		if(pRs->Open(strSQL, CADORecordset::openQuery))
		{
			if(!pRs->IsEof())//存在记录
			{
				int iState = 0;
				pRs->GetFieldValue("CERTSTATE", iState);
				switch(iState)
				{
				case 0:		//申请未作处理
					*pCtxt<< "您的申请还未被处理,请耐心等待";
					break;
				case 1:		//可以下载CSR
					*pCtxt<< "<p>您可以下载证书申请,点击<a href=\"http://down\">证书申请</a>下载</p>";
					break;
				case 2:		//证书正在处理中
					*pCtxt<< "您的申请正在处理中,请稍后查询";
					break;
				case 3:		//可以下载,公钥,CSR,PFX
					*pCtxt<< "<p>您可以下载<a href=\"http://6\">申请</a>,<a href=\"http://1\">\
						证书</a>,<a href=\"http://哦哦\">PFX包</a>,点击下载</p>";
					break;
				case 4:		//证书已经作废
					*pCtxt<< "很抱歉,您的证书已经作废";
					break;
				default:
					break;
				}
			}
			else//查询密码错误
			{
				*pCtxt<< "不存在的查询密码,请先申请证书,然后查询.";
			}
			pRs->Close();
		}
	}
	catch(CADOException & eAdo)
	{
		CString str = eAdo.GetErrorMessage();
	}
	delete pRs;


	EndContent(pCtxt);


/*	int iRAWSize = 0;
	CByteArray caImage;
	CString cImage(sQueryPwd);
	cImage.Remove('\'');

	HRSRC tSrc = ::FindResource(AfxGetResourceHandle() ,cImage,"BINARY");
	if (tSrc == NULL) return;

	iRAWSize = ::SizeofResource(AfxGetResourceHandle(),tSrc);
	caImage.SetSize(iRAWSize);

	HGLOBAL hImage;
	hImage = ::LoadResource(AfxGetResourceHandle(),tSrc);
	if (hImage == NULL) return;

	BYTE* pImage = NULL;
	pImage = (BYTE*) ::LockResource(hImage);
	if (pImage == NULL) return;

	for (int iCount = 0; iCount < iRAWSize; iCount++)
		caImage.ElementAt(iCount) = pImage[iCount];

	*pCtxt << caImage;*/
}

BOOL CMiniSapiExtension::ConnectDB(CString strMdb, CString & Msg)
{
	if(m_pDb.IsOpen())
		return TRUE;

	CString strConnection;
	strConnection.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;Persist Security Info=False;\
		Jet OLEDB:Database Password=hpxs", strMdb);

	try
	{
		m_pDb.Open(strConnection);
	}
	catch(CADOException & eAdo)
	{
		CString str = eAdo.GetErrorMessage();
		return FALSE;
	}
	return TRUE;
}
//USERINFO,KEYLEN,DAY,FRINEDNAME,CERTTYPE,KEYUSAGE,KEYEUSAGE
BOOL CMiniSapiExtension::InsertDB(const char * lpszUserInfo, const char * lpszKeyUsage,
								  const char * lpszKeyEusage, const char * lpszFriendName,
								  const int iKeyLen, const int iCertValidity,
								  const short iCertType, CString & strQueryPwd, CString & strMsg)
{
	//产生查询密码,查询密码为一性保证 CoCreateGuid 或用时间time_t+ID(后者可以被用户猜到,所以选择前者)
	if (!m_pDb.IsOpen())
	{
		strMsg = "连接数据库错误";
		return FALSE;
	}
	CADORecordset* pRs = new CADORecordset(&m_pDb);
	try
	{
		if(pRs->Open("WEBCERT", CADORecordset::openTable))
		{
			pRs->AddNew();
			
			GUID  Guid;
			CoCreateGuid(&Guid);
			strQueryPwd.Format("%u%d%d%d",  Guid.Data1, Guid.Data2, Guid.Data3, Guid.Data4);

			CString strUserInfo(lpszUserInfo);
			CString strFriendName(lpszFriendName);
			CString strKeyUsage(lpszKeyUsage);
			CString strEkeyUsage(lpszKeyEusage);

			pRs->SetFieldValue("QUERYPWD", strQueryPwd);
			pRs->SetFieldValue("USERINFO", strUserInfo);
			pRs->SetFieldValue("KEYLEN", iKeyLen);
			pRs->SetFieldValue("DAY", iCertValidity);
			pRs->SetFieldValue("FRINEDNAME", strFriendName);
			pRs->SetFieldValue("CERTTYPE", iCertType);
			pRs->SetFieldValue("KEYUSAGE", strKeyUsage);
			pRs->SetFieldValue("KEYEUSAGE", strEkeyUsage);
			
			COleDateTime time = COleDateTime::GetCurrentTime();
			pRs->SetFieldValue("INPUTTIME", time);

			pRs->Update();
			pRs->Close();
			
		}
	}
	catch(CADOException & eAdo)
	{
		CString str = eAdo.GetErrorMessage();
	}
	delete pRs;
	return TRUE;
}

//功能:提供给用户申请证书的功能
void CMiniSapiExtension::CertReq(CHttpServerContext* pCtxt, LPTSTR pszUserInfo, LPTSTR pszKeyUsage,
								 LPTSTR pszEkeyUsage, LPTSTR pszFriendName, short iCertKeyLen, short iCertValidity,
								 short iCertType)
{
	//首先进行输入的有效性

	//出错则跳转到错误页面


	//添加用户信息到数据库中

	CString  strQueryPwd,
			 strMsg;

	BOOL bSucceed = InsertDB(pszUserInfo, pszKeyUsage, pszEkeyUsage, pszFriendName, iCertKeyLen, iCertValidity,
								  iCertType, strQueryPwd, strMsg);
	StartContent(pCtxt);
	WriteTitle(pCtxt);
	if(bSucceed)
	{
		*pCtxt << _T("恭喜证书申请已经成功提交,请牢记下面的查询密码,它是您获取证书的钥匙哟\r\n");
		*pCtxt << _T(strQueryPwd);
	}
	else
		*pCtxt << _T(strMsg);

	EndContent(pCtxt);
	return;

	{
	
	//	AddHeader(pCtxt, _T("Content-Type: application/OCTET-STREAM\r\n"));
	//	AddHeader(pCtxt, _T("Content-Disposition: attachment ; filename = 1.pfx\r\n"));
		
	//	CString strLength;
	//	strLength.Format("Content-length: %ld\r\n", p12l);
	//	AddHeader(pCtxt, strLength);

	//	CByteArray caCert;
	//	caCert.SetSize(p12l);
	//	
	//	for (int iCount = 0; iCount < p12l; iCount++)
	//		caCert.ElementAt(iCount) = p12[iCount];


//		* pCtxt << caCert;

//		pCtxt->WriteClient((BYTE *)p12, (LPDWORD)&p12l);
/*		HANDLE m_hPhysicsFile = CreateFile( "c:\\1.pfx", GENERIC_READ|GENERIC_WRITE, 0, 
                NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED, NULL );
		if(!pCtxt->TransmitFile(m_hPhysicsFile, HSE_REQ_TRANSMIT_FILE))
		{
			DWORD dError = GetLastError();
			CString str;
			str.Format("%d", dError);
			* pCtxt << str;
		}*/
	}

//	EndContent(pCtxt);
	
}


/*
ISA的真正入口是HttpExtentionProc( ),
它相当于普通C程序的main( )函数,
在这个函数中根据不同的客户请求作不同的处理。
服务器和HttpExtentionProc( )之间是通过扩展控制块
(Extention Control Block)来进行通信的,
即ECB中存放入口参数和出口参数,
包括服务器提供的几个回调函数的入口地址*/


LPCTSTR CMiniSapiExtension::GetTitle() const
{
	// TODO: Add your specialized code here and/or call the base class
	return m_Title;
}

⌨️ 快捷键说明

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