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