00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "tlsschannel.h"
00014
00015 #ifdef HAVE_WINTLS
00016
00017 #include <stdio.h>
00018 #include <iostream>
00019
00020 namespace gloox
00021 {
00022 SChannel::SChannel( TLSHandler* th, const std::string& server )
00023 : TLSBase( th, server ), m_cleanedup( true )
00024 {
00025
00026 }
00027
00028 SChannel::~SChannel()
00029 {
00030 m_handler = 0;
00031 cleanup();
00032
00033 }
00034
00035 bool SChannel::encrypt( const std::string& data )
00036 {
00037 if( !m_handler )
00038 return false;
00039
00040
00041 std::string data_copy = data;
00042
00043 SecBuffer buffer[4];
00044 SecBufferDesc buffer_desc;
00045 DWORD cbIoBufferLength = m_sizes.cbHeader + m_sizes.cbMaximumMessage + m_sizes.cbTrailer;
00046
00047 PBYTE e_iobuffer = static_cast<PBYTE>( LocalAlloc( LMEM_FIXED, cbIoBufferLength ) );
00048
00049 if( e_iobuffer == NULL )
00050 {
00051
00052 cleanup();
00053 if( !m_secure )
00054 m_handler->handleHandshakeResult( this, false, m_certInfo );
00055 return false;
00056 }
00057 PBYTE e_message = e_iobuffer + m_sizes.cbHeader;
00058 do
00059 {
00060 const int size = data_copy.size() > m_sizes.cbMaximumMessage
00061 ? m_sizes.cbMaximumMessage
00062 : data_copy.size();
00063 memcpy( e_message, data_copy.data(), size );
00064 if( data_copy.size() > m_sizes.cbMaximumMessage )
00065 data_copy.erase( 0, m_sizes.cbMaximumMessage );
00066 else
00067 data_copy = "";
00068
00069 buffer[0].pvBuffer = e_iobuffer;
00070 buffer[0].cbBuffer = m_sizes.cbHeader;
00071 buffer[0].BufferType = SECBUFFER_STREAM_HEADER;
00072
00073 buffer[1].pvBuffer = e_message;
00074 buffer[1].cbBuffer = size;
00075 buffer[1].BufferType = SECBUFFER_DATA;
00076
00077 buffer[2].pvBuffer = static_cast<char*>(buffer[1].pvBuffer) + buffer[1].cbBuffer;
00078 buffer[2].cbBuffer = m_sizes.cbTrailer;
00079 buffer[2].BufferType = SECBUFFER_STREAM_TRAILER;
00080
00081 buffer[3].BufferType = SECBUFFER_EMPTY;
00082
00083 buffer_desc.ulVersion = SECBUFFER_VERSION;
00084 buffer_desc.cBuffers = 4;
00085 buffer_desc.pBuffers = buffer;
00086
00087 SECURITY_STATUS e_status = EncryptMessage( &m_context, 0, &buffer_desc, 0 );
00088 if( SUCCEEDED( e_status ) )
00089 {
00090 std::string encrypted( reinterpret_cast<const char*>(e_iobuffer),
00091 buffer[0].cbBuffer + buffer[1].cbBuffer + buffer[2].cbBuffer );
00092 m_handler->handleEncryptedData( this, encrypted );
00093
00094 }
00095 else
00096 {
00097 LocalFree( e_iobuffer );
00098 cleanup();
00099 if( !m_secure )
00100 m_handler->handleHandshakeResult( this, false, m_certInfo );
00101 return false;
00102 }
00103 }
00104 while( data_copy.size() > 0 );
00105 LocalFree( e_iobuffer );
00106 return true;
00107 }
00108
00109 int SChannel::decrypt( const std::string& data )
00110 {
00111
00112 if( !m_handler )
00113 return 0;
00114
00115
00116 if( m_secure )
00117 {
00118 m_buffer += data;
00119
00120 SecBuffer buffer[4];
00121 SecBufferDesc buffer_desc;
00122 DWORD cbIoBufferLength = m_sizes.cbHeader + m_sizes.cbMaximumMessage + m_sizes.cbTrailer;
00123
00124 PBYTE e_iobuffer = static_cast<PBYTE>( LocalAlloc( LMEM_FIXED, cbIoBufferLength ) );
00125 if( e_iobuffer == NULL )
00126 {
00127
00128 cleanup();
00129 if( !m_secure )
00130 m_handler->handleHandshakeResult( this, false, m_certInfo );
00131 return 0;
00132 }
00133 SECURITY_STATUS e_status;
00134
00135
00136 do
00137 {
00138 memcpy( e_iobuffer, m_buffer.data(), m_buffer.size() >
00139 cbIoBufferLength ? cbIoBufferLength : m_buffer.size() );
00140
00141 buffer[0].pvBuffer = e_iobuffer;
00142 buffer[0].cbBuffer = m_buffer.size() > cbIoBufferLength ? cbIoBufferLength : m_buffer.size();
00143 buffer[0].BufferType = SECBUFFER_DATA;
00144 buffer[1].cbBuffer = buffer[2].cbBuffer = buffer[3].cbBuffer = 0;
00145 buffer[1].BufferType = buffer[2].BufferType = buffer[3].BufferType = SECBUFFER_EMPTY;
00146
00147 buffer_desc.ulVersion = SECBUFFER_VERSION;
00148 buffer_desc.cBuffers = 4;
00149 buffer_desc.pBuffers = buffer;
00150
00151 unsigned long processed_data = buffer[0].cbBuffer;
00152 e_status = DecryptMessage( &m_context, &buffer_desc, 0, 0 );
00153
00154
00155
00156
00157
00158
00159 SecBuffer* pDataBuffer = NULL;
00160 SecBuffer* pExtraBuffer = NULL;
00161 for( int i = 1; i < 4; i++ )
00162 {
00163 if( pDataBuffer == NULL && buffer[i].BufferType == SECBUFFER_DATA )
00164 {
00165 pDataBuffer = &buffer[i];
00166
00167 }
00168 if( pExtraBuffer == NULL && buffer[i].BufferType == SECBUFFER_EXTRA )
00169 {
00170 pExtraBuffer = &buffer[i];
00171 }
00172 }
00173 if( e_status == SEC_E_OK )
00174 {
00175 std::string decrypted( reinterpret_cast<const char*>( pDataBuffer->pvBuffer ),
00176 pDataBuffer->cbBuffer );
00177 m_handler->handleDecryptedData( this, decrypted );
00178 if( pExtraBuffer == NULL )
00179 {
00180 m_buffer.erase( 0, processed_data );
00181 }
00182 else
00183 {
00184
00185 m_buffer.erase( 0, m_buffer.size() - pExtraBuffer->cbBuffer );
00186
00187 }
00188 }
00189 else if( e_status == SEC_E_INCOMPLETE_MESSAGE )
00190 {
00191 break;
00192 }
00193 else
00194 {
00195
00196 cleanup();
00197 if( !m_secure )
00198 m_handler->handleHandshakeResult( this, false, m_certInfo );
00199 break;
00200 }
00201 }
00202 while( m_buffer.size() != 0 );
00203 LocalFree( e_iobuffer );
00204 }
00205 else
00206 {
00207 handshakeStage( data );
00208 }
00209
00210 return 0;
00211 }
00212
00213 void SChannel::cleanup()
00214 {
00215 if( !m_cleanedup )
00216 {
00217 m_valid = false;
00218 m_secure = false;
00219 DeleteSecurityContext( &m_context );
00220 FreeCredentialsHandle( &m_credHandle );
00221 }
00222 }
00223
00224 bool SChannel::handshake()
00225 {
00226 if( !m_handler )
00227 return false;
00228
00229
00230 SECURITY_STATUS error;
00231 ULONG return_flags;
00232 TimeStamp t;
00233 SecBuffer obuf[1];
00234 SecBufferDesc obufs;
00235 SCHANNEL_CRED tlscred;
00236 ULONG request = ISC_REQ_ALLOCATE_MEMORY
00237 | ISC_REQ_CONFIDENTIALITY
00238 | ISC_REQ_EXTENDED_ERROR
00239 | ISC_REQ_INTEGRITY
00240 | ISC_REQ_REPLAY_DETECT
00241 | ISC_REQ_SEQUENCE_DETECT
00242 | ISC_REQ_STREAM
00243 | ISC_REQ_MANUAL_CRED_VALIDATION;
00244
00245
00246 memset( &tlscred, 0, sizeof( SCHANNEL_CRED ) );
00247 tlscred.dwVersion = SCHANNEL_CRED_VERSION;
00248 tlscred.grbitEnabledProtocols = SP_PROT_TLS1;
00249
00250 error = AcquireCredentialsHandle( 0,
00251 UNISP_NAME,
00252 SECPKG_CRED_OUTBOUND,
00253 0,
00254 &tlscred,
00255 0,
00256 0,
00257 &m_credHandle,
00258 &t );
00259
00260 if( error != SEC_E_OK )
00261 {
00262 cleanup();
00263 m_handler->handleHandshakeResult( this, false, m_certInfo );
00264 return false;
00265 }
00266 else
00267 {
00268
00269 obuf[0].cbBuffer = 0;
00270 obuf[0].pvBuffer = 0;
00271 obuf[0].BufferType = SECBUFFER_TOKEN;
00272
00273 obufs.ulVersion = SECBUFFER_VERSION;
00274 obufs.cBuffers = 1;
00275 obufs.pBuffers = obuf;
00276
00277 SEC_CHAR* hname = const_cast<char*>( m_server.c_str() );
00278
00279 error = InitializeSecurityContext( &m_credHandle,
00280 0,
00281 hname,
00282 request,
00283 0,
00284 SECURITY_NETWORK_DREP,
00285 0,
00286 0,
00287 &m_context,
00288 &obufs,
00289 &return_flags,
00290 NULL );
00291
00292
00293 if( error == SEC_I_CONTINUE_NEEDED )
00294 {
00295 m_cleanedup = false;
00296
00297 std::string senddata( static_cast<char*>(obuf[0].pvBuffer), obuf[0].cbBuffer );
00298 FreeContextBuffer( obuf[0].pvBuffer );
00299 m_handler->handleEncryptedData( this, senddata );
00300 return true;
00301 }
00302 else
00303 {
00304 cleanup();
00305 m_handler->handleHandshakeResult( this, false, m_certInfo );
00306 return false;
00307 }
00308 }
00309 return true;
00310 }
00311
00312 void SChannel::handshakeStage( const std::string& data )
00313 {
00314
00315 m_buffer += data;
00316
00317 SECURITY_STATUS error;
00318 ULONG a;
00319 TimeStamp t;
00320 SecBuffer ibuf[2], obuf[1];
00321 SecBufferDesc ibufs, obufs;
00322 ULONG request = ISC_REQ_ALLOCATE_MEMORY
00323 | ISC_REQ_CONFIDENTIALITY
00324 | ISC_REQ_EXTENDED_ERROR
00325 | ISC_REQ_INTEGRITY
00326 | ISC_REQ_REPLAY_DETECT
00327 | ISC_REQ_SEQUENCE_DETECT
00328 | ISC_REQ_STREAM
00329 | ISC_REQ_MANUAL_CRED_VALIDATION;
00330
00331 SEC_CHAR* hname = const_cast<char*>( m_server.c_str() );
00332
00333 do
00334 {
00335
00336 ibuf[0].cbBuffer = m_buffer.size();
00337 ibuf[0].pvBuffer = static_cast<void*>( const_cast<char*>( m_buffer.c_str() ) );
00338
00339 ibuf[1].cbBuffer = 0;
00340 ibuf[1].pvBuffer = 0;
00341 obuf[0].cbBuffer = 0;
00342 obuf[0].pvBuffer = 0;
00343
00344 ibuf[0].BufferType = SECBUFFER_TOKEN;
00345 ibuf[1].BufferType = SECBUFFER_EMPTY;
00346 obuf[0].BufferType = SECBUFFER_EMPTY;
00347
00348 ibufs.ulVersion = obufs.ulVersion = SECBUFFER_VERSION;
00349 ibufs.cBuffers = 2;
00350 obufs.cBuffers = 1;
00351 ibufs.pBuffers = ibuf;
00352 obufs.pBuffers = obuf;
00353
00354
00355
00356
00357
00358
00359
00360
00361 error = InitializeSecurityContext( &m_credHandle,
00362 &m_context,
00363 hname,
00364 request,
00365 0,
00366 0,
00367 &ibufs,
00368 0,
00369 0,
00370 &obufs,
00371 &a,
00372 &t );
00373
00374 if( error == SEC_E_OK )
00375 {
00376
00377 if( ibuf[1].BufferType == SECBUFFER_EXTRA )
00378 {
00379 m_buffer.erase( 0, m_buffer.size() - ibuf[1].cbBuffer );
00380 }
00381 else
00382 {
00383 m_buffer = "";
00384 }
00385 setSizes();
00386 setCertinfos();
00387
00388 m_secure = true;
00389 m_handler->handleHandshakeResult( this, true, m_certInfo );
00390 break;
00391 }
00392 else if( error == SEC_I_CONTINUE_NEEDED )
00393 {
00394
00395
00396
00397
00398
00399
00400
00401 if( obuf[0].cbBuffer != 0 && obuf[0].pvBuffer != NULL )
00402 {
00403 std::string senddata( static_cast<char*>(obuf[0].pvBuffer), obuf[0].cbBuffer );
00404 FreeContextBuffer( obuf[0].pvBuffer );
00405 m_handler->handleEncryptedData( this, senddata );
00406 }
00407
00408 if( ibuf[1].BufferType == SECBUFFER_EXTRA )
00409 {
00410 m_buffer.erase( 0, m_buffer.size() - ibuf[1].cbBuffer );
00411 }
00412 else
00413 {
00414 m_buffer = "";
00415 }
00416 return;
00417 }
00418 else if( error == SEC_I_INCOMPLETE_CREDENTIALS )
00419 {
00420 handshakeStage( "" );
00421 }
00422 else if( error == SEC_E_INCOMPLETE_MESSAGE )
00423 {
00424 break;
00425 }
00426 else
00427 {
00428 cleanup();
00429 m_handler->handleHandshakeResult( this, false, m_certInfo );
00430 break;
00431 }
00432 }
00433 while( true );
00434 }
00435
00436 void SChannel::setCACerts( const StringList& cacerts ) {}
00437
00438 void SChannel::setClientCert( const std::string& clientKey, const std::string& clientCerts ) {}
00439
00440 void SChannel::setSizes()
00441 {
00442 if( QueryContextAttributes( &m_context, SECPKG_ATTR_STREAM_SIZES, &m_sizes ) == SEC_E_OK )
00443 {
00444
00445 }
00446 else
00447 {
00448
00449 cleanup();
00450 m_handler->handleHandshakeResult( this, false, m_certInfo );
00451 }
00452 }
00453
00454 int SChannel::filetime2int( FILETIME t )
00455 {
00456 SYSTEMTIME stUTC;
00457 FileTimeToSystemTime(&t, &stUTC);
00458 std::tm ts;
00459 ts.tm_year = stUTC.wYear - 1900;
00460 ts.tm_mon = stUTC.wMonth - 1;
00461 ts.tm_mday = stUTC.wDay;
00462 ts.tm_hour = stUTC.wHour;
00463 ts.tm_min = stUTC.wMinute;
00464 ts.tm_sec = stUTC.wSecond;
00465
00466 int unixtime;
00467 if ( (unixtime = mktime(&ts)) == -1 )
00468 unixtime = 0;
00469 return unixtime;
00470 }
00471
00472 void SChannel::validateCert()
00473 {
00474 bool valid = false;
00475 HTTPSPolicyCallbackData policyHTTPS;
00476 CERT_CHAIN_POLICY_PARA policyParameter;
00477 CERT_CHAIN_POLICY_STATUS policyStatus;
00478
00479 PCCERT_CONTEXT remoteCertContext = NULL;
00480 PCCERT_CHAIN_CONTEXT chainContext = NULL;
00481 CERT_CHAIN_PARA chainParameter;
00482 PSTR serverName = const_cast<char*>( m_server.c_str() );
00483
00484 PWSTR uServerName = NULL;
00485 DWORD csizeServerName;
00486
00487 LPSTR Usages[] = {
00488 szOID_PKIX_KP_SERVER_AUTH,
00489 szOID_SERVER_GATED_CRYPTO,
00490 szOID_SGC_NETSCAPE
00491 };
00492 DWORD cUsages = sizeof( Usages ) / sizeof( LPSTR );
00493
00494 do
00495 {
00496
00497 if( QueryContextAttributes( &m_context, SECPKG_ATTR_REMOTE_CERT_CONTEXT,
00498 (PVOID)&remoteCertContext ) != SEC_E_OK )
00499 {
00500
00501
00502 break;
00503 }
00504
00505
00506
00507 csizeServerName = MultiByteToWideChar( CP_ACP, 0, serverName, -1, NULL, 0 );
00508 uServerName = reinterpret_cast<WCHAR *>( LocalAlloc( LMEM_FIXED,
00509 csizeServerName * sizeof( WCHAR ) ) );
00510 if( uServerName == NULL )
00511 {
00512
00513 break;
00514 }
00515
00516
00517 csizeServerName = MultiByteToWideChar( CP_ACP, 0, serverName, -1, uServerName, csizeServerName );
00518 if( csizeServerName == 0 )
00519 {
00520
00521 break;
00522 }
00523
00524
00525 ZeroMemory( &chainParameter, sizeof( chainParameter ) );
00526 chainParameter.cbSize = sizeof( chainParameter );
00527 chainParameter.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR;
00528 chainParameter.RequestedUsage.Usage.cUsageIdentifier = cUsages;
00529 chainParameter.RequestedUsage.Usage.rgpszUsageIdentifier = Usages;
00530
00531 if( !CertGetCertificateChain( NULL, remoteCertContext, NULL, remoteCertContext->hCertStore,
00532 &chainParameter, 0, NULL, &chainContext ) )
00533 {
00534 DWORD status = GetLastError();
00535
00536 break;
00537 }
00538
00539
00540 ZeroMemory( &policyHTTPS, sizeof( HTTPSPolicyCallbackData ) );
00541 policyHTTPS.cbStruct = sizeof( HTTPSPolicyCallbackData );
00542 policyHTTPS.dwAuthType = AUTHTYPE_SERVER;
00543 policyHTTPS.fdwChecks = 0;
00544 policyHTTPS.pwszServerName = uServerName;
00545
00546 memset( &policyParameter, 0, sizeof( policyParameter ) );
00547 policyParameter.cbSize = sizeof( policyParameter );
00548 policyParameter.pvExtraPolicyPara = &policyHTTPS;
00549
00550 memset( &policyStatus, 0, sizeof( policyStatus ) );
00551 policyStatus.cbSize = sizeof( policyStatus );
00552
00553 if( !CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_SSL, chainContext, &policyParameter,
00554 &policyStatus ) )
00555 {
00556 DWORD status = GetLastError();
00557
00558 break;
00559 }
00560
00561 if( policyStatus.dwError )
00562 {
00563
00564 break;
00565 }
00566 valid = true;
00567 }
00568 while( false );
00569
00570 if( chainContext ) CertFreeCertificateChain( chainContext );
00571 m_certInfo.chain = valid;
00572 }
00573
00574 void SChannel::connectionInfos()
00575 {
00576 SecPkgContext_ConnectionInfo conn_info;
00577
00578 memset( &conn_info, 0, sizeof( conn_info ) );
00579
00580 if( QueryContextAttributes( &m_context, SECPKG_ATTR_CONNECTION_INFO, &conn_info ) == SEC_E_OK )
00581 {
00582 switch( conn_info.dwProtocol )
00583 {
00584 case SP_PROT_TLS1_CLIENT:
00585 m_certInfo.protocol = "TLSv1";
00586 break;
00587 case SP_PROT_SSL3_CLIENT:
00588 m_certInfo.protocol = "SSLv3";
00589 break;
00590 default:
00591 m_certInfo.protocol = "unknown";
00592 }
00593
00594 switch( conn_info.aiCipher )
00595 {
00596 case CALG_3DES:
00597 m_certInfo.cipher = "3DES";
00598 break;
00599 case CALG_AES_128:
00600 m_certInfo.cipher = "AES_128";
00601 break;
00602 case CALG_AES_256:
00603 m_certInfo.cipher = "AES_256";
00604 break;
00605 case CALG_DES:
00606 m_certInfo.cipher = "DES";
00607 break;
00608 case CALG_RC2:
00609 m_certInfo.cipher = "RC2";
00610 break;
00611 case CALG_RC4:
00612 m_certInfo.cipher = "RC4";
00613 break;
00614 default:
00615 m_certInfo.cipher = "";
00616 }
00617
00618 switch( conn_info.aiHash )
00619 {
00620 case CALG_MD5:
00621 m_certInfo.mac = "MD5";
00622 break;
00623 case CALG_SHA:
00624 m_certInfo.mac = "SHA";
00625 break;
00626 default:
00627 m_certInfo.mac = "";
00628 }
00629 }
00630 }
00631
00632 void SChannel::certData()
00633 {
00634 PCCERT_CONTEXT remoteCertContext = NULL;
00635 CHAR certString[1000];
00636
00637
00638 if( QueryContextAttributes( &m_context, SECPKG_ATTR_REMOTE_CERT_CONTEXT,
00639 (PVOID)&remoteCertContext ) != SEC_E_OK )
00640 {
00641 return;
00642 }
00643
00644
00645 m_certInfo.date_from = filetime2int( remoteCertContext->pCertInfo->NotBefore );
00646 m_certInfo.date_to = filetime2int( remoteCertContext->pCertInfo->NotAfter );
00647
00648 if( !CertNameToStr( remoteCertContext->dwCertEncodingType,
00649 &remoteCertContext->pCertInfo->Subject,
00650 CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
00651 certString, sizeof( certString ) ) )
00652 {
00653 return;
00654 }
00655 m_certInfo.server = certString;
00656
00657 if( !CertNameToStr( remoteCertContext->dwCertEncodingType,
00658 &remoteCertContext->pCertInfo->Issuer,
00659 CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
00660 certString, sizeof( certString ) ) )
00661 {
00662 return;
00663 }
00664 m_certInfo.issuer = certString;
00665 }
00666
00667 void SChannel::setCertinfos()
00668 {
00669 validateCert();
00670 connectionInfos();
00671 certData();
00672 }
00673
00674 #if 0
00675 void SChannel::print_error( int errorcode, const char* place )
00676 {
00677 printf( "Win error at %s.\n", place );
00678 switch( errorcode )
00679 {
00680 case SEC_E_OK:
00681 printf( "\tValue:\tSEC_E_OK\n" );
00682 printf( "\tDesc:\tNot really an error. Everything is fine.\n" );
00683 break;
00684 case SEC_E_INSUFFICIENT_MEMORY:
00685 printf( "\tValue:\tSEC_E_INSUFFICIENT_MEMORY\n" );
00686 printf( "\tDesc:\tThere is not enough memory available to complete the requested action.\n" );
00687 break;
00688 case SEC_E_INTERNAL_ERROR:
00689 printf( "\tValue:\tSEC_E_INTERNAL_ERROR\n" );
00690 printf( "\tDesc:\tAn error occurred that did not map to an SSPI error code.\n" );
00691 break;
00692 case SEC_E_NO_CREDENTIALS:
00693 printf( "\tValue:\tSEC_E_NO_CREDENTIALS\n" );
00694 printf( "\tDesc:\tNo credentials are available in the security package.\n" );
00695 break;
00696 case SEC_E_NOT_OWNER:
00697 printf( "\tValue:\tSEC_E_NOT_OWNER\n" );
00698 printf( "\tDesc:\tThe caller of the function does not have the necessary credentials.\n" );
00699 break;
00700 case SEC_E_SECPKG_NOT_FOUND:
00701 printf( "\tValue:\tSEC_E_SECPKG_NOT_FOUND\n" );
00702 printf( "\tDesc:\tThe requested security package does not exist. \n" );
00703 break;
00704 case SEC_E_UNKNOWN_CREDENTIALS:
00705 printf( "\tValue:\tSEC_E_UNKNOWN_CREDENTIALS\n" );
00706 printf( "\tDesc:\tThe credentials supplied to the package were not recognized.\n" );
00707 break;
00708 case SEC_E_INCOMPLETE_MESSAGE:
00709 printf( "\tValue:\tSEC_E_INCOMPLETE_MESSAGE\n" );
00710 printf( "\tDesc:\tData for the whole message was not read from the wire.\n" );
00711 break;
00712 case SEC_E_INVALID_HANDLE:
00713 printf( "\tValue:\tSEC_E_INVALID_HANDLE\n" );
00714 printf( "\tDesc:\tThe handle passed to the function is invalid.\n" );
00715 break;
00716 case SEC_E_INVALID_TOKEN:
00717 printf( "\tValue:\tSEC_E_INVALID_TOKEN\n" );
00718 printf( "\tDesc:\tThe error is due to a malformed input token, such as a token "
00719 "corrupted in transit...\n" );
00720 break;
00721 case SEC_E_LOGON_DENIED:
00722 printf( "\tValue:\tSEC_E_LOGON_DENIED\n" );
00723 printf( "\tDesc:\tThe logon failed.\n" );
00724 break;
00725 case SEC_E_NO_AUTHENTICATING_AUTHORITY:
00726 printf( "\tValue:\tSEC_E_NO_AUTHENTICATING_AUTHORITY\n" );
00727 printf( "\tDesc:\tNo authority could be contacted for authentication...\n" );
00728 break;
00729 case SEC_E_TARGET_UNKNOWN:
00730 printf( "\tValue:\tSEC_E_TARGET_UNKNOWN\n" );
00731 printf( "\tDesc:\tThe target was not recognized.\n" );
00732 break;
00733 case SEC_E_UNSUPPORTED_FUNCTION:
00734 printf( "\tValue:\tSEC_E_UNSUPPORTED_FUNCTION\n" );
00735 printf( "\tDesc:\tAn invalid context attribute flag (ISC_REQ_DELEGATE or "
00736 "ISC_REQ_PROMPT_FOR_CREDS)...\n" );
00737 break;
00738 case SEC_E_WRONG_PRINCIPAL:
00739 printf( "\tValue:\tSEC_E_WRONG_PRINCIPAL\n" );
00740 printf( "\tDesc:\tThe principal that received the authentication request "
00741 "is not the same as the...\n" );
00742 break;
00743 case SEC_I_COMPLETE_AND_CONTINUE:
00744 printf( "\tValue:\tSEC_I_COMPLETE_AND_CONTINUE\n" );
00745 printf( "\tDesc:\tThe client must call CompleteAuthToken and then pass the output...\n" );
00746 break;
00747 case SEC_I_COMPLETE_NEEDED:
00748 printf( "\tValue:\tSEC_I_COMPLETE_NEEDED\n" );
00749 printf( "\tDesc:\tThe client must finish building the message and then "
00750 "call the CompleteAuthToken function.\n" );
00751 break;
00752 case SEC_I_CONTINUE_NEEDED:
00753 printf( "\tValue:\tSEC_I_CONTINUE_NEEDED\n" );
00754 printf( "\tDesc:\tThe client must send the output token to the server "
00755 "and wait for a return token...\n" );
00756 break;
00757 case SEC_I_INCOMPLETE_CREDENTIALS:
00758 printf( "\tValue:\tSEC_I_INCOMPLETE_CREDENTIALS\n" );
00759 printf( "\tDesc:\tThe server has requested client authentication, "
00760 "and the supplied credentials either...\n" );
00761 break;
00762 default:
00763 printf( "\tValue:\t%d\n", errorcode );
00764 printf( "\tDesc:\tUnknown error code.\n" );
00765 }
00766 }
00767 #endif
00768
00769 }
00770
00771 #endif // HAVE_WINTLS