//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1993. // // File: ticktest.cxx // // Contents: KDC Ticket granting service test code. // // Classes: // // Functions: // // History: 19-Aug-93 WadeR Created // //---------------------------------------------------------------------------- #include #pragma hdrstop #include #include #include #include extern "C" { #include #include } #include #include extern PWCHAR pwzKdcPasswd; extern PWCHAR pwzPSPasswd; extern PWCHAR pwzRealm; extern PWCHAR pwzUserName; extern PWCHAR pwzUserPasswd; extern PWCHAR pwzTransport; extern PWCHAR pwzEndPoint; extern PWCHAR pwzAddress; extern PWCHAR pwzClientAddress; extern PWCHAR pwzKDC; extern PWCHAR pwzPrivSvr; extern PWCHAR pwzServiceName; extern DWORD dwUserRID; extern DWORD dwServiceRID; extern DWORD dwKdcRID; extern DWORD dwPrivSvrRID; extern BOOL fGetAS; extern BOOL fGetTGS; extern BOOL fGetPAC; extern BOOL fGetCTGT; extern BOOL fGetServiceTkt; extern BOOL fRenewSvc; extern BOOL fTestTransitComp; extern BOOL fTestReferal; extern BOOL fPrintPACs; extern BOOL fPrintTickets; extern BOOL fVerbose; enum BindTarget {KDC, KDCDBG}; enum CallType {GETTGS, GETAS}; handle_t BindTo( BindTarget target, LPTSTR pszTransport, LPTSTR pszEndpoint, LPTSTR pszServer ); NTSTATUS CheckPAData( const KERB_ENCRYPTION_KEY& kSessionKey, PKERB_PA_DATA pkdReply, enum CallType type ); ////////////////////////////////////////////////////////////////////////// // // Socket client functions // ////////////////////////////////////////////////////////////////////////// //+------------------------------------------------------------------------- // // Function: KerbInitializeSockets // // Synopsis: // // Effects: // // Arguments: // // Requires: // // Returns: // // Notes: // // //-------------------------------------------------------------------------- #define KERB_KDC_CALL_TIMEOUT 10 void PrintFlags( const KERB_TICKET_FLAGS fFlags ) { #define KerbFlagDef(x) {#x, KERB_TICKET_FLAGS_ ## x} const static struct { char * FlagName; KERB_TICKET_FLAGS Flag; } Flags[] = { KerbFlagDef( forwardable ), KerbFlagDef( forwarded ), KerbFlagDef( proxiable ), KerbFlagDef( proxy ), KerbFlagDef( may_postdate ), KerbFlagDef( postdated ), KerbFlagDef( invalid ), KerbFlagDef( renewable ), KerbFlagDef( initial ), KerbFlagDef( pre_authent ), KerbFlagDef( hw_authent ), KerbFlagDef( reserved ) }; const int cFlags = sizeof( Flags ) / sizeof( Flags[0] ); for (int i=0; ibPAData; CAuthData* padData; for (padData = padlList->FindFirst(Any); padData != NULL; padData = padlList->FindNext(padData, Any)) { switch (padData->adtDataType) { #if 0 case Pac: { printf("\tAuthorizationData (PAC):\n"); CPAC Pac; ULONG cb = Pac.UnMarshal( (PBYTE) padData->abData ); if (cb <= padData->cbData ) { if (fPrintPACs) ::Print( Pac ); fFoundSomething = TRUE; break; } else { printf("PAC didn't unmarshal correctly"); } } #endif default: printf("\tAuthorizationData (Unknown: %d bytes):", padData->cbData ); for (j=0; j < padData->cbData; j++ ) { printf("%x ", padData->abData[j] ); } printf("\n" ); } } if (!fFoundSomething) { printf("\tAuthorizationData (%d) : 0x", kitTicket.kitEncryptPart.pkdAuthorizationData->cbPAData ); for (j=0; j < kitTicket.kitEncryptPart.pkdAuthorizationData->cbPAData; j++ ) { printf("%x ", ((PBYTE)kitTicket.kitEncryptPart.pkdAuthorizationData->bPAData)[j] ); } printf("\n" ); } } #endif } int PrintPAC( PEncryptedData pedPAC, PWCHAR pwzKdcPasswd ) { #ifdef notdef // Decrypt it again to print it out. PEncryptedData pedPacCopy = (PEncryptedData) new BYTE [ SizeOfEncryptedData( pedPAC ) ]; memcpy( pedPacCopy, pedPAC, SizeOfEncryptedData( pedPAC ) ); // // Find the PAC in the mess of credentials // CAuthData * pad = ((CAuthDataList*)pedPacCopy->ctCipher.bMessage)->FindFirst(Pac_2); if (pad == NULL) { printf("GetPAC's return didn't have a PAC in it."); return 1; } PEncryptedData pedRealPac = (PEncryptedData) pad->abData; // // Get the KDC's key, use it to decrypt pedNewPac // // Print out the resulting new pac. // // delete pedNewPac // NTSTATUS sc; UNICODE_STRING ssFoo; KERB_ENCRYPTION_KEY kKey; SRtlInitString( &ssFoo, pwzKdcPasswd ); KerbHashPassword( &ssFoo, KERB_ETYPE_RC4_MD4, &kKey ); sc = KIDecryptData(pedRealPac, &kKey ); if (!NT_SUCCESS(sc)) { printf("Couldn't decrypt PAC second time 0x%X\n", sc ); return(1); } #endif return(0); } NTSTATUS CheckPAData( const KERB_ENCRYPTION_KEY& kSessionKey, PKERB_PA_DATA pkdReply, enum CallType type ) { #ifdef notdef NTSTATUS err = 0; TimeStamp tsKdcTime, tsLocalTime, tsDiff; CAuthData * pad; CAuthDataList * padlList; if (pkdReply == 0) { printf("Nothing in the padata returned.\n"); return(1); } // // This PAData should contain: Time // May contain: address info // May contain: old passwords // padlList = (CAuthDataList*) &pkdReply->bPAData[0]; if (padlList->GetMaxSize() != pkdReply->cbPAData ) { printf("Sizes are wrong for padata.\n"); err = -1; } pad = padlList->FindFirst( Time ); if (pad == NULL) { printf("Time not included in padata."); err = -1; } //sc = KIDecryptData( (PEncryptedData) pad->bData, &(KERB_ENCRYPTION_KEY&)kSessionKey ); //if (FAILED(sc)) //{ // printf("error 0x%X decrypting time.\n", sc ); // err = -1; //} //tsKdcTime = * (PTimeStamp) ((PEncryptedData) pad->abData)->ctCipherText.bMessage; tsKdcTime = * (PTimeStamp) pad->abData; GetCurrentTimeStamp( &tsLocalTime ); if (tsKdcTime > tsLocalTime) tsDiff = tsKdcTime - tsLocalTime; else tsDiff = tsLocalTime - tsKdcTime; if (tsDiff.QuadPart > UInt32x32To64( 10000000ul, 15 ) ) // 15 seconds. { printf("Warning: the time at the KDC is " ); Print( tsDiff ); printf(" different.\n" ); } // // Address info // // // Passwords // #endif return(S_OK); } KERBERR FooGetASTicket( IN PVOID hBinding, IN PWCHAR pwzUserName, IN PWCHAR pwzUserRealm, IN PWCHAR pwzServiceName, IN PWCHAR pwzUserPassword, IN PWCHAR pwzThisWorkstation, OUT PKERB_TICKET pktTicket, OUT PKERB_ENCRYPTED_KDC_REPLY * ReplyBody ) { NTSTATUS Status; KERBERR KerbErr; KERB_ENCRYPTION_KEY kUserKey; KERB_KDC_REQUEST Request; PKERB_KDC_REQUEST_BODY RequestBody = &Request.request_body; PKERB_ENCRYPTED_DATA pedReply = 0; PULONG CryptArray = NULL; ULONG CryptArraySize = 0; LARGE_INTEGER TempTime; KERB_MESSAGE_BUFFER InputMessage; KERB_MESSAGE_BUFFER OutputMessage; UNICODE_STRING ssPass; UNICODE_STRING ssService; UNICODE_STRING ssRealm; UNICODE_STRING ssName; PKERB_KDC_REPLY Reply = NULL; RtlInitUnicodeString( &ssPass, pwzUserPasswd ); KerbHashPassword( &ssPass, KERB_ETYPE_RC4_MD4, &kUserKey ); RtlZeroMemory( &OutputMessage, sizeof(KERB_MESSAGE_BUFFER) ); RtlZeroMemory( &InputMessage, sizeof(KERB_MESSAGE_BUFFER) ); RtlInitUnicodeString( &ssService, pwzServiceName ); RtlInitUnicodeString( &ssRealm, pwzUserRealm ); RtlInitUnicodeString( &ssName, pwzUserName ); // // Build the request // RtlZeroMemory( &Request, sizeof( KERB_KDC_REQUEST ) ); RequestBody->kdc_options = KERB_KDC_OPTIONS_forwardable | KERB_KDC_OPTIONS_proxiable | KERB_KDC_OPTIONS_renewable | KERB_KDC_OPTIONS_renewable_ok; RequestBody->nonce = 3; TempTime.QuadPart = 0; KerbConvertLargeIntToGeneralizedTime( &RequestBody->KERB_KDC_REQUEST_BODY_starttime, NULL, &TempTime ); TempTime.LowPart = 0xffffffff; TempTime.HighPart = 0x7fffffff; KerbConvertLargeIntToGeneralizedTime( &RequestBody->KERB_KDC_REQUEST_BODY_renew_until, NULL, &TempTime ); RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_renew_until_present; TempTime.QuadPart = 0; KerbConvertLargeIntToGeneralizedTime( &RequestBody->endtime, NULL, &TempTime ); // // Build crypt vector. // CDBuildVect( &CryptArraySize, NULL ); CryptArray = new ULONG [ CryptArraySize ]; CDBuildVect( &CryptArraySize, CryptArray ); KerbErr = KerbConvertArrayToCryptList( &RequestBody->encryption_type, CryptArray, CryptArraySize ); if (!KERB_SUCCESS(KerbErr)) { printf("Faield to convert array to crypt list: 0x%x\n",KerbErr); goto Cleanup; } // // BUGBUG: don't build pre-auth data // KerbErr = KerbConvertStringToPrincipalName( &RequestBody->server_name, &ssService ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to convert string to principal name: 0x%x\n",KerbErr); goto Cleanup; } KerbErr = KerbConvertStringToPrincipalName( &RequestBody->KERB_KDC_REQUEST_BODY_client_name, &ssName ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to convert string to principal name: 0x%x\n",KerbErr); goto Cleanup; } RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_client_name_present; KerbErr = KerbConvertUnicodeStringToRealm( &RequestBody->realm, &ssRealm ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to convert unicde string to realm: 0x%x\n",KerbErr); goto Cleanup; } Request.version = KERBEROS_VERSION; Request.message_type = KRB_AS_REQ; KerbErr = KerbPackKdcRequest( &Request, &InputMessage.BufferSize, &InputMessage.Buffer ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to pack KDC request: 0x%x\n",KerbErr); goto Cleanup; } Status = KerbCallKdc( hBinding, &InputMessage, &OutputMessage ); KerbErr = (KERBERR) Status; if (!KERB_SUCCESS(KerbErr)) { printf("KerbCallKdc failed: 0x%x\n",Status); goto Cleanup; } KerbErr = KerbUnpackKdcReply( OutputMessage.Buffer, OutputMessage.BufferSize, &Reply ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to unpack KDC reply: 0x%x\n",KerbErr); goto Cleanup; } KerbErr = KerbUnpackKdcReplyBody( &Reply->encrypted_part, &kUserKey, ReplyBody ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to unpack KDC reply body: 0x%x\n",KerbErr); goto Cleanup; } #ifdef notdef sc = CheckPAData( pkrReply->kSessionKey, pkdReply, GETAS ); if (FAILED(sc)) { printf("Problem with PAData returned: 0x%X\n", sc ); return(1); } #endif *pktTicket = Reply->ticket; Cleanup: // // BUGBUG: memory leak here // return(KerbErr); } KERBERR FooGetTGSTicket( IN PVOID hBinding, IN PWCHAR pwzUserName, IN PWCHAR pwzUserRealm, IN PWCHAR pwzServiceName, IN PKERB_TICKET pktTGTicket, IN PKERB_ENCRYPTED_KDC_REPLY pkrTGTReply, IN ULONG AuthDataSize, IN PUCHAR AuthData, IN BOOLEAN Renew, OUT PKERB_TICKET pktTicket, OUT PKERB_ENCRYPTED_KDC_REPLY * ReplyBody ) { KERB_KDC_REQUEST Request; PKERB_KDC_REQUEST_BODY RequestBody = &Request.request_body; UNICODE_STRING ssService; UNICODE_STRING UserName; UNICODE_STRING UserRealm; KERBERR KerbErr; KERB_PA_DATA_LIST PaData; PULONG CryptArray = NULL; ULONG CryptArraySize = 0; LARGE_INTEGER TempTime; KERB_MESSAGE_BUFFER InputMessage; KERB_MESSAGE_BUFFER OutputMessage; PKERB_KDC_REPLY Reply = NULL; KERB_ENCRYPTED_DATA EncAuthData; RtlZeroMemory( &EncAuthData, sizeof(KERB_ENCRYPTED_DATA) ); RtlInitUnicodeString( &ssService, pwzServiceName ); RtlInitUnicodeString( &UserName, pwzUserName ); RtlInitUnicodeString( &UserRealm, pwzUserRealm ); // // Build the request // RtlZeroMemory( &Request, sizeof( KERB_KDC_REQUEST ) ); RequestBody->kdc_options = KERB_KDC_OPTIONS_forwardable | KERB_KDC_OPTIONS_proxiable | KERB_KDC_OPTIONS_renewable | KERB_KDC_OPTIONS_renewable_ok; if (Renew) { RequestBody->kdc_options |= KERB_KDC_OPTIONS_renew; } RequestBody->nonce = 4; // // Build an AP request inside an encrypted data structure. // PaData.next = NULL; PaData.value.preauth_data_type = PA_TGS_REQ; KerbErr = KerbCreateApRequest( &UserName, &UserRealm, &pkrTGTReply->session_key, 5, // nonce pktTGTicket, 0, // AP options NULL, // gss checksum (PULONG) &PaData.value.preauth_data.length, &PaData.value.preauth_data.value ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to create AP request: 0x%x\n",KerbErr); goto Cleanup; } Request.KERB_KDC_REQUEST_preauth_data = &PaData; Request.bit_mask |= KERB_KDC_REQUEST_preauth_data_present; // // Build crypt vector. // CDBuildVect( &CryptArraySize, NULL ); CryptArray = new ULONG [ CryptArraySize ]; CDBuildVect( &CryptArraySize, CryptArray ); KerbErr = KerbConvertArrayToCryptList( &RequestBody->encryption_type, CryptArray, CryptArraySize ); if (!KERB_SUCCESS(KerbErr)) { printf("Faield to convert array to crypt list: 0x%x\n",KerbErr); goto Cleanup; } KerbErr = KerbConvertStringToPrincipalName( &RequestBody->KERB_KDC_REQUEST_BODY_client_name, &UserName ); if (!KERB_SUCCESS(KerbErr)) { goto Cleanup; } RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_client_name_present; KerbErr = KerbConvertUnicodeStringToRealm( &RequestBody->realm, &UserRealm ); if (!KERB_SUCCESS(KerbErr)) { goto Cleanup; } KerbErr = KerbConvertStringToPrincipalName( &RequestBody->server_name, &ssService ); if (!KERB_SUCCESS(KerbErr)) { goto Cleanup; } TempTime.QuadPart = 0; KerbConvertLargeIntToGeneralizedTime( &RequestBody->KERB_KDC_REQUEST_BODY_starttime, NULL, &TempTime ); TempTime.LowPart = 0xffffffff; TempTime.HighPart = 0x7fffffff; KerbConvertLargeIntToGeneralizedTime( &RequestBody->KERB_KDC_REQUEST_BODY_renew_until, NULL, &TempTime ); RequestBody->bit_mask |= KERB_KDC_REQUEST_BODY_renew_until_present; TempTime.LowPart = 0xffffffff; TempTime.HighPart = 0x7fffffff; KerbConvertLargeIntToGeneralizedTime( &RequestBody->endtime, NULL, &TempTime ); if (ARGUMENT_PRESENT(AuthData)) { ULONG EncryptionOverhead; KerbErr = KerbGetEncryptionOverhead( pktTGTicket->encrypted_part.encryption_type, &EncryptionOverhead, NULL // BUGBUG ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to get encryption overhead: 0x%x\n",KerbErr); goto Cleanup; } EncAuthData.cipher_text.length = AuthDataSize + EncryptionOverhead; EncAuthData.cipher_text.value = (PUCHAR) MIDL_user_allocate(EncAuthData.cipher_text.length); if (EncAuthData.cipher_text.value == NULL) { KerbErr = KRB_ERR_GENERIC; goto Cleanup; } KerbErr = KerbEncryptData( &EncAuthData, AuthDataSize, AuthData, pktTGTicket->encrypted_part.encryption_type, &pkrTGTReply->session_key ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to encrypt pac auth data: 0x%x\n",KerbErr); goto Cleanup; } RequestBody->enc_authorization_data = EncAuthData; RequestBody->bit_mask |= enc_authorization_data_present; } Request.version = KERBEROS_VERSION; Request.message_type = KRB_TGS_REQ; KerbErr = KerbPackKdcRequest( &Request, &InputMessage.BufferSize, &InputMessage.Buffer ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to pack KDC request: 0x%x\n",KerbErr); goto Cleanup; } // // Get the ticket. // OutputMessage.Buffer = NULL; OutputMessage.BufferSize = 0; KerbErr = (KERBERR) KerbCallKdc( hBinding, &InputMessage, &OutputMessage ); if (!KERB_SUCCESS(KerbErr)) { printf("KerbCallKdc failed: 0x%x\n",KerbErr); goto Cleanup; } KerbErr = KerbUnpackKdcReply( OutputMessage.Buffer, OutputMessage.BufferSize, &Reply ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to unpack KDC reply: 0x%x\n",KerbErr); goto Cleanup; } KerbErr = KerbUnpackKdcReplyBody( &Reply->encrypted_part, &pkrTGTReply->session_key, ReplyBody ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to unpack KDC reply body: 0x%x\n",KerbErr); goto Cleanup; } #ifdef notdef sc = CheckPAData( pkrReply->kSessionKey, pkdReply, GETAS ); if (FAILED(sc)) { printf("Problem with PAData returned: 0x%X\n", sc ); return(1); } #endif *pktTicket = Reply->ticket; Cleanup: if (EncAuthData.cipher_text.value != NULL) { MIDL_user_free(EncAuthData.cipher_text.value); } return(KerbErr); } KERBERR FooGetPAC( PVOID hBinding, LPWSTR pwzUserName, LPWSTR pwzUserRealm, PKERB_TICKET PrivSvrTicket, PKERB_ENCRYPTED_KDC_REPLY PrivSvrReply, PULONG AuthDataSize, PUCHAR * PackedAuthData ) { KERBERR KerbErr = KDC_ERR_NONE; UNICODE_STRING UserName; UNICODE_STRING UserRealm; KERB_MESSAGE_BUFFER RequestMessage; KERB_MESSAGE_BUFFER ReplyMessage; PKERB_ENCRYPTED_DATA EncryptedPacMessage = NULL; ReplyMessage.Buffer = NULL; ReplyMessage.BufferSize = 0; RtlInitUnicodeString( &UserName, pwzUserName ); RtlInitUnicodeString( &UserRealm, pwzUserRealm ); KerbErr = KerbCreateApRequest( &UserName, &UserRealm, &PrivSvrReply->session_key, 6, // nonce PrivSvrTicket, 0, // AP options NULL, // gss checksum &RequestMessage.BufferSize, &RequestMessage.Buffer ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to create AP request for PAC: 0x%x\n",KerbErr); goto Cleanup; } #ifdef notdef KerbErr = (KERBERR) GetPAC( hBinding, &RequestMessage, &ReplyMessage ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to get pac : 0x%x\n",KerbErr); goto Cleanup; } #endif // // Now decode pac // // // First unpack message into an encrypted data structure // KerbErr = KerbUnpackEncryptedData( ReplyMessage.Buffer, ReplyMessage.BufferSize, &EncryptedPacMessage ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to unpack enc pac data: 0x%x\n",KerbErr); goto Cleanup; } // // Now decrypt into a packed authorization data // *PackedAuthData = (PUCHAR) MIDL_user_allocate(EncryptedPacMessage->cipher_text.length); if (*PackedAuthData == NULL) { KerbErr = KRB_ERR_GENERIC; goto Cleanup; } KerbErr = KerbDecryptData( EncryptedPacMessage, &PrivSvrReply->session_key, AuthDataSize, *PackedAuthData ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to decrypt pac auth data: 0x%x\n",KerbErr); goto Cleanup; } Cleanup: if (RequestMessage.Buffer != NULL) { MIDL_user_free(RequestMessage.Buffer); } if (EncryptedPacMessage != NULL) { MIDL_user_free(EncryptedPacMessage); } if (ReplyMessage.Buffer != NULL) { MIDL_user_free(ReplyMessage.Buffer); } return(KerbErr); } KERBERR FooCheckTicket( LPWSTR pwzUserName, LPWSTR pwzUserRealm, LPWSTR pwzServiceName, LPWSTR pwzServicePassword, PKERB_TICKET ServiceTicket, PKERB_ENCRYPTED_KDC_REPLY ServiceReply ) { KERBERR KerbErr = KDC_ERR_NONE; UNICODE_STRING UserName; UNICODE_STRING UserRealm; UNICODE_STRING ServiceName; UNICODE_STRING ServicePassword; ULONG AuthDataSize; ULONG ApRequestSize; PUCHAR ApRequestMessage = NULL; PKERB_AP_REQUEST ApRequest = NULL; KERB_ENCRYPTION_KEY ServiceKey; LARGE_INTEGER tsFudgeFactor; PKERB_ENCRYPTED_TICKET EncryptPart = NULL; PKERB_AUTHENTICATOR Authenticator = NULL; KERB_ENCRYPTION_KEY SessionKey; BOOLEAN UseSubKey; tsFudgeFactor.QuadPart = 300 * (LONGLONG) 10000000; CAuthenticatorList Authenticators( tsFudgeFactor ); if (!NT_SUCCESS(Authenticators->Init()) { return KERB_ERR_GENERIC; } RtlInitUnicodeString( &UserName, pwzUserName ); RtlInitUnicodeString( &UserRealm, pwzUserRealm ); RtlInitUnicodeString( &ServiceName, pwzServiceName ); RtlInitUnicodeString( &ServicePassword, pwzServicePassword ); KerbErr = KerbHashPassword( &ServicePassword, KERB_ETYPE_RC4_MD4, &ServiceKey ); if (!KERB_SUCCESS(KerbErr)) { goto Cleanup; } KerbErr = KerbCreateApRequest( &UserName, &UserRealm, &ServiceReply->session_key, 7, // nonce ServiceTicket, 0, // AP options NULL, // gss checksum &ApRequestSize, &ApRequestMessage ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to create AP request for PAC: 0x%x\n",KerbErr); goto Cleanup; } KerbErr = KerbUnpackApRequest( ApRequestMessage, ApRequestSize, &ApRequest ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to unpack ap request: 0x%x\n",KerbErr); goto Cleanup; } KerbErr = KerbCheckTicket( &ApRequest->ticket, &ApRequest->authenticator, &ServiceKey, Authenticators, &tsFudgeFactor, &ServiceName, &EncryptPart, &Authenticator, &SessionKey, &UseSubKey ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed to check ticket: 0x%x\n",KerbErr); goto Cleanup; } Cleanup: if (ApRequest != NULL) { MIDL_user_free(ApRequest); } KerbFreeTicket(EncryptPart); KerbFreeAuthenticator(Authenticator); if (ApRequestMessage != NULL) { MIDL_user_free(ApRequestMessage); } return(KerbErr); } int TicketTests() { int ret = 0; ULONG cbAuthen = 0; NTSTATUS sc; WCHAR ServiceName[100]; UNICODE_STRING KdcName; PVOID SocketHandle = NULL; wcscpy( ServiceName, pwzRealm ); wcscat(ServiceName,L"\\"); wcscat(ServiceName,pwzUserName); sc = KerbInitializeSockets( 0x0101, 5 ); if (!NT_SUCCESS(sc)) { printf("Failed to initialize sockets: 0x%x\n",sc); return((int) sc); } RtlInitUnicodeString( &KdcName, pwzAddress ); sc = KerbBindSocket( &KdcName, &SocketHandle ); if (!NT_SUCCESS(sc)) { printf("KerbSocketBind failed: %0x%x\n",sc); return((int) sc); } __try { KERB_TICKET ktASTicket; KERB_TICKET ktPSTicket; KERB_TICKET ktCTGTicket; KERB_TICKET ktServTicket; KERB_TICKET ktRenewServTicket; PKERB_ENCRYPTED_KDC_REPLY pkrASReply = NULL; PKERB_ENCRYPTED_KDC_REPLY pkrPSReply = NULL; PKERB_ENCRYPTED_KDC_REPLY pkrCTGTReply = NULL; PKERB_ENCRYPTED_KDC_REPLY pkrServReply = NULL; PKERB_ENCRYPTED_KDC_REPLY pkrRenewServReply = NULL; ULONG AuthDataSize = 0; PUCHAR AuthData = NULL; LARGE_INTEGER tsPing; KERBERR KerbErr; ULONG PingFlags = 0; handle_t hKDC = BindTo( KDC, pwzTransport, pwzEndPoint, pwzAddress ); if (hKDC == 0 || hKDC == (handle_t)-1 ) { printf("Error binding, quitting.\n" ); ret = (1); goto Done; } sc = KDCPing( hKDC, &PingFlags, &tsPing ); if (sc != 0) { printf("Error %d (0x%X) from KdcPing()\n", sc ); ret = (1); goto Done; } if (fGetAS) { KerbErr = FooGetASTicket( SocketHandle, pwzUserName, pwzRealm, pwzKDC, pwzUserPasswd, pwzClientAddress, &ktASTicket, &pkrASReply ); if (!KERB_SUCCESS(KerbErr)) { goto Done; } if (fPrintTickets) { printf("Initial TGT:\n" ); PrintTicket( &ktASTicket, pwzKdcPasswd ); } } if (fGetTGS) { KerbErr = FooGetTGSTicket( SocketHandle, // hBinding pwzUserName, // pwzUserName pwzRealm, // pwzUserRealm pwzPrivSvr, // pwzServiceName &ktASTicket, // ktTGTicket pkrASReply, // krTGTReply 0, NULL, // no authorization FALSE, // don't renew &ktPSTicket, // ppktTicket &pkrPSReply ); // pkrReply if (!KERB_SUCCESS(KerbErr)) { goto Done; } if (fPrintTickets) { printf("Ticket to PS:\n" ); PrintTicket( &ktPSTicket, pwzPSPasswd ); } } #ifdef notdef if (fGetPAC) { // // Get the PAC. // KerbErr = FooGetPAC( SocketHandle, pwzUserName, pwzRealm, &ktPSTicket, pkrPSReply, &AuthDataSize, &AuthData ); if (!KERB_SUCCESS(KerbErr)) { printf("FooGetPAC() == 0x%X\n", KerbErr ); goto Done; } } if (fGetCTGT) { KerbErr = FooGetTGSTicket( SocketHandle, // hBinding pwzUserName, // pwzUserName pwzRealm, // pwzUserRealm pwzKDC, // pwzServiceName &ktASTicket, // ktTGTicket pkrASReply, // krTGTReply AuthDataSize, AuthData, FALSE, // don't renew &ktCTGTicket, // ppktTicket &pkrCTGTReply ); // pkrReply if (!KERB_SUCCESS(KerbErr)) { printf("Failed to get TGT: 0x%x\n",KerbErr); goto Done; } } #endif // notdef if (fGetServiceTkt) { KerbErr = FooGetTGSTicket( SocketHandle, // hBinding pwzUserName, // pwzUserName pwzRealm, // pwzUserRealm ServiceName, // pwzServiceName &ktASTicket, // ktTGTicket pkrASReply, // krTGTReply 0, NULL, // no auth data FALSE, // don't renew &ktServTicket, // ppktTicket &pkrServReply ); // pkrReply if (!KERB_SUCCESS(KerbErr)) { printf("Faield to get ticket to service: 0x%x\n",KerbErr); goto Done; } // // Now check the ticket. // KerbErr = FooCheckTicket( pwzUserName, pwzRealm, ServiceName, // service name pwzUserPasswd, /// service password &ktServTicket, pkrServReply ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed tocheck service ticket: 0x%x\n",KerbErr); goto Done; } } if (fRenewSvc) { KerbErr = FooGetTGSTicket( SocketHandle, // hBinding pwzUserName, // pwzUserName pwzRealm, // pwzUserRealm ServiceName, // pwzServiceName &ktServTicket, // ktTGTicket pkrServReply, // krTGTReply 0, NULL, // no auth data TRUE, &ktRenewServTicket, // ppktTicket &pkrRenewServReply ); // pkrReply if (!KERB_SUCCESS(KerbErr)) { printf("Faield to get ticket to service: 0x%x\n",KerbErr); goto Done; } // // Now check the ticket. // KerbErr = FooCheckTicket( pwzUserName, pwzRealm, ServiceName, // service name pwzUserPasswd, /// service password &ktServTicket, pkrServReply ); if (!KERB_SUCCESS(KerbErr)) { printf("Failed tocheck service ticket: 0x%x\n",KerbErr); goto Done; } } Done: ; } __except ( EXCEPTION_EXECUTE_HANDLER ) { printf("Exception 0x%x (%d) in ticktest.\n", GetExceptionCode(), GetExceptionCode() ); ret = 5; } if (SocketHandle != NULL) { closesocket((SOCKET) SocketHandle); } return(ret); }