SECURITY.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*++
  2. Copyright 1996-1997 Microsoft Corporation
  3. Module Name:
  4.     security.c
  5. Abstract:
  6.     Handles communication with the SSP package.
  7. Revision History:
  8. --*/
  9. #include <windows.h>
  10. #include <winsock.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #define SECURITY_WIN32
  14. #include "sspi.h"
  15. #include "issperr.h"
  16. #include "security.h"
  17. #include "collect.h"
  18. static HINSTANCE g_hLib;
  19. static DWORD g_cbMaxToken;
  20. static PSecurityFunctionTable g_pFuncs;
  21. // structure storing the state of the authentication sequence
  22. //
  23. typedef struct _AUTH_SEQ {
  24.     BOOL _fNewConversation;
  25.     CredHandle _hcred;
  26.     BOOL _fHaveCredHandle;
  27.     BOOL _fHaveCtxtHandle;
  28.     struct _SecHandle  _hctxt;
  29. } AUTH_SEQ, *PAUTH_SEQ;
  30. #define SEC_SUCCESS(Status) ((Status) >= 0)
  31. #define PACKAGE_NAME "NTLM"
  32. #define NT_DLL_NAME "security.dll"
  33. // Target name for the security package
  34. //
  35. #define TOKEN_SOURCE_NAME       "AuthSamp"
  36. BOOL InitPackage (DWORD *pcbMaxMessage)
  37. /*++
  38.  Routine Description:
  39.     Finds, loads and initializes the security package
  40.  Return Value:
  41.     Returns TRUE is successful; otherwise FALSE is returned.
  42. --*/
  43. {
  44. FARPROC pInit;
  45. SECURITY_STATUS ss;
  46. PSecPkgInfo pkgInfo;
  47. // load and initialize the ntlm ssp
  48. //
  49. g_hLib = LoadLibrary (NT_DLL_NAME);
  50. if (NULL == g_hLib)  {
  51. fprintf (stderr, "Couldn't load dll: %un", GetLastError ());
  52. return(FALSE);
  53. }
  54. pInit = GetProcAddress (g_hLib, SECURITY_ENTRYPOINT);
  55. if (NULL == pInit)  {
  56. fprintf (stderr, "Couldn't get sec init routine: %un", GetLastError ());
  57. return(FALSE);
  58. }
  59. g_pFuncs = (PSecurityFunctionTable) pInit ();
  60. if (NULL == g_pFuncs)  {
  61. fprintf (stderr, "Couldn't init packagen");
  62. return(FALSE);
  63. }
  64. // Query for the package we're interested in
  65. //
  66. ss = g_pFuncs->QuerySecurityPackageInfo (PACKAGE_NAME, &pkgInfo);
  67. if (!SEC_SUCCESS(ss))  {
  68. fprintf (stderr, "Couldn't query package info for %s, error %un",
  69. PACKAGE_NAME, ss);
  70. return(FALSE);
  71. }
  72. g_cbMaxToken = pkgInfo->cbMaxToken;
  73. g_pFuncs->FreeContextBuffer (pkgInfo);
  74. *pcbMaxMessage = g_cbMaxToken;
  75. return TRUE;
  76. }
  77. BOOL TermPackage ()
  78. {
  79. FreeLibrary (g_hLib);
  80. return(TRUE);
  81. }
  82. BOOL GenClientContext (
  83. DWORD dwKey,
  84. BYTE *pIn,
  85. DWORD cbIn,
  86. BYTE *pOut,
  87. DWORD *pcbOut,
  88. BOOL *pfDone)
  89. /*++
  90.  Routine Description:
  91.     Optionally takes an input buffer coming from the server and returns
  92. a buffer of information to send back to the server.  Also returns
  93. an indication of whether or not the context is complete.
  94.  Return Value:
  95.     Returns TRUE is successful; otherwise FALSE is returned.
  96. --*/
  97. {
  98. SECURITY_STATUS ss;
  99. TimeStamp Lifetime;
  100. SecBufferDesc OutBuffDesc;
  101. SecBuffer OutSecBuff;
  102. SecBufferDesc InBuffDesc;
  103. SecBuffer InSecBuff;
  104. ULONG ContextAttributes;
  105. PAUTH_SEQ pAS;
  106. // Lookup pAS based on Key
  107. //
  108. if (!GetEntry (dwKey, (PVOID*) &pAS))
  109. return(FALSE);
  110. if (pAS->_fNewConversation)  {
  111. ss = g_pFuncs->AcquireCredentialsHandle (
  112. NULL, // principal
  113. PACKAGE_NAME,
  114. SECPKG_CRED_OUTBOUND,
  115. NULL, // LOGON id
  116. NULL, // auth data
  117. NULL, // get key fn
  118. NULL, // get key arg
  119. &pAS->_hcred,
  120. &Lifetime
  121. );
  122. if (SEC_SUCCESS (ss))
  123. pAS->_fHaveCredHandle = TRUE;
  124. else {
  125. fprintf (stderr, "AcquireCreds failed: %un", ss);
  126. return(FALSE);
  127. }
  128. }
  129. // prepare output buffer
  130. //
  131. OutBuffDesc.ulVersion = 0;
  132. OutBuffDesc.cBuffers = 1;
  133. OutBuffDesc.pBuffers = &OutSecBuff;
  134. OutSecBuff.cbBuffer = *pcbOut;
  135. OutSecBuff.BufferType = SECBUFFER_TOKEN;
  136. OutSecBuff.pvBuffer = pOut;
  137. // prepare input buffer
  138. //
  139. if (!pAS->_fNewConversation)  {
  140. InBuffDesc.ulVersion = 0;
  141. InBuffDesc.cBuffers = 1;
  142. InBuffDesc.pBuffers = &InSecBuff;
  143. InSecBuff.cbBuffer = cbIn;
  144. InSecBuff.BufferType = SECBUFFER_TOKEN;
  145. InSecBuff.pvBuffer = pIn;
  146. }
  147. ss = g_pFuncs->InitializeSecurityContext (
  148. &pAS->_hcred,
  149. pAS->_fNewConversation ? NULL : &pAS->_hctxt,
  150. TOKEN_SOURCE_NAME,
  151. 0, // context requirements
  152. 0, // reserved1
  153. SECURITY_NATIVE_DREP,
  154. pAS->_fNewConversation ? NULL : &InBuffDesc,
  155. 0, // reserved2
  156. &pAS->_hctxt,
  157. &OutBuffDesc,
  158. &ContextAttributes,
  159. &Lifetime
  160. );
  161. if (!SEC_SUCCESS (ss))  {
  162. fprintf (stderr, "init context failed: %un", ss);
  163. return FALSE;
  164. }
  165. pAS->_fHaveCtxtHandle = TRUE;
  166. // Complete token -- if applicable
  167. //
  168. if ((SEC_I_COMPLETE_NEEDED == ss) || (SEC_I_COMPLETE_AND_CONTINUE == ss))  {
  169. if (g_pFuncs->CompleteAuthToken) {
  170. ss = g_pFuncs->CompleteAuthToken (&pAS->_hctxt, &OutBuffDesc);
  171. if (!SEC_SUCCESS(ss))  {
  172. fprintf (stderr, "complete failed: %un", ss);
  173. return FALSE;
  174. }
  175. }
  176. else {
  177. fprintf (stderr, "Complete not supported.n");
  178. return FALSE;
  179. }
  180. }
  181. *pcbOut = OutSecBuff.cbBuffer;
  182. if (pAS->_fNewConversation)
  183. pAS->_fNewConversation = FALSE;
  184. *pfDone = !((SEC_I_CONTINUE_NEEDED == ss) ||
  185. (SEC_I_COMPLETE_AND_CONTINUE == ss));
  186. return TRUE;
  187. }
  188. BOOL GenServerContext (
  189. DWORD dwKey,
  190. BYTE *pIn,
  191. DWORD cbIn,
  192. BYTE *pOut,
  193. DWORD *pcbOut,
  194. BOOL *pfDone)
  195. /*++
  196.  Routine Description:
  197.     Takes an input buffer coming from the client and returns a buffer
  198. to be sent to the client.  Also returns an indication of whether or
  199. not the context is complete.
  200.  Return Value:
  201.     Returns TRUE is successful; otherwise FALSE is returned.
  202. --*/
  203. {
  204. SECURITY_STATUS ss;
  205. TimeStamp Lifetime;
  206. SecBufferDesc OutBuffDesc;
  207. SecBuffer OutSecBuff;
  208. SecBufferDesc InBuffDesc;
  209. SecBuffer InSecBuff;
  210. ULONG ContextAttributes;
  211. PAUTH_SEQ pAS;
  212. // Lookup pAS based on Key
  213. //
  214. if (!GetEntry (dwKey, (PVOID*) &pAS))
  215. return(FALSE);
  216. if (pAS->_fNewConversation)  {
  217. ss = g_pFuncs->AcquireCredentialsHandle (
  218. NULL, // principal
  219. PACKAGE_NAME,
  220. SECPKG_CRED_INBOUND,
  221. NULL, // LOGON id
  222. NULL, // auth data
  223. NULL, // get key fn
  224. NULL, // get key arg
  225. &pAS->_hcred,
  226. &Lifetime
  227. );
  228. if (SEC_SUCCESS (ss))
  229. pAS->_fHaveCredHandle = TRUE;
  230. else {
  231. fprintf (stderr, "AcquireCreds failed: %un", ss);
  232. return(FALSE);
  233. }
  234. }
  235. // prepare output buffer
  236. //
  237. OutBuffDesc.ulVersion = 0;
  238. OutBuffDesc.cBuffers = 1;
  239. OutBuffDesc.pBuffers = &OutSecBuff;
  240. OutSecBuff.cbBuffer = *pcbOut;
  241. OutSecBuff.BufferType = SECBUFFER_TOKEN;
  242. OutSecBuff.pvBuffer = pOut;
  243. // prepare input buffer
  244. //
  245. InBuffDesc.ulVersion = 0;
  246. InBuffDesc.cBuffers = 1;
  247. InBuffDesc.pBuffers = &InSecBuff;
  248. InSecBuff.cbBuffer = cbIn;
  249. InSecBuff.BufferType = SECBUFFER_TOKEN;
  250. InSecBuff.pvBuffer = pIn;
  251. ss = g_pFuncs->AcceptSecurityContext (
  252. &pAS->_hcred,
  253. pAS->_fNewConversation ? NULL : &pAS->_hctxt,
  254. &InBuffDesc,
  255. 0, // context requirements
  256. SECURITY_NATIVE_DREP,
  257. &pAS->_hctxt,
  258. &OutBuffDesc,
  259. &ContextAttributes,
  260. &Lifetime
  261. );
  262. if (!SEC_SUCCESS (ss))  {
  263. fprintf (stderr, "init context failed: %un", ss);
  264. return FALSE;
  265. }
  266. pAS->_fHaveCtxtHandle = TRUE;
  267. // Complete token -- if applicable
  268. //
  269. if ((SEC_I_COMPLETE_NEEDED == ss) || (SEC_I_COMPLETE_AND_CONTINUE == ss))  {
  270. if (g_pFuncs->CompleteAuthToken) {
  271. ss = g_pFuncs->CompleteAuthToken (&pAS->_hctxt, &OutBuffDesc);
  272. if (!SEC_SUCCESS(ss))  {
  273. fprintf (stderr, "complete failed: %un", ss);
  274. return FALSE;
  275. }
  276. }
  277. else {
  278. fprintf (stderr, "Complete not supported.n");
  279. return FALSE;
  280. }
  281. }
  282. *pcbOut = OutSecBuff.cbBuffer;
  283. if (pAS->_fNewConversation)
  284. pAS->_fNewConversation = FALSE;
  285. *pfDone = !((SEC_I_CONTINUE_NEEDED == ss) ||
  286. (SEC_I_COMPLETE_AND_CONTINUE == ss));
  287. return TRUE;
  288. }
  289. BOOL ImpersonateContext (DWORD dwKey)
  290. /*++
  291.  Routine Description:
  292.     Impersonates the client whose context is associated with the
  293. supplied key.
  294.  Return Value:
  295.     Returns TRUE is successful; otherwise FALSE is returned.
  296. --*/
  297. {
  298. SECURITY_STATUS ss;
  299. PAUTH_SEQ pAS;
  300. // Lookup pAS based on Key
  301. //
  302. if (!GetEntry (dwKey, (PVOID*) &pAS))
  303. return(FALSE);
  304. ss = g_pFuncs->ImpersonateSecurityContext (&pAS->_hctxt);
  305. if (!SEC_SUCCESS(ss)) {
  306. fprintf (stderr, "Impersonate failed: %un", ss);
  307. return(FALSE);
  308. }
  309. return(TRUE);
  310. }
  311. BOOL RevertContext (DWORD dwKey)
  312. /*++
  313.  Routine Description:
  314.     Reverts to the original server context.
  315.  Return Value:
  316.     Returns TRUE is successful; otherwise FALSE is returned.
  317. --*/
  318. {
  319. SECURITY_STATUS ss;
  320. PAUTH_SEQ pAS;
  321. // Lookup pAS based on Key
  322. //
  323. if (!GetEntry (dwKey, (PVOID*) &pAS))
  324. return(FALSE);
  325. ss = g_pFuncs->RevertSecurityContext (&pAS->_hctxt);
  326. if (!SEC_SUCCESS(ss)) {
  327. fprintf (stderr, "Revert failed: %un", ss);
  328. return(FALSE);
  329. }
  330. return(TRUE);
  331. }
  332. BOOL InitSession (DWORD dwKey)
  333. /*++
  334.  Routine Description:
  335.     Initializes the context associated with a key and adds it to the
  336. collection.
  337.  Return Value:
  338.     Returns TRUE is successful; otherwise FALSE is returned.
  339. --*/
  340. {
  341. PAUTH_SEQ pAS;
  342. pAS = (PAUTH_SEQ) malloc (sizeof (AUTH_SEQ));
  343. if (NULL == pAS)
  344. return(FALSE);
  345. pAS->_fNewConversation = TRUE;
  346. pAS->_fHaveCredHandle = FALSE;
  347. pAS->_fHaveCtxtHandle = FALSE;
  348. if (!AddEntry (dwKey, (PVOID)pAS))  {
  349. free (pAS);
  350. return(FALSE);
  351. }
  352. return(TRUE);
  353. }
  354. BOOL TermSession (DWORD dwKey)
  355. /*++
  356.  Routine Description:
  357.     Releases the resources associated with a key and removes it from
  358. the collection.
  359.  Return Value:
  360.     Returns TRUE is successful; otherwise FALSE is returned.
  361. --*/
  362. {
  363. PAUTH_SEQ pAS;
  364. if (!DeleteEntry (dwKey, (LPVOID*)&pAS))
  365. return(FALSE);
  366. if (pAS->_fHaveCtxtHandle)
  367. g_pFuncs->DeleteSecurityContext (&pAS->_hctxt);
  368. if (pAS->_fHaveCredHandle)
  369. g_pFuncs->FreeCredentialHandle (&pAS->_hcred);
  370. free (pAS);
  371. return(TRUE);
  372. }