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.

1450 lines
38 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: ticktest.cxx
  7. //
  8. // Contents: KDC Ticket granting service test code.
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 19-Aug-93 WadeR Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <secpch2.hxx>
  18. #pragma hdrstop
  19. #include <stdio.h>
  20. #include <authdata.hxx>
  21. #include <kerbcomm.h>
  22. #include <tostring.hxx>
  23. extern "C" {
  24. #include <winsock.h>
  25. #include <kdc.h>
  26. }
  27. #include <kdcsvr.hxx>
  28. #include <tktutil.hxx>
  29. extern PWCHAR pwzKdcPasswd;
  30. extern PWCHAR pwzPSPasswd;
  31. extern PWCHAR pwzRealm;
  32. extern PWCHAR pwzUserName;
  33. extern PWCHAR pwzUserPasswd;
  34. extern PWCHAR pwzTransport;
  35. extern PWCHAR pwzEndPoint;
  36. extern PWCHAR pwzAddress;
  37. extern PWCHAR pwzClientAddress;
  38. extern PWCHAR pwzKDC;
  39. extern PWCHAR pwzPrivSvr;
  40. extern PWCHAR pwzServiceName;
  41. extern DWORD dwUserRID;
  42. extern DWORD dwServiceRID;
  43. extern DWORD dwKdcRID;
  44. extern DWORD dwPrivSvrRID;
  45. extern BOOL fGetAS;
  46. extern BOOL fGetTGS;
  47. extern BOOL fGetPAC;
  48. extern BOOL fGetCTGT;
  49. extern BOOL fGetServiceTkt;
  50. extern BOOL fRenewSvc;
  51. extern BOOL fTestTransitComp;
  52. extern BOOL fTestReferal;
  53. extern BOOL fPrintPACs;
  54. extern BOOL fPrintTickets;
  55. extern BOOL fVerbose;
  56. enum BindTarget {KDC, KDCDBG};
  57. enum CallType {GETTGS, GETAS};
  58. handle_t
  59. BindTo( BindTarget target,
  60. LPTSTR pszTransport,
  61. LPTSTR pszEndpoint,
  62. LPTSTR pszServer );
  63. NTSTATUS
  64. CheckPAData( const KERB_ENCRYPTION_KEY& kSessionKey, PKERB_PA_DATA pkdReply, enum CallType type );
  65. //////////////////////////////////////////////////////////////////////////
  66. //
  67. // Socket client functions
  68. //
  69. //////////////////////////////////////////////////////////////////////////
  70. //+-------------------------------------------------------------------------
  71. //
  72. // Function: KerbInitializeSockets
  73. //
  74. // Synopsis:
  75. //
  76. // Effects:
  77. //
  78. // Arguments:
  79. //
  80. // Requires:
  81. //
  82. // Returns:
  83. //
  84. // Notes:
  85. //
  86. //
  87. //--------------------------------------------------------------------------
  88. #define KERB_KDC_CALL_TIMEOUT 10
  89. void
  90. PrintFlags( const KERB_TICKET_FLAGS fFlags )
  91. {
  92. #define KerbFlagDef(x) {#x, KERB_TICKET_FLAGS_ ## x}
  93. const static struct {
  94. char * FlagName;
  95. KERB_TICKET_FLAGS Flag;
  96. } Flags[] = {
  97. KerbFlagDef( forwardable ),
  98. KerbFlagDef( forwarded ),
  99. KerbFlagDef( proxiable ),
  100. KerbFlagDef( proxy ),
  101. KerbFlagDef( may_postdate ),
  102. KerbFlagDef( postdated ),
  103. KerbFlagDef( invalid ),
  104. KerbFlagDef( renewable ),
  105. KerbFlagDef( initial ),
  106. KerbFlagDef( pre_authent ),
  107. KerbFlagDef( hw_authent ),
  108. KerbFlagDef( reserved )
  109. };
  110. const int cFlags = sizeof( Flags ) / sizeof( Flags[0] );
  111. for (int i=0; i<cFlags; i++)
  112. {
  113. if (fFlags & Flags[i].Flag)
  114. {
  115. printf("%s,", Flags[i].FlagName );
  116. }
  117. }
  118. printf("\b \n");
  119. #undef KerbFlagDef
  120. }
  121. inline void
  122. Print( const UNICODE_STRING& ssFoo )
  123. {
  124. printf("%wZ", &ssFoo );
  125. }
  126. void
  127. Print( const LARGE_INTEGER& tsFoo )
  128. {
  129. UNICODE_STRING ssTime = TimeStampToString( tsFoo );
  130. printf("%wZ", &ssTime );
  131. KerbFreeString(&ssTime);
  132. }
  133. void
  134. Print( const KERB_ENCRYPTION_KEY& kKey )
  135. {
  136. printf("%d,%d,{",kKey.keytype, kKey.keyvalue.length);
  137. for (ULONG i=0; i<kKey.keyvalue.length; i++ )
  138. {
  139. printf("%02x ", kKey.keyvalue.value[i] );
  140. }
  141. printf("\b}");
  142. }
  143. void
  144. Print( const PISID psid )
  145. {
  146. WCHAR Buffer[512];
  147. UNICODE_STRING usFoo = {0, sizeof(Buffer), Buffer};
  148. RtlConvertSidToUnicodeString( &usFoo, psid, FALSE );
  149. printf("%wZ", &usFoo );
  150. }
  151. void
  152. PrintTicket( PKERB_TICKET pktTicket,
  153. PWCHAR pwzPasswd )
  154. {
  155. #ifdef notdef
  156. NTSTATUS sc;
  157. PKERB_ENCRYPTED_TICKET pkitTicket;
  158. PKERB_TICKET pktTicketCopy;
  159. KERB_ENCRYPTION_KEY kKey;
  160. UNICODE_STRING ssFoo;
  161. RtlInitUnicodeString( &ssFoo, pwzPasswd );
  162. KerbHashPassword(
  163. &ssFoo,
  164. KERB_ETYPE_RC4_MD4,
  165. &kKey
  166. );
  167. pktTicketCopy = (PKerbTicket) new BYTE [sizeof(SizeOfTicket( pktTicket )];
  168. RtlCopyMemory( pktTicketCopy, pktTicket, SizeOfTicket( pktTicket ) );
  169. sc = KerbUnpackTicket( pktTicketCopy, &kKey, &kitTicket );
  170. if (FAILED(sc))
  171. {
  172. printf("Couldn't decrypt ticket with password '%ws' (0x%X)\n",
  173. pwzPasswd, sc );
  174. return;
  175. }
  176. if (kitTicket.dwVersion != 5) {
  177. printf("\t*** dwVersion: 0x%lX\t\t*** not 5\n", kitTicket.dwVersion );
  178. } else {
  179. printf("\tdwVersion:\t%d",kitTicket.dwVersion );
  180. }
  181. printf("\n\tFlags: (0x%x):\t",kitTicket.kitEncryptPart.fTicketFlags );
  182. PrintFlags( kitTicket.kitEncryptPart.fTicketFlags );
  183. printf("\tInitialTicket:\t" );
  184. ::Print( kitTicket.gInitialTicket );
  185. printf("\n\tThisTicket:\t" );
  186. ::Print( kitTicket.gThisTicket );
  187. printf("\n\tIssuingRealm: \t" );
  188. ::Print( kitTicket.dsIssuingRealm );
  189. printf("\n\tServerName: \t" );
  190. ::Print( kitTicket.ServerName.accsid );
  191. printf("\n\tSessionKey: \t" );
  192. ::Print(kitTicket.kitEncryptPart.kSessionKey);
  193. printf("\n\tInitialRealm: \t" );
  194. ::Print( kitTicket.kitEncryptPart.dsInitialRealm );
  195. printf("\n\tPrincipal: \t" );
  196. ::Print( kitTicket.kitEncryptPart.Principal.accsid );
  197. printf("\n\ttsAuthentication:" );
  198. ::Print( kitTicket.kitEncryptPart.tsAuthentication );
  199. printf("\n\ttsStartTime:\t" );
  200. ::Print( kitTicket.kitEncryptPart.tsStartTime );
  201. printf("\n\ttsEndTime:\t" );
  202. ::Print( kitTicket.kitEncryptPart.tsEndTime );
  203. printf("\n\ttsRenewUntil:\t" );
  204. ::Print( kitTicket.kitEncryptPart.tsRenewUntil );
  205. printf("\n\tTransited: \t%ws", kitTicket.kitEncryptPart.tdTransited.pwzTransited );
  206. // printf("\n\tHostAddresses:\t%ws", kitTicket.kitEncryptPart.pkdHostAddresses );
  207. printf("\n");
  208. if (kitTicket.kitEncryptPart.pkdAuthorizationData)
  209. {
  210. ULONG j;
  211. BOOL fFoundSomething = FALSE;
  212. CAuthDataList* padlList = (CAuthDataList*)kitTicket.kitEncryptPart.pkdAuthorizationData->bPAData;
  213. CAuthData* padData;
  214. for (padData = padlList->FindFirst(Any);
  215. padData != NULL;
  216. padData = padlList->FindNext(padData, Any))
  217. {
  218. switch (padData->adtDataType)
  219. {
  220. #if 0
  221. case Pac:
  222. {
  223. printf("\tAuthorizationData (PAC):\n");
  224. CPAC Pac;
  225. ULONG cb = Pac.UnMarshal( (PBYTE) padData->abData );
  226. if (cb <= padData->cbData )
  227. {
  228. if (fPrintPACs)
  229. ::Print( Pac );
  230. fFoundSomething = TRUE;
  231. break;
  232. }
  233. else
  234. {
  235. printf("PAC didn't unmarshal correctly");
  236. }
  237. }
  238. #endif
  239. default:
  240. printf("\tAuthorizationData (Unknown: %d bytes):",
  241. padData->cbData );
  242. for (j=0; j < padData->cbData; j++ ) {
  243. printf("%x ", padData->abData[j] );
  244. }
  245. printf("\n" );
  246. }
  247. }
  248. if (!fFoundSomething)
  249. {
  250. printf("\tAuthorizationData (%d) : 0x", kitTicket.kitEncryptPart.pkdAuthorizationData->cbPAData );
  251. for (j=0; j < kitTicket.kitEncryptPart.pkdAuthorizationData->cbPAData; j++ ) {
  252. printf("%x ", ((PBYTE)kitTicket.kitEncryptPart.pkdAuthorizationData->bPAData)[j] );
  253. }
  254. printf("\n" );
  255. }
  256. }
  257. #endif
  258. }
  259. int
  260. PrintPAC( PEncryptedData pedPAC,
  261. PWCHAR pwzKdcPasswd )
  262. {
  263. #ifdef notdef
  264. // Decrypt it again to print it out.
  265. PEncryptedData pedPacCopy =
  266. (PEncryptedData) new BYTE [ SizeOfEncryptedData( pedPAC ) ];
  267. memcpy( pedPacCopy, pedPAC, SizeOfEncryptedData( pedPAC ) );
  268. //
  269. // Find the PAC in the mess of credentials
  270. //
  271. CAuthData * pad = ((CAuthDataList*)pedPacCopy->ctCipher.bMessage)->FindFirst(Pac_2);
  272. if (pad == NULL)
  273. {
  274. printf("GetPAC's return didn't have a PAC in it.");
  275. return 1;
  276. }
  277. PEncryptedData pedRealPac = (PEncryptedData) pad->abData;
  278. //
  279. // Get the KDC's key, use it to decrypt pedNewPac
  280. //
  281. // Print out the resulting new pac.
  282. //
  283. // delete pedNewPac
  284. //
  285. NTSTATUS sc;
  286. UNICODE_STRING ssFoo;
  287. KERB_ENCRYPTION_KEY kKey;
  288. SRtlInitString( &ssFoo, pwzKdcPasswd );
  289. KerbHashPassword(
  290. &ssFoo,
  291. KERB_ETYPE_RC4_MD4,
  292. &kKey
  293. );
  294. sc = KIDecryptData(pedRealPac, &kKey );
  295. if (!NT_SUCCESS(sc))
  296. {
  297. printf("Couldn't decrypt PAC second time 0x%X\n", sc );
  298. return(1);
  299. }
  300. #endif
  301. return(0);
  302. }
  303. NTSTATUS
  304. CheckPAData( const KERB_ENCRYPTION_KEY& kSessionKey, PKERB_PA_DATA pkdReply, enum CallType type )
  305. {
  306. #ifdef notdef
  307. NTSTATUS err = 0;
  308. TimeStamp tsKdcTime, tsLocalTime, tsDiff;
  309. CAuthData * pad;
  310. CAuthDataList * padlList;
  311. if (pkdReply == 0)
  312. {
  313. printf("Nothing in the padata returned.\n");
  314. return(1);
  315. }
  316. //
  317. // This PAData should contain: Time
  318. // May contain: address info
  319. // May contain: old passwords
  320. //
  321. padlList = (CAuthDataList*) &pkdReply->bPAData[0];
  322. if (padlList->GetMaxSize() != pkdReply->cbPAData )
  323. {
  324. printf("Sizes are wrong for padata.\n");
  325. err = -1;
  326. }
  327. pad = padlList->FindFirst( Time );
  328. if (pad == NULL)
  329. {
  330. printf("Time not included in padata.");
  331. err = -1;
  332. }
  333. //sc = KIDecryptData( (PEncryptedData) pad->bData, &(KERB_ENCRYPTION_KEY&)kSessionKey );
  334. //if (FAILED(sc))
  335. //{
  336. // printf("error 0x%X decrypting time.\n", sc );
  337. // err = -1;
  338. //}
  339. //tsKdcTime = * (PTimeStamp) ((PEncryptedData) pad->abData)->ctCipherText.bMessage;
  340. tsKdcTime = * (PTimeStamp) pad->abData;
  341. GetCurrentTimeStamp( &tsLocalTime );
  342. if (tsKdcTime > tsLocalTime)
  343. tsDiff = tsKdcTime - tsLocalTime;
  344. else
  345. tsDiff = tsLocalTime - tsKdcTime;
  346. if (tsDiff.QuadPart > UInt32x32To64( 10000000ul, 15 ) ) // 15 seconds.
  347. {
  348. printf("Warning: the time at the KDC is " );
  349. Print( tsDiff );
  350. printf(" different.\n" );
  351. }
  352. //
  353. // Address info
  354. //
  355. //
  356. // Passwords
  357. //
  358. #endif
  359. return(S_OK);
  360. }
  361. KERBERR
  362. FooGetASTicket( IN PVOID hBinding,
  363. IN PWCHAR pwzUserName,
  364. IN PWCHAR pwzUserRealm,
  365. IN PWCHAR pwzServiceName,
  366. IN PWCHAR pwzUserPassword,
  367. IN PWCHAR pwzThisWorkstation,
  368. OUT PKERB_TICKET pktTicket,
  369. OUT PKERB_ENCRYPTED_KDC_REPLY * ReplyBody )
  370. {
  371. NTSTATUS Status;
  372. KERBERR KerbErr;
  373. KERB_ENCRYPTION_KEY kUserKey;
  374. KERB_KDC_REQUEST Request;
  375. PKERB_KDC_REQUEST_BODY RequestBody = &Request.request_body;
  376. PKERB_ENCRYPTED_DATA pedReply = 0;
  377. PULONG CryptArray = NULL;
  378. ULONG CryptArraySize = 0;
  379. LARGE_INTEGER TempTime;
  380. KERB_MESSAGE_BUFFER InputMessage;
  381. KERB_MESSAGE_BUFFER OutputMessage;
  382. UNICODE_STRING ssPass;
  383. UNICODE_STRING ssService;
  384. UNICODE_STRING ssRealm;
  385. UNICODE_STRING ssName;
  386. PKERB_KDC_REPLY Reply = NULL;
  387. RtlInitUnicodeString( &ssPass, pwzUserPasswd );
  388. KerbHashPassword(
  389. &ssPass,
  390. KERB_ETYPE_RC4_MD4,
  391. &kUserKey
  392. );
  393. RtlZeroMemory(
  394. &OutputMessage,
  395. sizeof(KERB_MESSAGE_BUFFER)
  396. );
  397. RtlZeroMemory(
  398. &InputMessage,
  399. sizeof(KERB_MESSAGE_BUFFER)
  400. );
  401. RtlInitUnicodeString(
  402. &ssService,
  403. pwzServiceName
  404. );
  405. RtlInitUnicodeString(
  406. &ssRealm,
  407. pwzUserRealm
  408. );
  409. RtlInitUnicodeString(
  410. &ssName,
  411. pwzUserName
  412. );
  413. //
  414. // Build the request
  415. //
  416. RtlZeroMemory( &Request, sizeof( KERB_KDC_REQUEST ) );
  417. RequestBody->kdc_options =
  418. KERB_KDC_OPTIONS_forwardable |
  419. KERB_KDC_OPTIONS_proxiable |
  420. KERB_KDC_OPTIONS_renewable |
  421. KERB_KDC_OPTIONS_renewable_ok;
  422. RequestBody->nonce = 3;
  423. TempTime.QuadPart = 0;
  424. KerbConvertLargeIntToGeneralizedTime(
  425. &RequestBody->KERB_KDC_REQUEST_BODY_starttime,
  426. NULL,
  427. &TempTime
  428. );
  429. TempTime.LowPart = 0xffffffff;
  430. TempTime.HighPart = 0x7fffffff;
  431. KerbConvertLargeIntToGeneralizedTime(
  432. &RequestBody->KERB_KDC_REQUEST_BODY_renew_until,
  433. NULL,
  434. &TempTime
  435. );
  436. RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_renew_until_present;
  437. TempTime.QuadPart = 0;
  438. KerbConvertLargeIntToGeneralizedTime(
  439. &RequestBody->endtime,
  440. NULL,
  441. &TempTime
  442. );
  443. //
  444. // Build crypt vector.
  445. //
  446. CDBuildVect( &CryptArraySize, NULL );
  447. CryptArray = new ULONG [ CryptArraySize ];
  448. CDBuildVect( &CryptArraySize, CryptArray );
  449. KerbErr = KerbConvertArrayToCryptList(
  450. &RequestBody->encryption_type,
  451. CryptArray,
  452. CryptArraySize
  453. );
  454. if (!KERB_SUCCESS(KerbErr))
  455. {
  456. printf("Faield to convert array to crypt list: 0x%x\n",KerbErr);
  457. goto Cleanup;
  458. }
  459. //
  460. // BUGBUG: don't build pre-auth data
  461. //
  462. KerbErr = KerbConvertStringToPrincipalName(
  463. &RequestBody->server_name,
  464. &ssService
  465. );
  466. if (!KERB_SUCCESS(KerbErr))
  467. {
  468. printf("Failed to convert string to principal name: 0x%x\n",KerbErr);
  469. goto Cleanup;
  470. }
  471. KerbErr = KerbConvertStringToPrincipalName(
  472. &RequestBody->KERB_KDC_REQUEST_BODY_client_name,
  473. &ssName
  474. );
  475. if (!KERB_SUCCESS(KerbErr))
  476. {
  477. printf("Failed to convert string to principal name: 0x%x\n",KerbErr);
  478. goto Cleanup;
  479. }
  480. RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_client_name_present;
  481. KerbErr = KerbConvertUnicodeStringToRealm(
  482. &RequestBody->realm,
  483. &ssRealm
  484. );
  485. if (!KERB_SUCCESS(KerbErr))
  486. {
  487. printf("Failed to convert unicde string to realm: 0x%x\n",KerbErr);
  488. goto Cleanup;
  489. }
  490. Request.version = KERBEROS_VERSION;
  491. Request.message_type = KRB_AS_REQ;
  492. KerbErr = KerbPackKdcRequest(
  493. &Request,
  494. &InputMessage.BufferSize,
  495. &InputMessage.Buffer
  496. );
  497. if (!KERB_SUCCESS(KerbErr))
  498. {
  499. printf("Failed to pack KDC request: 0x%x\n",KerbErr);
  500. goto Cleanup;
  501. }
  502. Status = KerbCallKdc(
  503. hBinding,
  504. &InputMessage,
  505. &OutputMessage
  506. );
  507. KerbErr = (KERBERR) Status;
  508. if (!KERB_SUCCESS(KerbErr))
  509. {
  510. printf("KerbCallKdc failed: 0x%x\n",Status);
  511. goto Cleanup;
  512. }
  513. KerbErr = KerbUnpackKdcReply(
  514. OutputMessage.Buffer,
  515. OutputMessage.BufferSize,
  516. &Reply
  517. );
  518. if (!KERB_SUCCESS(KerbErr))
  519. {
  520. printf("Failed to unpack KDC reply: 0x%x\n",KerbErr);
  521. goto Cleanup;
  522. }
  523. KerbErr = KerbUnpackKdcReplyBody(
  524. &Reply->encrypted_part,
  525. &kUserKey,
  526. ReplyBody
  527. );
  528. if (!KERB_SUCCESS(KerbErr))
  529. {
  530. printf("Failed to unpack KDC reply body: 0x%x\n",KerbErr);
  531. goto Cleanup;
  532. }
  533. #ifdef notdef
  534. sc = CheckPAData( pkrReply->kSessionKey, pkdReply, GETAS );
  535. if (FAILED(sc))
  536. {
  537. printf("Problem with PAData returned: 0x%X\n", sc );
  538. return(1);
  539. }
  540. #endif
  541. *pktTicket = Reply->ticket;
  542. Cleanup:
  543. //
  544. // BUGBUG: memory leak here
  545. //
  546. return(KerbErr);
  547. }
  548. KERBERR
  549. FooGetTGSTicket(
  550. IN PVOID hBinding,
  551. IN PWCHAR pwzUserName,
  552. IN PWCHAR pwzUserRealm,
  553. IN PWCHAR pwzServiceName,
  554. IN PKERB_TICKET pktTGTicket,
  555. IN PKERB_ENCRYPTED_KDC_REPLY pkrTGTReply,
  556. IN ULONG AuthDataSize,
  557. IN PUCHAR AuthData,
  558. IN BOOLEAN Renew,
  559. OUT PKERB_TICKET pktTicket,
  560. OUT PKERB_ENCRYPTED_KDC_REPLY * ReplyBody
  561. )
  562. {
  563. KERB_KDC_REQUEST Request;
  564. PKERB_KDC_REQUEST_BODY RequestBody = &Request.request_body;
  565. UNICODE_STRING ssService;
  566. UNICODE_STRING UserName;
  567. UNICODE_STRING UserRealm;
  568. KERBERR KerbErr;
  569. KERB_PA_DATA_LIST PaData;
  570. PULONG CryptArray = NULL;
  571. ULONG CryptArraySize = 0;
  572. LARGE_INTEGER TempTime;
  573. KERB_MESSAGE_BUFFER InputMessage;
  574. KERB_MESSAGE_BUFFER OutputMessage;
  575. PKERB_KDC_REPLY Reply = NULL;
  576. KERB_ENCRYPTED_DATA EncAuthData;
  577. RtlZeroMemory(
  578. &EncAuthData,
  579. sizeof(KERB_ENCRYPTED_DATA)
  580. );
  581. RtlInitUnicodeString(
  582. &ssService,
  583. pwzServiceName
  584. );
  585. RtlInitUnicodeString(
  586. &UserName,
  587. pwzUserName
  588. );
  589. RtlInitUnicodeString(
  590. &UserRealm,
  591. pwzUserRealm
  592. );
  593. //
  594. // Build the request
  595. //
  596. RtlZeroMemory( &Request, sizeof( KERB_KDC_REQUEST ) );
  597. RequestBody->kdc_options = KERB_KDC_OPTIONS_forwardable |
  598. KERB_KDC_OPTIONS_proxiable |
  599. KERB_KDC_OPTIONS_renewable |
  600. KERB_KDC_OPTIONS_renewable_ok;
  601. if (Renew)
  602. {
  603. RequestBody->kdc_options |= KERB_KDC_OPTIONS_renew;
  604. }
  605. RequestBody->nonce = 4;
  606. //
  607. // Build an AP request inside an encrypted data structure.
  608. //
  609. PaData.next = NULL;
  610. PaData.value.preauth_data_type = PA_TGS_REQ;
  611. KerbErr = KerbCreateApRequest(
  612. &UserName,
  613. &UserRealm,
  614. &pkrTGTReply->session_key,
  615. 5, // nonce
  616. pktTGTicket,
  617. 0, // AP options
  618. NULL, // gss checksum
  619. (PULONG) &PaData.value.preauth_data.length,
  620. &PaData.value.preauth_data.value
  621. );
  622. if (!KERB_SUCCESS(KerbErr))
  623. {
  624. printf("Failed to create AP request: 0x%x\n",KerbErr);
  625. goto Cleanup;
  626. }
  627. Request.KERB_KDC_REQUEST_preauth_data = &PaData;
  628. Request.bit_mask |= KERB_KDC_REQUEST_preauth_data_present;
  629. //
  630. // Build crypt vector.
  631. //
  632. CDBuildVect( &CryptArraySize, NULL );
  633. CryptArray = new ULONG [ CryptArraySize ];
  634. CDBuildVect( &CryptArraySize, CryptArray );
  635. KerbErr = KerbConvertArrayToCryptList(
  636. &RequestBody->encryption_type,
  637. CryptArray,
  638. CryptArraySize
  639. );
  640. if (!KERB_SUCCESS(KerbErr))
  641. {
  642. printf("Faield to convert array to crypt list: 0x%x\n",KerbErr);
  643. goto Cleanup;
  644. }
  645. KerbErr = KerbConvertStringToPrincipalName(
  646. &RequestBody->KERB_KDC_REQUEST_BODY_client_name,
  647. &UserName
  648. );
  649. if (!KERB_SUCCESS(KerbErr))
  650. {
  651. goto Cleanup;
  652. }
  653. RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_client_name_present;
  654. KerbErr = KerbConvertUnicodeStringToRealm(
  655. &RequestBody->realm,
  656. &UserRealm
  657. );
  658. if (!KERB_SUCCESS(KerbErr))
  659. {
  660. goto Cleanup;
  661. }
  662. KerbErr = KerbConvertStringToPrincipalName(
  663. &RequestBody->server_name,
  664. &ssService
  665. );
  666. if (!KERB_SUCCESS(KerbErr))
  667. {
  668. goto Cleanup;
  669. }
  670. TempTime.QuadPart = 0;
  671. KerbConvertLargeIntToGeneralizedTime(
  672. &RequestBody->KERB_KDC_REQUEST_BODY_starttime,
  673. NULL,
  674. &TempTime
  675. );
  676. TempTime.LowPart = 0xffffffff;
  677. TempTime.HighPart = 0x7fffffff;
  678. KerbConvertLargeIntToGeneralizedTime(
  679. &RequestBody->KERB_KDC_REQUEST_BODY_renew_until,
  680. NULL,
  681. &TempTime
  682. );
  683. RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_renew_until_present;
  684. TempTime.LowPart = 0xffffffff;
  685. TempTime.HighPart = 0x7fffffff;
  686. KerbConvertLargeIntToGeneralizedTime(
  687. &RequestBody->endtime,
  688. NULL,
  689. &TempTime
  690. );
  691. if (ARGUMENT_PRESENT(AuthData))
  692. {
  693. ULONG EncryptionOverhead;
  694. KerbErr = KerbGetEncryptionOverhead(
  695. pktTGTicket->encrypted_part.encryption_type,
  696. &EncryptionOverhead,
  697. NULL // BUGBUG
  698. );
  699. if (!KERB_SUCCESS(KerbErr))
  700. {
  701. printf("Failed to get encryption overhead: 0x%x\n",KerbErr);
  702. goto Cleanup;
  703. }
  704. EncAuthData.cipher_text.length = AuthDataSize + EncryptionOverhead;
  705. EncAuthData.cipher_text.value = (PUCHAR) MIDL_user_allocate(EncAuthData.cipher_text.length);
  706. if (EncAuthData.cipher_text.value == NULL)
  707. {
  708. KerbErr = KRB_ERR_GENERIC;
  709. goto Cleanup;
  710. }
  711. KerbErr = KerbEncryptData(
  712. &EncAuthData,
  713. AuthDataSize,
  714. AuthData,
  715. pktTGTicket->encrypted_part.encryption_type,
  716. &pkrTGTReply->session_key
  717. );
  718. if (!KERB_SUCCESS(KerbErr))
  719. {
  720. printf("Failed to encrypt pac auth data: 0x%x\n",KerbErr);
  721. goto Cleanup;
  722. }
  723. RequestBody->enc_authorization_data = EncAuthData;
  724. RequestBody->bit_mask |= enc_authorization_data_present;
  725. }
  726. Request.version = KERBEROS_VERSION;
  727. Request.message_type = KRB_TGS_REQ;
  728. KerbErr = KerbPackKdcRequest(
  729. &Request,
  730. &InputMessage.BufferSize,
  731. &InputMessage.Buffer
  732. );
  733. if (!KERB_SUCCESS(KerbErr))
  734. {
  735. printf("Failed to pack KDC request: 0x%x\n",KerbErr);
  736. goto Cleanup;
  737. }
  738. //
  739. // Get the ticket.
  740. //
  741. OutputMessage.Buffer = NULL;
  742. OutputMessage.BufferSize = 0;
  743. KerbErr = (KERBERR) KerbCallKdc(
  744. hBinding,
  745. &InputMessage,
  746. &OutputMessage
  747. );
  748. if (!KERB_SUCCESS(KerbErr))
  749. {
  750. printf("KerbCallKdc failed: 0x%x\n",KerbErr);
  751. goto Cleanup;
  752. }
  753. KerbErr = KerbUnpackKdcReply(
  754. OutputMessage.Buffer,
  755. OutputMessage.BufferSize,
  756. &Reply
  757. );
  758. if (!KERB_SUCCESS(KerbErr))
  759. {
  760. printf("Failed to unpack KDC reply: 0x%x\n",KerbErr);
  761. goto Cleanup;
  762. }
  763. KerbErr = KerbUnpackKdcReplyBody(
  764. &Reply->encrypted_part,
  765. &pkrTGTReply->session_key,
  766. ReplyBody
  767. );
  768. if (!KERB_SUCCESS(KerbErr))
  769. {
  770. printf("Failed to unpack KDC reply body: 0x%x\n",KerbErr);
  771. goto Cleanup;
  772. }
  773. #ifdef notdef
  774. sc = CheckPAData( pkrReply->kSessionKey, pkdReply, GETAS );
  775. if (FAILED(sc))
  776. {
  777. printf("Problem with PAData returned: 0x%X\n", sc );
  778. return(1);
  779. }
  780. #endif
  781. *pktTicket = Reply->ticket;
  782. Cleanup:
  783. if (EncAuthData.cipher_text.value != NULL)
  784. {
  785. MIDL_user_free(EncAuthData.cipher_text.value);
  786. }
  787. return(KerbErr);
  788. }
  789. KERBERR
  790. FooGetPAC(
  791. PVOID hBinding,
  792. LPWSTR pwzUserName,
  793. LPWSTR pwzUserRealm,
  794. PKERB_TICKET PrivSvrTicket,
  795. PKERB_ENCRYPTED_KDC_REPLY PrivSvrReply,
  796. PULONG AuthDataSize,
  797. PUCHAR * PackedAuthData
  798. )
  799. {
  800. KERBERR KerbErr = KDC_ERR_NONE;
  801. UNICODE_STRING UserName;
  802. UNICODE_STRING UserRealm;
  803. KERB_MESSAGE_BUFFER RequestMessage;
  804. KERB_MESSAGE_BUFFER ReplyMessage;
  805. PKERB_ENCRYPTED_DATA EncryptedPacMessage = NULL;
  806. ReplyMessage.Buffer = NULL;
  807. ReplyMessage.BufferSize = 0;
  808. RtlInitUnicodeString(
  809. &UserName,
  810. pwzUserName
  811. );
  812. RtlInitUnicodeString(
  813. &UserRealm,
  814. pwzUserRealm
  815. );
  816. KerbErr = KerbCreateApRequest(
  817. &UserName,
  818. &UserRealm,
  819. &PrivSvrReply->session_key,
  820. 6, // nonce
  821. PrivSvrTicket,
  822. 0, // AP options
  823. NULL, // gss checksum
  824. &RequestMessage.BufferSize,
  825. &RequestMessage.Buffer
  826. );
  827. if (!KERB_SUCCESS(KerbErr))
  828. {
  829. printf("Failed to create AP request for PAC: 0x%x\n",KerbErr);
  830. goto Cleanup;
  831. }
  832. #ifdef notdef
  833. KerbErr = (KERBERR) GetPAC(
  834. hBinding,
  835. &RequestMessage,
  836. &ReplyMessage
  837. );
  838. if (!KERB_SUCCESS(KerbErr))
  839. {
  840. printf("Failed to get pac : 0x%x\n",KerbErr);
  841. goto Cleanup;
  842. }
  843. #endif
  844. //
  845. // Now decode pac
  846. //
  847. //
  848. // First unpack message into an encrypted data structure
  849. //
  850. KerbErr = KerbUnpackEncryptedData(
  851. ReplyMessage.Buffer,
  852. ReplyMessage.BufferSize,
  853. &EncryptedPacMessage
  854. );
  855. if (!KERB_SUCCESS(KerbErr))
  856. {
  857. printf("Failed to unpack enc pac data: 0x%x\n",KerbErr);
  858. goto Cleanup;
  859. }
  860. //
  861. // Now decrypt into a packed authorization data
  862. //
  863. *PackedAuthData = (PUCHAR) MIDL_user_allocate(EncryptedPacMessage->cipher_text.length);
  864. if (*PackedAuthData == NULL)
  865. {
  866. KerbErr = KRB_ERR_GENERIC;
  867. goto Cleanup;
  868. }
  869. KerbErr = KerbDecryptData(
  870. EncryptedPacMessage,
  871. &PrivSvrReply->session_key,
  872. AuthDataSize,
  873. *PackedAuthData
  874. );
  875. if (!KERB_SUCCESS(KerbErr))
  876. {
  877. printf("Failed to decrypt pac auth data: 0x%x\n",KerbErr);
  878. goto Cleanup;
  879. }
  880. Cleanup:
  881. if (RequestMessage.Buffer != NULL)
  882. {
  883. MIDL_user_free(RequestMessage.Buffer);
  884. }
  885. if (EncryptedPacMessage != NULL)
  886. {
  887. MIDL_user_free(EncryptedPacMessage);
  888. }
  889. if (ReplyMessage.Buffer != NULL)
  890. {
  891. MIDL_user_free(ReplyMessage.Buffer);
  892. }
  893. return(KerbErr);
  894. }
  895. KERBERR
  896. FooCheckTicket(
  897. LPWSTR pwzUserName,
  898. LPWSTR pwzUserRealm,
  899. LPWSTR pwzServiceName,
  900. LPWSTR pwzServicePassword,
  901. PKERB_TICKET ServiceTicket,
  902. PKERB_ENCRYPTED_KDC_REPLY ServiceReply
  903. )
  904. {
  905. KERBERR KerbErr = KDC_ERR_NONE;
  906. UNICODE_STRING UserName;
  907. UNICODE_STRING UserRealm;
  908. UNICODE_STRING ServiceName;
  909. UNICODE_STRING ServicePassword;
  910. ULONG AuthDataSize;
  911. ULONG ApRequestSize;
  912. PUCHAR ApRequestMessage = NULL;
  913. PKERB_AP_REQUEST ApRequest = NULL;
  914. KERB_ENCRYPTION_KEY ServiceKey;
  915. LARGE_INTEGER tsFudgeFactor;
  916. PKERB_ENCRYPTED_TICKET EncryptPart = NULL;
  917. PKERB_AUTHENTICATOR Authenticator = NULL;
  918. KERB_ENCRYPTION_KEY SessionKey;
  919. BOOLEAN UseSubKey;
  920. tsFudgeFactor.QuadPart = 300 * (LONGLONG) 10000000;
  921. CAuthenticatorList Authenticators( tsFudgeFactor );
  922. if (!NT_SUCCESS(Authenticators->Init())
  923. {
  924. return KERB_ERR_GENERIC;
  925. }
  926. RtlInitUnicodeString(
  927. &UserName,
  928. pwzUserName
  929. );
  930. RtlInitUnicodeString(
  931. &UserRealm,
  932. pwzUserRealm
  933. );
  934. RtlInitUnicodeString(
  935. &ServiceName,
  936. pwzServiceName
  937. );
  938. RtlInitUnicodeString(
  939. &ServicePassword,
  940. pwzServicePassword
  941. );
  942. KerbErr = KerbHashPassword(
  943. &ServicePassword,
  944. KERB_ETYPE_RC4_MD4,
  945. &ServiceKey
  946. );
  947. if (!KERB_SUCCESS(KerbErr))
  948. {
  949. goto Cleanup;
  950. }
  951. KerbErr = KerbCreateApRequest(
  952. &UserName,
  953. &UserRealm,
  954. &ServiceReply->session_key,
  955. 7, // nonce
  956. ServiceTicket,
  957. 0, // AP options
  958. NULL, // gss checksum
  959. &ApRequestSize,
  960. &ApRequestMessage
  961. );
  962. if (!KERB_SUCCESS(KerbErr))
  963. {
  964. printf("Failed to create AP request for PAC: 0x%x\n",KerbErr);
  965. goto Cleanup;
  966. }
  967. KerbErr = KerbUnpackApRequest(
  968. ApRequestMessage,
  969. ApRequestSize,
  970. &ApRequest
  971. );
  972. if (!KERB_SUCCESS(KerbErr))
  973. {
  974. printf("Failed to unpack ap request: 0x%x\n",KerbErr);
  975. goto Cleanup;
  976. }
  977. KerbErr = KerbCheckTicket(
  978. &ApRequest->ticket,
  979. &ApRequest->authenticator,
  980. &ServiceKey,
  981. Authenticators,
  982. &tsFudgeFactor,
  983. &ServiceName,
  984. &EncryptPart,
  985. &Authenticator,
  986. &SessionKey,
  987. &UseSubKey
  988. );
  989. if (!KERB_SUCCESS(KerbErr))
  990. {
  991. printf("Failed to check ticket: 0x%x\n",KerbErr);
  992. goto Cleanup;
  993. }
  994. Cleanup:
  995. if (ApRequest != NULL)
  996. {
  997. MIDL_user_free(ApRequest);
  998. }
  999. KerbFreeTicket(EncryptPart);
  1000. KerbFreeAuthenticator(Authenticator);
  1001. if (ApRequestMessage != NULL)
  1002. {
  1003. MIDL_user_free(ApRequestMessage);
  1004. }
  1005. return(KerbErr);
  1006. }
  1007. int
  1008. TicketTests()
  1009. {
  1010. int ret = 0;
  1011. ULONG cbAuthen = 0;
  1012. NTSTATUS sc;
  1013. WCHAR ServiceName[100];
  1014. UNICODE_STRING KdcName;
  1015. PVOID SocketHandle = NULL;
  1016. wcscpy(
  1017. ServiceName,
  1018. pwzRealm
  1019. );
  1020. wcscat(ServiceName,L"\\");
  1021. wcscat(ServiceName,pwzUserName);
  1022. sc = KerbInitializeSockets(
  1023. 0x0101,
  1024. 5
  1025. );
  1026. if (!NT_SUCCESS(sc))
  1027. {
  1028. printf("Failed to initialize sockets: 0x%x\n",sc);
  1029. return((int) sc);
  1030. }
  1031. RtlInitUnicodeString(
  1032. &KdcName,
  1033. pwzAddress
  1034. );
  1035. sc = KerbBindSocket(
  1036. &KdcName,
  1037. &SocketHandle
  1038. );
  1039. if (!NT_SUCCESS(sc))
  1040. {
  1041. printf("KerbSocketBind failed: %0x%x\n",sc);
  1042. return((int) sc);
  1043. }
  1044. __try
  1045. {
  1046. KERB_TICKET ktASTicket;
  1047. KERB_TICKET ktPSTicket;
  1048. KERB_TICKET ktCTGTicket;
  1049. KERB_TICKET ktServTicket;
  1050. KERB_TICKET ktRenewServTicket;
  1051. PKERB_ENCRYPTED_KDC_REPLY pkrASReply = NULL;
  1052. PKERB_ENCRYPTED_KDC_REPLY pkrPSReply = NULL;
  1053. PKERB_ENCRYPTED_KDC_REPLY pkrCTGTReply = NULL;
  1054. PKERB_ENCRYPTED_KDC_REPLY pkrServReply = NULL;
  1055. PKERB_ENCRYPTED_KDC_REPLY pkrRenewServReply = NULL;
  1056. ULONG AuthDataSize = 0;
  1057. PUCHAR AuthData = NULL;
  1058. LARGE_INTEGER tsPing;
  1059. KERBERR KerbErr;
  1060. ULONG PingFlags = 0;
  1061. handle_t hKDC = BindTo( KDC, pwzTransport, pwzEndPoint, pwzAddress );
  1062. if (hKDC == 0 || hKDC == (handle_t)-1 )
  1063. {
  1064. printf("Error binding, quitting.\n" );
  1065. ret = (1);
  1066. goto Done;
  1067. }
  1068. sc = KDCPing( hKDC, &PingFlags, &tsPing );
  1069. if (sc != 0)
  1070. {
  1071. printf("Error %d (0x%X) from KdcPing()\n", sc );
  1072. ret = (1);
  1073. goto Done;
  1074. }
  1075. if (fGetAS)
  1076. {
  1077. KerbErr = FooGetASTicket(
  1078. SocketHandle,
  1079. pwzUserName,
  1080. pwzRealm,
  1081. pwzKDC,
  1082. pwzUserPasswd,
  1083. pwzClientAddress,
  1084. &ktASTicket,
  1085. &pkrASReply );
  1086. if (!KERB_SUCCESS(KerbErr))
  1087. {
  1088. goto Done;
  1089. }
  1090. if (fPrintTickets)
  1091. {
  1092. printf("Initial TGT:\n" );
  1093. PrintTicket( &ktASTicket, pwzKdcPasswd );
  1094. }
  1095. }
  1096. if (fGetTGS)
  1097. {
  1098. KerbErr = FooGetTGSTicket( SocketHandle, // hBinding
  1099. pwzUserName, // pwzUserName
  1100. pwzRealm, // pwzUserRealm
  1101. pwzPrivSvr, // pwzServiceName
  1102. &ktASTicket, // ktTGTicket
  1103. pkrASReply, // krTGTReply
  1104. 0,
  1105. NULL, // no authorization
  1106. FALSE, // don't renew
  1107. &ktPSTicket, // ppktTicket
  1108. &pkrPSReply ); // pkrReply
  1109. if (!KERB_SUCCESS(KerbErr))
  1110. {
  1111. goto Done;
  1112. }
  1113. if (fPrintTickets)
  1114. {
  1115. printf("Ticket to PS:\n" );
  1116. PrintTicket( &ktPSTicket, pwzPSPasswd );
  1117. }
  1118. }
  1119. #ifdef notdef
  1120. if (fGetPAC)
  1121. {
  1122. //
  1123. // Get the PAC.
  1124. //
  1125. KerbErr = FooGetPAC(
  1126. SocketHandle,
  1127. pwzUserName,
  1128. pwzRealm,
  1129. &ktPSTicket,
  1130. pkrPSReply,
  1131. &AuthDataSize,
  1132. &AuthData
  1133. );
  1134. if (!KERB_SUCCESS(KerbErr))
  1135. {
  1136. printf("FooGetPAC() == 0x%X\n", KerbErr );
  1137. goto Done;
  1138. }
  1139. }
  1140. if (fGetCTGT)
  1141. {
  1142. KerbErr = FooGetTGSTicket( SocketHandle, // hBinding
  1143. pwzUserName, // pwzUserName
  1144. pwzRealm, // pwzUserRealm
  1145. pwzKDC, // pwzServiceName
  1146. &ktASTicket, // ktTGTicket
  1147. pkrASReply, // krTGTReply
  1148. AuthDataSize,
  1149. AuthData,
  1150. FALSE, // don't renew
  1151. &ktCTGTicket, // ppktTicket
  1152. &pkrCTGTReply ); // pkrReply
  1153. if (!KERB_SUCCESS(KerbErr))
  1154. {
  1155. printf("Failed to get TGT: 0x%x\n",KerbErr);
  1156. goto Done;
  1157. }
  1158. }
  1159. #endif // notdef
  1160. if (fGetServiceTkt) {
  1161. KerbErr = FooGetTGSTicket( SocketHandle, // hBinding
  1162. pwzUserName, // pwzUserName
  1163. pwzRealm, // pwzUserRealm
  1164. ServiceName, // pwzServiceName
  1165. &ktASTicket, // ktTGTicket
  1166. pkrASReply, // krTGTReply
  1167. 0,
  1168. NULL, // no auth data
  1169. FALSE, // don't renew
  1170. &ktServTicket, // ppktTicket
  1171. &pkrServReply ); // pkrReply
  1172. if (!KERB_SUCCESS(KerbErr))
  1173. {
  1174. printf("Faield to get ticket to service: 0x%x\n",KerbErr);
  1175. goto Done;
  1176. }
  1177. //
  1178. // Now check the ticket.
  1179. //
  1180. KerbErr = FooCheckTicket(
  1181. pwzUserName,
  1182. pwzRealm,
  1183. ServiceName, // service name
  1184. pwzUserPasswd, /// service password
  1185. &ktServTicket,
  1186. pkrServReply
  1187. );
  1188. if (!KERB_SUCCESS(KerbErr))
  1189. {
  1190. printf("Failed tocheck service ticket: 0x%x\n",KerbErr);
  1191. goto Done;
  1192. }
  1193. }
  1194. if (fRenewSvc)
  1195. {
  1196. KerbErr = FooGetTGSTicket( SocketHandle, // hBinding
  1197. pwzUserName, // pwzUserName
  1198. pwzRealm, // pwzUserRealm
  1199. ServiceName, // pwzServiceName
  1200. &ktServTicket, // ktTGTicket
  1201. pkrServReply, // krTGTReply
  1202. 0,
  1203. NULL, // no auth data
  1204. TRUE,
  1205. &ktRenewServTicket, // ppktTicket
  1206. &pkrRenewServReply ); // pkrReply
  1207. if (!KERB_SUCCESS(KerbErr))
  1208. {
  1209. printf("Faield to get ticket to service: 0x%x\n",KerbErr);
  1210. goto Done;
  1211. }
  1212. //
  1213. // Now check the ticket.
  1214. //
  1215. KerbErr = FooCheckTicket(
  1216. pwzUserName,
  1217. pwzRealm,
  1218. ServiceName, // service name
  1219. pwzUserPasswd, /// service password
  1220. &ktServTicket,
  1221. pkrServReply
  1222. );
  1223. if (!KERB_SUCCESS(KerbErr))
  1224. {
  1225. printf("Failed tocheck service ticket: 0x%x\n",KerbErr);
  1226. goto Done;
  1227. }
  1228. }
  1229. Done:
  1230. ;
  1231. }
  1232. __except ( EXCEPTION_EXECUTE_HANDLER )
  1233. {
  1234. printf("Exception 0x%x (%d) in ticktest.\n", GetExceptionCode(), GetExceptionCode() );
  1235. ret = 5;
  1236. }
  1237. if (SocketHandle != NULL)
  1238. {
  1239. closesocket((SOCKET) SocketHandle);
  1240. }
  1241. return(ret);
  1242. }