Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

587 lines
14 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: SIPObjSS.cpp
  8. //
  9. // Contents: Microsoft SIP Provider - Structured Storage
  10. //
  11. // History: 07-Aug-1997 pberkman created
  12. //
  13. //--------------------------------------------------------------------------
  14. #include "global.hxx"
  15. #include "sipobjss.hxx"
  16. #include <objidl.h>
  17. #include <objbase.h>
  18. #define SIG_AUTHOR 0
  19. #define SIG_NOTARY 1
  20. #define SIG_MAX 1
  21. typedef struct StreamIds_
  22. {
  23. DWORD dwSigIndex;
  24. WCHAR *pwszName;
  25. } StreamIds;
  26. static StreamIds Ids[] =
  27. {
  28. SIG_AUTHOR, L"\001MSDigSig(Author)",
  29. SIG_NOTARY, L"\001MSDigSig(Notary)",
  30. 0xffffffff, NULL
  31. };
  32. ////////////////////////////////////////////////////////////////////////////
  33. //
  34. // construct/destruct:
  35. //
  36. SIPObjectSS_::SIPObjectSS_(DWORD id) : SIPObject_(id)
  37. {
  38. GUID gSS = CRYPT_SUBJTYPE_SS_IMAGE;
  39. memset(&SpcSigInfo,0x00,sizeof(SPC_SIGINFO));
  40. SpcSigInfo.dwSipVersion = MSSIP_CURRENT_VERSION;
  41. memcpy(&SpcSigInfo.gSIPGuid, &gSS, sizeof(GUID));
  42. pTopStg = NULL;
  43. this->fUseFileMap = FALSE;
  44. }
  45. SIPObjectSS_::~SIPObjectSS_(void)
  46. {
  47. if (pTopStg)
  48. {
  49. pTopStg->Commit(STGC_DEFAULT);
  50. pTopStg->Release();
  51. }
  52. }
  53. ////////////////////////////////////////////////////////////////////////////
  54. //
  55. // public:
  56. //
  57. BOOL SIPObjectSS_::RemoveSignedDataMsg(SIP_SUBJECTINFO *pSI,DWORD dwIdx)
  58. {
  59. if (dwIdx > SIG_MAX)
  60. {
  61. SetLastError((DWORD)TRUST_E_NOSIGNATURE);
  62. return(FALSE);
  63. }
  64. if (this->FileHandleFromSubject(pSI, GENERIC_READ | GENERIC_WRITE))
  65. {
  66. if (pTopStg->DestroyElement(Ids[dwIdx].pwszName) != S_OK)
  67. {
  68. SetLastError((DWORD)TRUST_E_NOSIGNATURE);
  69. return(FALSE);
  70. }
  71. return(TRUE);
  72. }
  73. return(FALSE);
  74. }
  75. ////////////////////////////////////////////////////////////////////////////
  76. //
  77. // protected:
  78. //
  79. BOOL SIPObjectSS_::GetMessageFromFile(SIP_SUBJECTINFO *pSI,
  80. WIN_CERTIFICATE *pWinCert,
  81. DWORD dwIndex,DWORD *pcbCert)
  82. {
  83. if (!(pTopStg))
  84. {
  85. return(FALSE);
  86. }
  87. if (dwIndex > SIG_MAX)
  88. {
  89. SetLastError((DWORD)TRUST_E_NOSIGNATURE);
  90. return(FALSE);
  91. }
  92. STATSTG sStatStg;
  93. IStream *pStream;
  94. DWORD cbCert;
  95. pStream = NULL;
  96. if ((pTopStg->OpenStream(Ids[dwIndex].pwszName, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
  97. 0, &pStream) != S_OK) ||
  98. !(pStream))
  99. {
  100. SetLastError(TRUST_E_NOSIGNATURE);
  101. return(FALSE);
  102. }
  103. if (pStream->Stat(&sStatStg, STATFLAG_NONAME) != S_OK)
  104. {
  105. pStream->Release();
  106. SetLastError(ERROR_BAD_FORMAT);
  107. return(FALSE);
  108. }
  109. cbCert = sStatStg.cbSize.LowPart;
  110. if (cbCert == 0)
  111. {
  112. pStream->Release();
  113. SetLastError(TRUST_E_NOSIGNATURE);
  114. return(FALSE);
  115. }
  116. cbCert += WVT_OFFSETOF(WIN_CERTIFICATE, bCertificate);
  117. if (*pcbCert < cbCert)
  118. {
  119. pStream->Release();
  120. *pcbCert = cbCert;
  121. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  122. return(FALSE);
  123. }
  124. if (pWinCert)
  125. {
  126. DWORD cbRead;
  127. pWinCert->dwLength = cbCert;
  128. pWinCert->wRevision = WIN_CERT_REVISION_2_0;
  129. pWinCert->wCertificateType = WIN_CERT_TYPE_PKCS_SIGNED_DATA;
  130. cbRead = 0;
  131. cbCert -= WVT_OFFSETOF(WIN_CERTIFICATE, bCertificate);
  132. if ((pStream->Read(pWinCert->bCertificate, cbCert, &cbRead) != S_OK) ||
  133. (cbRead != cbCert))
  134. {
  135. SetLastError(ERROR_BAD_FORMAT);
  136. pStream->Release();
  137. return(FALSE);
  138. }
  139. }
  140. pStream->Release();
  141. return(TRUE);
  142. }
  143. BOOL SIPObjectSS_::PutMessageInFile(SIP_SUBJECTINFO *pSI,
  144. WIN_CERTIFICATE *pWinCert,DWORD *pdwIndex)
  145. {
  146. if ((pWinCert->dwLength <= OFFSETOF(WIN_CERTIFICATE,bCertificate)) ||
  147. (pWinCert->wCertificateType != WIN_CERT_TYPE_PKCS_SIGNED_DATA))
  148. {
  149. SetLastError(ERROR_INVALID_PARAMETER);
  150. return(FALSE);
  151. }
  152. if (*pdwIndex > SIG_MAX)
  153. {
  154. SetLastError(ERROR_INVALID_PARAMETER);
  155. return(FALSE);
  156. }
  157. IStream *pStream;
  158. pStream = NULL;
  159. if ((pTopStg->CreateStream(Ids[*pdwIndex].pwszName,
  160. STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,
  161. 0, 0, &pStream) != S_OK) ||
  162. !(pStream))
  163. {
  164. SetLastError(ERROR_BAD_FORMAT);
  165. return(FALSE);
  166. }
  167. if (pStream->Write(pWinCert->bCertificate,
  168. pWinCert->dwLength - WVT_OFFSETOF(WIN_CERTIFICATE, bCertificate),
  169. NULL) != S_OK)
  170. {
  171. pStream->Release();
  172. SetLastError(ERROR_BAD_FORMAT);
  173. return(FALSE);
  174. }
  175. pStream->Release();
  176. return(TRUE);
  177. }
  178. BOOL SIPObjectSS_::GetDigestStream(DIGEST_DATA *pDigestData,
  179. DIGEST_FUNCTION pfnCallBack, DWORD dwFlags)
  180. {
  181. return(this->IStorageDigest(pTopStg, pDigestData, pfnCallBack));
  182. }
  183. BOOL SIPObjectSS_::IStorageDigest(IStorage *pStg, DIGEST_DATA *pDigestData, DIGEST_FUNCTION pfnCallBack)
  184. {
  185. STATSTG *pSortStg;
  186. STATSTG sStatStg;
  187. DWORD cSortStg;
  188. BOOL fRet;
  189. cSortStg = 0;
  190. pSortStg = NULL;
  191. if (!(this->SortElements(pStg, &cSortStg, &pSortStg)))
  192. {
  193. return(FALSE);
  194. }
  195. if (cSortStg == 0)
  196. {
  197. return(TRUE);
  198. }
  199. if (!(pSortStg))
  200. {
  201. return(FALSE);
  202. }
  203. for (int i = 0; i < (int)cSortStg; i++)
  204. {
  205. switch (pSortStg[i].type)
  206. {
  207. case STGTY_STORAGE:
  208. IStorage *pInnerStg;
  209. pInnerStg = NULL;
  210. if ((pStg->OpenStorage(pSortStg[i].pwcsName, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
  211. 0, 0, &pInnerStg) != S_OK) ||
  212. !(pInnerStg))
  213. {
  214. this->FreeElements(&cSortStg, &pSortStg);
  215. SetLastError(ERROR_BAD_FORMAT);
  216. return(FALSE);
  217. }
  218. //
  219. // WARNING: recursive!
  220. //
  221. fRet = this->IStorageDigest(pInnerStg, pDigestData, pfnCallBack);
  222. pInnerStg->Release();
  223. if (!(fRet))
  224. {
  225. this->FreeElements(&cSortStg, &pSortStg);
  226. return(FALSE);
  227. }
  228. break;
  229. case STGTY_STREAM:
  230. IStream *pInnerStm;
  231. StreamIds *pIds;
  232. BOOL fSigEntry;
  233. BYTE rgb[512];
  234. ULONG cbRead;
  235. fSigEntry = FALSE;
  236. pIds = &Ids[0];
  237. while (pIds->dwSigIndex != 0xffffffff)
  238. {
  239. if (_wcsicmp(pSortStg[i].pwcsName, pIds->pwszName) == 0)
  240. {
  241. fSigEntry = TRUE;
  242. break;
  243. }
  244. pIds++;
  245. }
  246. if (fSigEntry)
  247. {
  248. break;
  249. }
  250. pInnerStm = NULL;
  251. if ((pStg->OpenStream(pSortStg[i].pwcsName,
  252. NULL,
  253. STGM_READ | STGM_SHARE_EXCLUSIVE,
  254. 0,
  255. &pInnerStm) != S_OK) ||
  256. !(pInnerStm))
  257. {
  258. this->FreeElements(&cSortStg, &pSortStg);
  259. SetLastError(ERROR_BAD_FORMAT);
  260. return(FALSE);
  261. }
  262. for EVER
  263. {
  264. cbRead = 0;
  265. if (pInnerStm->Read(rgb, 512, &cbRead) != S_OK)
  266. {
  267. break;
  268. }
  269. if (cbRead == 0)
  270. {
  271. break;
  272. }
  273. if (!(pfnCallBack(pDigestData, rgb, cbRead)))
  274. {
  275. this->FreeElements(&cSortStg, &pSortStg);
  276. pInnerStm->Release();
  277. return(FALSE);
  278. }
  279. }
  280. pInnerStm->Release();
  281. break;
  282. case STGTY_LOCKBYTES:
  283. break;
  284. case STGTY_PROPERTY:
  285. break;
  286. default:
  287. break;
  288. }
  289. }
  290. memset(&sStatStg, 0x00, sizeof(STATSTG));
  291. if (pStg->Stat(&sStatStg, STATFLAG_NONAME) != S_OK)
  292. {
  293. this->FreeElements(&cSortStg, &pSortStg);
  294. SetLastError(ERROR_BAD_FORMAT);
  295. return(FALSE);
  296. }
  297. // the ctime member is changed if the file is copied....
  298. // !(pfnCallBack(pDigestData, (BYTE *)&sStatStg.ctime, sizeof(FILETIME))) ||
  299. //
  300. if (!(pfnCallBack(pDigestData, (BYTE *)&sStatStg.type, sizeof(DWORD))) ||
  301. !(pfnCallBack(pDigestData, (BYTE *)&sStatStg.cbSize, sizeof(ULARGE_INTEGER))) ||
  302. !(pfnCallBack(pDigestData, (BYTE *)&sStatStg.clsid, sizeof(CLSID))) ||
  303. !(pfnCallBack(pDigestData, (BYTE *)&sStatStg.grfStateBits, sizeof(DWORD))))
  304. {
  305. this->FreeElements(&cSortStg, &pSortStg);
  306. return(FALSE);
  307. }
  308. this->FreeElements(&cSortStg, &pSortStg);
  309. return(TRUE);
  310. }
  311. BOOL SIPObjectSS_::FileHandleFromSubject(SIP_SUBJECTINFO *pSubject, DWORD dwAccess, DWORD dwShared)
  312. {
  313. /* if ((dwAccess & GENERIC_WRITE) &&
  314. (pSubject->hFile != NULL) &&
  315. (pSubject->hFile != INVALID_HANDLE_VALUE))
  316. {
  317. CloseHandle(pSubject->hFile);
  318. pSubject->hFile = NULL;
  319. } */
  320. HRESULT hr;
  321. pTopStg = NULL;
  322. /* if ((hr = StgOpenStorage((const WCHAR *)pSubject->pwsFileName,
  323. NULL,
  324. (dwAccess & GENERIC_WRITE) ?
  325. (STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT) :
  326. (STGM_READ | STGM_SHARE_DENY_NONE | STGM_TRANSACTED),
  327. NULL,
  328. 0,
  329. &pTopStg)) != S_OK)
  330. {
  331. pTopStg = NULL;
  332. return(FALSE);
  333. } */
  334. if ((hr = StgOpenStorage((const WCHAR *)pSubject->pwsFileName,
  335. NULL,
  336. (dwAccess & GENERIC_WRITE) ?
  337. (STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT) :
  338. (STGM_READ | STGM_SHARE_DENY_WRITE | STGM_DIRECT),
  339. NULL,
  340. 0,
  341. &pTopStg)) != S_OK)
  342. {
  343. pTopStg = NULL;
  344. return(FALSE);
  345. }
  346. return(TRUE);
  347. }
  348. ////////////////////////////////////////////////////////////////////////////
  349. //
  350. // private:
  351. //
  352. BOOL WINAPI IsStructuredStorageFile(WCHAR *pwszFileName, GUID *pgSubject)
  353. {
  354. GUID gSS = CRYPT_SUBJTYPE_SS_IMAGE;
  355. if (!(pwszFileName) ||
  356. !(pgSubject))
  357. {
  358. SetLastError(ERROR_INVALID_PARAMETER);
  359. return(FALSE);
  360. }
  361. if (StgIsStorageFile(pwszFileName) == S_OK)
  362. {
  363. memcpy(pgSubject, &gSS, sizeof(GUID));
  364. return(TRUE);
  365. }
  366. return(FALSE);
  367. }
  368. static int __cdecl CompareSTATSTG(const void *p1, const void *p2)
  369. {
  370. return(wcscmp(((STATSTG *)p1)->pwcsName, ((STATSTG *)p2)->pwcsName));
  371. }
  372. void SIPObjectSS_::FreeElements(DWORD *pcStg, STATSTG **ppStg)
  373. {
  374. if (*ppStg)
  375. {
  376. STATSTG *pStg;
  377. pStg = *ppStg;
  378. for (int i = 0; i < (int)*pcStg; i++)
  379. {
  380. if (pStg[i].pwcsName)
  381. {
  382. CoTaskMemFree(pStg[i].pwcsName);
  383. }
  384. }
  385. DELETE_OBJECT(*ppStg);
  386. }
  387. *pcStg = 0;
  388. }
  389. BOOL SIPObjectSS_::SortElements(IStorage *pStg, DWORD *pcSortStg, STATSTG **ppSortStg)
  390. {
  391. DWORD cb;
  392. IEnumSTATSTG *pEnum;
  393. pEnum = NULL;
  394. *pcSortStg = 0;
  395. *ppSortStg = NULL;
  396. if (pStg->EnumElements(0, NULL, 0, &pEnum) != S_OK)
  397. {
  398. return(FALSE);
  399. }
  400. DWORD celtFetched;
  401. STATSTG rgCntStatStg[10];
  402. for EVER
  403. {
  404. celtFetched = 0;
  405. pEnum->Next(10, rgCntStatStg, &celtFetched);
  406. if (celtFetched == 0)
  407. {
  408. break;
  409. }
  410. *pcSortStg += celtFetched;
  411. while (celtFetched--)
  412. {
  413. CoTaskMemFree(rgCntStatStg[celtFetched].pwcsName);
  414. }
  415. }
  416. if (*pcSortStg > 0)
  417. {
  418. cb = sizeof(STATSTG) * *pcSortStg;
  419. if (!(*ppSortStg = (STATSTG *)this->SIPNew(cb)))
  420. {
  421. pEnum->Release();
  422. return(FALSE);
  423. }
  424. memset(*ppSortStg, 0x00, cb);
  425. pEnum->Reset();
  426. celtFetched = 0;
  427. if ((pEnum->Next(*pcSortStg, *ppSortStg, &celtFetched) != S_OK) ||
  428. (celtFetched != *pcSortStg))
  429. {
  430. this->FreeElements(pcSortStg, ppSortStg);
  431. pEnum->Release();
  432. SetLastError(ERROR_BAD_FORMAT);
  433. return(FALSE);
  434. }
  435. qsort(*ppSortStg, *pcSortStg, sizeof(STATSTG), CompareSTATSTG);
  436. }
  437. pEnum->Release();
  438. return(TRUE);
  439. }