MiniSapi.cpp
上传用户:dengkfang
上传日期:2008-12-30
资源大小:5233k
文件大小:11k
源码类别:

CA认证

开发平台:

Visual C++

  1. // MINISAPI.CPP - Implementation file for your Internet Server
  2. //    MiniSapi Extension
  3. #include "stdafx.h"
  4. #include "MiniSapi.h"
  5. #include "..CAca.h"
  6. #include <afxdisp.h>
  7. ///////////////////////////////////////////////////////////////////////
  8. // command-parsing map
  9. BEGIN_PARSE_MAP(CMiniSapiExtension, CHttpServer)
  10. // TODO: insert your ON_PARSE_COMMAND() and 
  11. // ON_PARSE_COMMAND_PARAMS() here to hook up your commands.
  12. // For example:
  13. ON_PARSE_COMMAND(CertReq, CMiniSapiExtension, ITS_PSTR ITS_PSTR ITS_PSTR ITS_PSTR ITS_I2 ITS_I2 ITS_I2)
  14. ON_PARSE_COMMAND_PARAMS("UserInfo KeyUsage EkeyUsage FriendName CertKeyLen CertValidity CertType")
  15. ON_PARSE_COMMAND(Query, CMiniSapiExtension, ITS_PSTR)
  16. ON_PARSE_COMMAND_PARAMS("QueryPwd")
  17. ON_PARSE_COMMAND(Default, CMiniSapiExtension, ITS_EMPTY)
  18. DEFAULT_PARSE_COMMAND(Default, CMiniSapiExtension)
  19. END_PARSE_MAP(CMiniSapiExtension)
  20. ///////////////////////////////////////////////////////////////////////
  21. // The one and only CMiniSapiExtension object
  22. CMiniSapiExtension theExtension;
  23. ///////////////////////////////////////////////////////////////////////
  24. // CMiniSapiExtension implementation
  25. CMiniSapiExtension::CMiniSapiExtension()
  26. {
  27. m_Title = "MiniCA 在线证书发放系统";
  28. }
  29. CMiniSapiExtension::~CMiniSapiExtension()
  30. {
  31. }
  32. /*
  33. ISA(Internet Server Application)也可称为ISAPI DLL,
  34. 其功能和CGI程序的功能直接相对应,使用方法和CGI也类似,
  35. 由客户端在URL中指定其名称而激活。
  36. 例如下面的请求将调用服务器的虚拟可执行目录Scripts下的function.dll
  37. (ISAPI DLL必须放在服务器的虚拟可执行目录下): 
  38. http://www.abc.com/Scripts/function.dll?
  39. ISA和服务器之间的接口主要有两个:
  40. GetExtentionVersion( )和HttpExtentionProc( )。
  41. 任何ISA都必须在其PE文件头的引出表中定义这两个引出函数,
  42. 以供Web服务器在适当的时候调用。 
  43. 1、当服务器刚加载ISA时,它会调用ISA提供的GetExtentionVersion( )
  44. 来获得该ISA所需要的服务器版本,并与自己的版本相比较,以保证版本兼容*/
  45. BOOL CMiniSapiExtension::GetExtensionVersion(HSE_VERSION_INFO* pVer)
  46. {
  47. // Call default implementation for initialization
  48. /*
  49. typedef struct _HSE_VERSION_INFO 
  50. DWORD dwExtensionVersion; //版本号 
  51. CHAR lpszExtensionDesc[HSE_MAX_EXT_DLL_NAME_LEN]; //关于ISA的描述字符串 
  52. } HSE_VERSION_INFO, *LPHSE_VERSION_INFO; 
  53. */
  54. CHttpServer::GetExtensionVersion(pVer);
  55. HMODULE hMiniCA = GetModuleHandle("MiniCA.exe");
  56. CString strMiniPath;
  57. if(hMiniCA)
  58. {
  59. GetModuleFileName(hMiniCA, strMiniPath.GetBuffer(MAX_PATH), MAX_PATH);
  60. strMiniPath.ReleaseBuffer();
  61. int nPos;
  62. nPos = strMiniPath.ReverseFind ('\');
  63. CString strMdbPath = strMiniPath.Left (nPos);
  64. strMdbPath += "\MiniCA.mdb";
  65. CString Msg;
  66. if(!ConnectDB(strMdbPath, Msg))//连接数据库失败
  67. {
  68. // return FALSE;无法显示网页HTTP 500 - 内部服务器错误 
  69. }
  70. }
  71. else //MiniCA外的调用
  72. {
  73. return FALSE;
  74. }
  75. //通过可执行文件路径得到数据库路径
  76. // Load description string
  77. TCHAR sz[HSE_MAX_EXT_DLL_NAME_LEN+1];
  78. ISAPIVERIFY(::LoadString(AfxGetResourceHandle(),
  79. IDS_SERVER, sz, HSE_MAX_EXT_DLL_NAME_LEN));
  80. _tcscpy(pVer->lpszExtensionDesc, sz);
  81. return TRUE;
  82. }
  83. BOOL CMiniSapiExtension::TerminateExtension(DWORD dwFlags)
  84. {
  85. // extension is being terminated
  86. //TODO: Clean up any per-instance resources
  87. return TRUE;
  88. }
  89. ///////////////////////////////////////////////////////////////////////
  90. // CMiniSapiExtension command handlers
  91. void CMiniSapiExtension::Default(CHttpServerContext* pCtxt)
  92. {
  93. StartContent(pCtxt);
  94. SetTitle("默认页面");
  95. WriteTitle(pCtxt);
  96. *pCtxt << _T("欢迎来到数字证书自作-CERTSELFrn<P>");
  97. *pCtxt << _T(" 填写个人信息后,选择需要的证书类型就可以自作您需要的证书了.rn");
  98. EndContent(pCtxt);
  99. }
  100. // Do not edit the following lines, which are needed by ClassWizard.
  101. #if 0
  102. BEGIN_MESSAGE_MAP(CMiniSapiExtension, CHttpServer)
  103. //{{AFX_MSG_MAP(CMiniSapiExtension)
  104. //}}AFX_MSG_MAP
  105. END_MESSAGE_MAP()
  106. #endif // 0
  107. ///////////////////////////////////////////////////////////////////////
  108. // If your extension will not use MFC, you'll need this code to make
  109. // sure the extension objects can find the resource handle for the
  110. // module.  If you convert your extension to not be dependent on MFC,
  111. // remove the comments arounn the following AfxGetResourceHandle()
  112. // and DllMain() functions, as well as the g_hInstance global.
  113. /****
  114. static HINSTANCE g_hInstance;
  115. HINSTANCE AFXISAPI AfxGetResourceHandle()
  116. {
  117. return g_hInstance;
  118. }
  119. BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ulReason,
  120. LPVOID lpReserved)
  121. {
  122. if (ulReason == DLL_PROCESS_ATTACH)
  123. {
  124. g_hInstance = hInst;
  125. }
  126. return TRUE;
  127. }
  128. ****/
  129. void CMiniSapiExtension::Query(CHttpServerContext* pCtxt, LPCSTR sQueryPwd)
  130. {
  131. StartContent(pCtxt);
  132. SetTitle("用户查询");
  133. WriteTitle(pCtxt);
  134. if (!m_pDb.IsOpen())
  135. {
  136. *pCtxt<< "连接数据库错误,服务器发生故障";
  137. return;
  138. }
  139. CADORecordset* pRs = new CADORecordset(&m_pDb);
  140. try
  141. {
  142. CString strSQL;
  143. strSQL.Format("Select CERTSTATE From WEBCERT Where QUERYPWD = '%s'", sQueryPwd);
  144. if(pRs->Open(strSQL, CADORecordset::openQuery))
  145. {
  146. if(!pRs->IsEof())//存在记录
  147. {
  148. int iState = 0;
  149. pRs->GetFieldValue("CERTSTATE", iState);
  150. switch(iState)
  151. {
  152. case 0: //申请未作处理
  153. *pCtxt<< "您的申请还未被处理,请耐心等待";
  154. break;
  155. case 1: //可以下载CSR
  156. *pCtxt<< "<p>您可以下载证书申请,点击<a href="http://down">证书申请</a>下载</p>";
  157. break;
  158. case 2: //证书正在处理中
  159. *pCtxt<< "您的申请正在处理中,请稍后查询";
  160. break;
  161. case 3: //可以下载,公钥,CSR,PFX
  162. *pCtxt<< "<p>您可以下载<a href="http://6">申请</a>,<a href="http://1">
  163. 证书</a>,<a href="http://哦哦">PFX包</a>,点击下载</p>";
  164. break;
  165. case 4: //证书已经作废
  166. *pCtxt<< "很抱歉,您的证书已经作废";
  167. break;
  168. default:
  169. break;
  170. }
  171. }
  172. else//查询密码错误
  173. {
  174. *pCtxt<< "不存在的查询密码,请先申请证书,然后查询.";
  175. }
  176. pRs->Close();
  177. }
  178. }
  179. catch(CADOException & eAdo)
  180. {
  181. CString str = eAdo.GetErrorMessage();
  182. }
  183. delete pRs;
  184. EndContent(pCtxt);
  185. /* int iRAWSize = 0;
  186. CByteArray caImage;
  187. CString cImage(sQueryPwd);
  188. cImage.Remove(''');
  189. HRSRC tSrc = ::FindResource(AfxGetResourceHandle() ,cImage,"BINARY");
  190. if (tSrc == NULL) return;
  191. iRAWSize = ::SizeofResource(AfxGetResourceHandle(),tSrc);
  192. caImage.SetSize(iRAWSize);
  193. HGLOBAL hImage;
  194. hImage = ::LoadResource(AfxGetResourceHandle(),tSrc);
  195. if (hImage == NULL) return;
  196. BYTE* pImage = NULL;
  197. pImage = (BYTE*) ::LockResource(hImage);
  198. if (pImage == NULL) return;
  199. for (int iCount = 0; iCount < iRAWSize; iCount++)
  200. caImage.ElementAt(iCount) = pImage[iCount];
  201. *pCtxt << caImage;*/
  202. }
  203. BOOL CMiniSapiExtension::ConnectDB(CString strMdb, CString & Msg)
  204. {
  205. if(m_pDb.IsOpen())
  206. return TRUE;
  207. CString strConnection;
  208. strConnection.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;Persist Security Info=False;
  209. Jet OLEDB:Database Password=hpxs", strMdb);
  210. try
  211. {
  212. m_pDb.Open(strConnection);
  213. }
  214. catch(CADOException & eAdo)
  215. {
  216. CString str = eAdo.GetErrorMessage();
  217. return FALSE;
  218. }
  219. return TRUE;
  220. }
  221. //USERINFO,KEYLEN,DAY,FRINEDNAME,CERTTYPE,KEYUSAGE,KEYEUSAGE
  222. BOOL CMiniSapiExtension::InsertDB(const char * lpszUserInfo, const char * lpszKeyUsage,
  223.   const char * lpszKeyEusage, const char * lpszFriendName,
  224.   const int iKeyLen, const int iCertValidity,
  225.   const short iCertType, CString & strQueryPwd, CString & strMsg)
  226. {
  227. //产生查询密码,查询密码为一性保证 CoCreateGuid 或用时间time_t+ID(后者可以被用户猜到,所以选择前者)
  228. if (!m_pDb.IsOpen())
  229. {
  230. strMsg = "连接数据库错误";
  231. return FALSE;
  232. }
  233. CADORecordset* pRs = new CADORecordset(&m_pDb);
  234. try
  235. {
  236. if(pRs->Open("WEBCERT", CADORecordset::openTable))
  237. {
  238. pRs->AddNew();
  239. GUID  Guid;
  240. CoCreateGuid(&Guid);
  241. strQueryPwd.Format("%u%d%d%d",  Guid.Data1, Guid.Data2, Guid.Data3, Guid.Data4);
  242. CString strUserInfo(lpszUserInfo);
  243. CString strFriendName(lpszFriendName);
  244. CString strKeyUsage(lpszKeyUsage);
  245. CString strEkeyUsage(lpszKeyEusage);
  246. pRs->SetFieldValue("QUERYPWD", strQueryPwd);
  247. pRs->SetFieldValue("USERINFO", strUserInfo);
  248. pRs->SetFieldValue("KEYLEN", iKeyLen);
  249. pRs->SetFieldValue("DAY", iCertValidity);
  250. pRs->SetFieldValue("FRINEDNAME", strFriendName);
  251. pRs->SetFieldValue("CERTTYPE", iCertType);
  252. pRs->SetFieldValue("KEYUSAGE", strKeyUsage);
  253. pRs->SetFieldValue("KEYEUSAGE", strEkeyUsage);
  254. COleDateTime time = COleDateTime::GetCurrentTime();
  255. pRs->SetFieldValue("INPUTTIME", time);
  256. pRs->Update();
  257. pRs->Close();
  258. }
  259. }
  260. catch(CADOException & eAdo)
  261. {
  262. CString str = eAdo.GetErrorMessage();
  263. }
  264. delete pRs;
  265. return TRUE;
  266. }
  267. //功能:提供给用户申请证书的功能
  268. void CMiniSapiExtension::CertReq(CHttpServerContext* pCtxt, LPTSTR pszUserInfo, LPTSTR pszKeyUsage,
  269.  LPTSTR pszEkeyUsage, LPTSTR pszFriendName, short iCertKeyLen, short iCertValidity,
  270.  short iCertType)
  271. {
  272. //首先进行输入的有效性
  273. //出错则跳转到错误页面
  274. //添加用户信息到数据库中
  275. CString  strQueryPwd,
  276.  strMsg;
  277. BOOL bSucceed = InsertDB(pszUserInfo, pszKeyUsage, pszEkeyUsage, pszFriendName, iCertKeyLen, iCertValidity,
  278.   iCertType, strQueryPwd, strMsg);
  279. StartContent(pCtxt);
  280. WriteTitle(pCtxt);
  281. if(bSucceed)
  282. {
  283. *pCtxt << _T("恭喜证书申请已经成功提交,请牢记下面的查询密码,它是您获取证书的钥匙哟rn");
  284. *pCtxt << _T(strQueryPwd);
  285. }
  286. else
  287. *pCtxt << _T(strMsg);
  288. EndContent(pCtxt);
  289. return;
  290. {
  291. // AddHeader(pCtxt, _T("Content-Type: application/OCTET-STREAMrn"));
  292. // AddHeader(pCtxt, _T("Content-Disposition: attachment ; filename = 1.pfxrn"));
  293. // CString strLength;
  294. // strLength.Format("Content-length: %ldrn", p12l);
  295. // AddHeader(pCtxt, strLength);
  296. // CByteArray caCert;
  297. // caCert.SetSize(p12l);
  298. //
  299. // for (int iCount = 0; iCount < p12l; iCount++)
  300. // caCert.ElementAt(iCount) = p12[iCount];
  301. // * pCtxt << caCert;
  302. // pCtxt->WriteClient((BYTE *)p12, (LPDWORD)&p12l);
  303. /* HANDLE m_hPhysicsFile = CreateFile( "c:\1.pfx", GENERIC_READ|GENERIC_WRITE, 0, 
  304.                 NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED, NULL );
  305. if(!pCtxt->TransmitFile(m_hPhysicsFile, HSE_REQ_TRANSMIT_FILE))
  306. {
  307. DWORD dError = GetLastError();
  308. CString str;
  309. str.Format("%d", dError);
  310. * pCtxt << str;
  311. }*/
  312. }
  313. // EndContent(pCtxt);
  314. }
  315. /*
  316. ISA的真正入口是HttpExtentionProc( ),
  317. 它相当于普通C程序的main( )函数,
  318. 在这个函数中根据不同的客户请求作不同的处理。
  319. 服务器和HttpExtentionProc( )之间是通过扩展控制块
  320. (Extention Control Block)来进行通信的,
  321. 即ECB中存放入口参数和出口参数,
  322. 包括服务器提供的几个回调函数的入口地址*/
  323. LPCTSTR CMiniSapiExtension::GetTitle() const
  324. {
  325. // TODO: Add your specialized code here and/or call the base class
  326. return m_Title;
  327. }