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 m_buffer = "";
00216 if( !m_cleanedup )
00217 {
00218 m_valid = false;
00219 m_secure = false;
00220 m_cleanedup = true;
00221 DeleteSecurityContext( &m_context );
00222 FreeCredentialsHandle( &m_credHandle );
00223 }
00224 }
00225
00226 bool SChannel::handshake()
00227 {
00228 if( !m_handler )
00229 return false;
00230
00231
00232 SECURITY_STATUS error;
00233 ULONG return_flags;
00234 TimeStamp t;
00235 SecBuffer obuf[1];
00236 SecBufferDesc obufs;
00237 SCHANNEL_CRED tlscred;
00238 ULONG request = ISC_REQ_ALLOCATE_MEMORY
00239 | ISC_REQ_CONFIDENTIALITY
00240 | ISC_REQ_EXTENDED_ERROR
00241 | ISC_REQ_INTEGRITY
00242 | ISC_REQ_REPLAY_DETECT
00243 | ISC_REQ_SEQUENCE_DETECT
00244 | ISC_REQ_STREAM
00245 | ISC_REQ_MANUAL_CRED_VALIDATION;
00246
00247
00248 memset( &tlscred, 0, sizeof( SCHANNEL_CRED ) );
00249 tlscred.dwVersion = SCHANNEL_CRED_VERSION;
00250 tlscred.grbitEnabledProtocols = SP_PROT_TLS1;
00251
00252 error = AcquireCredentialsHandle( 0,
00253 UNISP_NAME,
00254 SECPKG_CRED_OUTBOUND,
00255 0,
00256 &tlscred,
00257 0,
00258 0,
00259 &m_credHandle,
00260 &t );
00261
00262 if( error != SEC_E_OK )
00263 {
00264 cleanup();
00265 m_handler->handleHandshakeResult( this, false, m_certInfo );
00266 return false;
00267 }
00268 else
00269 {
00270
00271 obuf[0].cbBuffer = 0;
00272 obuf[0].pvBuffer = 0;
00273 obuf[0].BufferType = SECBUFFER_TOKEN;
00274
00275 obufs.ulVersion = SECBUFFER_VERSION;
00276 obufs.cBuffers = 1;
00277 obufs.pBuffers = obuf;
00278
00279 SEC_CHAR* hname = const_cast<char*>( m_server.c_str() );
00280
00281 error = InitializeSecurityContext( &m_credHandle,
00282 0,
00283 hname,
00284 request,
00285 0,
00286 SECURITY_NETWORK_DREP,
00287 0,
00288 0,
00289 &m_context,
00290 &obufs,
00291 &return_flags,
00292 NULL );
00293
00294
00295 if( error == SEC_I_CONTINUE_NEEDED )
00296 {
00297 m_cleanedup = false;
00298
00299 std::string senddata( static_cast<char*>(obuf[0].pvBuffer), obuf[0].cbBuffer );
00300 FreeContextBuffer( obuf[0].pvBuffer );
00301 m_handler->handleEncryptedData( this, senddata );
00302 return true;
00303 }
00304 else
00305 {
00306 cleanup();
00307 m_handler->handleHandshakeResult( this, false, m_certInfo );
00308 return false;
00309 }
00310 }
00311 return true;
00312 }
00313
00314 void SChannel::handshakeStage( const std::string& data )
00315 {
00316
00317 m_buffer += data;
00318
00319 SECURITY_STATUS error;
00320 ULONG a;
00321 TimeStamp t;
00322 SecBuffer ibuf[2], obuf[1];
00323 SecBufferDesc ibufs, obufs;
00324 ULONG request = ISC_REQ_ALLOCATE_MEMORY
00325 | ISC_REQ_CONFIDENTIALITY
00326 | ISC_REQ_EXTENDED_ERROR
00327 | ISC_REQ_INTEGRITY
00328 | ISC_REQ_REPLAY_DETECT
00329 | ISC_REQ_SEQUENCE_DETECT
00330 | ISC_REQ_STREAM
00331 | ISC_REQ_MANUAL_CRED_VALIDATION;
00332
00333 SEC_CHAR* hname = const_cast<char*>( m_server.c_str() );
00334
00335 do
00336 {
00337
00338 ibuf[0].cbBuffer = m_buffer.size();
00339 ibuf[0].pvBuffer = static_cast<void*>( const_cast<char*>( m_buffer.c_str() ) );
00340
00341 ibuf[1].cbBuffer = 0;
00342 ibuf[1].pvBuffer = 0;
00343 obuf[0].cbBuffer = 0;
00344 obuf[0].pvBuffer = 0;
00345
00346 ibuf[0].BufferType = SECBUFFER_TOKEN;
00347 ibuf[1].BufferType = SECBUFFER_EMPTY;
00348 obuf[0].BufferType = SECBUFFER_EMPTY;
00349
00350 ibufs.ulVersion = obufs.ulVersion = SECBUFFER_VERSION;
00351 ibufs.cBuffers = 2;
00352 obufs.cBuffers = 1;
00353 ibufs.pBuffers = ibuf;
00354 obufs.pBuffers = obuf;
00355
00356
00357
00358
00359
00360
00361
00362
00363 error = InitializeSecurityContext( &m_credHandle,
00364 &m_context,
00365 hname,
00366 request,
00367 0,
00368 0,
00369 &ibufs,
00370 0,
00371 0,
00372 &obufs,
00373 &a,
00374 &t );
00375
00376 if( error == SEC_E_OK )
00377 {
00378
00379 if( ibuf[1].BufferType == SECBUFFER_EXTRA )
00380 {
00381 m_buffer.erase( 0, m_buffer.size() - ibuf[1].cbBuffer );
00382 }
00383 else
00384 {
00385 m_buffer = "";
00386 }
00387 setSizes();
00388 setCertinfos();
00389
00390 m_secure = true;
00391 m_handler->handleHandshakeResult( this, true, m_certInfo );
00392 break;
00393 }
00394 else if( error == SEC_I_CONTINUE_NEEDED )
00395 {
00396
00397
00398
00399
00400
00401
00402
00403 if( obuf[0].cbBuffer != 0 && obuf[0].pvBuffer != NULL )
00404 {
00405 std::string senddata( static_cast<char*>(obuf[0].pvBuffer), obuf[0].cbBuffer );
00406 FreeContextBuffer( obuf[0].pvBuffer );
00407 m_handler->handleEncryptedData( this, senddata );
00408 }
00409
00410 if( ibuf[1].BufferType == SECBUFFER_EXTRA )
00411 {
00412 m_buffer.erase( 0, m_buffer.size() - ibuf[1].cbBuffer );
00413 }
00414 else
00415 {
00416 m_buffer = "";
00417 }
00418 return;
00419 }
00420 else if( error == SEC_I_INCOMPLETE_CREDENTIALS )
00421 {
00422 handshakeStage( "" );
00423 }
00424 else if( error == SEC_E_INCOMPLETE_MESSAGE )
00425 {
00426 break;
00427 }
00428 else
00429 {
00430 cleanup();
00431 m_handler->handleHandshakeResult( this, false, m_certInfo );
00432 break;
00433 }
00434 }
00435 while( true );
00436 }
00437
00438 void SChannel::setCACerts( const StringList& cacerts ) {}
00439
00440 void SChannel::setClientCert( const std::string& clientKey, const std::string& clientCerts ) {}
00441
00442 void SChannel::setSizes()
00443 {
00444 if( QueryContextAttributes( &m_context, SECPKG_ATTR_STREAM_SIZES, &m_sizes ) == SEC_E_OK )
00445 {
00446
00447 }
00448 else
00449 {
00450
00451 cleanup();
00452 m_handler->handleHandshakeResult( this, false, m_certInfo );
00453 }
00454 }
00455
00456 int SChannel::filetime2int( FILETIME t )
00457 {
00458 SYSTEMTIME stUTC;
00459 FileTimeToSystemTime(&t, &stUTC);
00460 std::tm ts;
00461 ts.tm_year = stUTC.wYear - 1900;
00462 ts.tm_mon = stUTC.wMonth - 1;
00463 ts.tm_mday = stUTC.wDay;
00464 ts.tm_hour = stUTC.wHour;
00465 ts.tm_min = stUTC.wMinute;
00466 ts.tm_sec = stUTC.wSecond;
00467
00468 int unixtime;
00469 if ( (unixtime = mktime(&ts)) == -1 )
00470 unixtime = 0;
00471 return unixtime;
00472 }
00473
00474 void SChannel::validateCert()
00475 {
00476 bool valid = false;
00477 HTTPSPolicyCallbackData policyHTTPS;
00478 CERT_CHAIN_POLICY_PARA policyParameter;
00479 CERT_CHAIN_POLICY_STATUS policyStatus;
00480
00481 PCCERT_CONTEXT remoteCertContext = NULL;
00482 PCCERT_CHAIN_CONTEXT chainContext = NULL;
00483 CERT_CHAIN_PARA chainParameter;
00484 PSTR serverName = const_cast<char*>( m_server.c_str() );
00485
00486 PWSTR uServerName = NULL;
00487 DWORD csizeServerName;
00488
00489 LPSTR Usages[] = {
00490 szOID_PKIX_KP_SERVER_AUTH,
00491 szOID_SERVER_GATED_CRYPTO,
00492 szOID_SGC_NETSCAPE
00493 };
00494 DWORD cUsages = sizeof( Usages ) / sizeof( LPSTR );
00495
00496 do
00497 {
00498
00499 if( QueryContextAttributes( &m_context, SECPKG_ATTR_REMOTE_CERT_CONTEXT,
00500 (PVOID)&remoteCertContext ) != SEC_E_OK )
00501 {
00502
00503
00504 break;
00505 }
00506
00507
00508
00509 csizeServerName = MultiByteToWideChar( CP_ACP, 0, serverName, -1, NULL, 0 );
00510 uServerName = reinterpret_cast<WCHAR *>( LocalAlloc( LMEM_FIXED,
00511 csizeServerName * sizeof( WCHAR ) ) );
00512 if( uServerName == NULL )
00513 {
00514
00515 break;
00516 }
00517
00518
00519 csizeServerName = MultiByteToWideChar( CP_ACP, 0, serverName, -1, uServerName, csizeServerName );
00520 if( csizeServerName == 0 )
00521 {
00522
00523 break;
00524 }
00525
00526
00527 ZeroMemory( &chainParameter, sizeof( chainParameter ) );
00528 chainParameter.cbSize = sizeof( chainParameter );
00529 chainParameter.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR;
00530 chainParameter.RequestedUsage.Usage.cUsageIdentifier = cUsages;
00531 chainParameter.RequestedUsage.Usage.rgpszUsageIdentifier = Usages;
00532
00533 if( !CertGetCertificateChain( NULL, remoteCertContext, NULL, remoteCertContext->hCertStore,
00534 &chainParameter, 0, NULL, &chainContext ) )
00535 {
00536 DWORD status = GetLastError();
00537
00538 break;
00539 }
00540
00541
00542 ZeroMemory( &policyHTTPS, sizeof( HTTPSPolicyCallbackData ) );
00543 policyHTTPS.cbStruct = sizeof( HTTPSPolicyCallbackData );
00544 policyHTTPS.dwAuthType = AUTHTYPE_SERVER;
00545 policyHTTPS.fdwChecks = 0;
00546 policyHTTPS.pwszServerName = uServerName;
00547
00548 memset( &policyParameter, 0, sizeof( policyParameter ) );
00549 policyParameter.cbSize = sizeof( policyParameter );
00550 policyParameter.pvExtraPolicyPara = &policyHTTPS;
00551
00552 memset( &policyStatus, 0, sizeof( policyStatus ) );
00553 policyStatus.cbSize = sizeof( policyStatus );
00554
00555 if( !CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_SSL, chainContext, &policyParameter,
00556 &policyStatus ) )
00557 {
00558 DWORD status = GetLastError();
00559
00560 break;
00561 }
00562
00563 if( policyStatus.dwError )
00564 {
00565
00566 break;
00567 }
00568 valid = true;
00569 }
00570 while( false );
00571
00572 if( chainContext ) CertFreeCertificateChain( chainContext );
00573 m_certInfo.chain = valid;
00574 }
00575
00576 void SChannel::connectionInfos()
00577 {
00578 SecPkgContext_ConnectionInfo conn_info;
00579
00580 memset( &conn_info, 0, sizeof( conn_info ) );
00581
00582 if( QueryContextAttributes( &m_context, SECPKG_ATTR_CONNECTION_INFO, &conn_info ) == SEC_E_OK )
00583 {
00584 switch( conn_info.dwProtocol )
00585 {
00586 case SP_PROT_TLS1_CLIENT:
00587 m_certInfo.protocol = "TLSv1";
00588 break;
00589 case SP_PROT_SSL3_CLIENT:
00590 m_certInfo.protocol = "SSLv3";
00591 break;
00592 default:
00593 m_certInfo.protocol = "unknown";
00594 }
00595
00596 switch( conn_info.aiCipher )
00597 {
00598 case CALG_3DES:
00599 m_certInfo.cipher = "3DES";
00600 break;
00601 case CALG_AES_128:
00602 m_certInfo.cipher = "AES_128";
00603 break;
00604 case CALG_AES_256:
00605 m_certInfo.cipher = "AES_256";
00606 break;
00607 case CALG_DES:
00608 m_certInfo.cipher = "DES";
00609 break;
00610 case CALG_RC2:
00611 m_certInfo.cipher = "RC2";
00612 break;
00613 case CALG_RC4:
00614 m_certInfo.cipher = "RC4";
00615 break;
00616 default:
00617 m_certInfo.cipher = "";
00618 }
00619
00620 switch( conn_info.aiHash )
00621 {
00622 case CALG_MD5:
00623 m_certInfo.mac = "MD5";
00624 break;
00625 case CALG_SHA:
00626 m_certInfo.mac = "SHA";
00627 break;
00628 default:
00629 m_certInfo.mac = "";
00630 }
00631 }
00632 }
00633
00634 void SChannel::certData()
00635 {
00636 PCCERT_CONTEXT remoteCertContext = NULL;
00637 CHAR certString[1000];
00638
00639
00640 if( QueryContextAttributes( &m_context, SECPKG_ATTR_REMOTE_CERT_CONTEXT,
00641 (PVOID)&remoteCertContext ) != SEC_E_OK )
00642 {
00643 return;
00644 }
00645
00646
00647 m_certInfo.date_from = filetime2int( remoteCertContext->pCertInfo->NotBefore );
00648 m_certInfo.date_to = filetime2int( remoteCertContext->pCertInfo->NotAfter );
00649
00650 if( !CertNameToStr( remoteCertContext->dwCertEncodingType,
00651 &remoteCertContext->pCertInfo->Subject,
00652 CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
00653 certString, sizeof( certString ) ) )
00654 {
00655 return;
00656 }
00657 m_certInfo.server = certString;
00658
00659 if( !CertNameToStr( remoteCertContext->dwCertEncodingType,
00660 &remoteCertContext->pCertInfo->Issuer,
00661 CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
00662 certString, sizeof( certString ) ) )
00663 {
00664 return;
00665 }
00666 m_certInfo.issuer = certString;
00667 }
00668
00669 void SChannel::setCertinfos()
00670 {
00671 validateCert();
00672 connectionInfos();
00673 certData();
00674 }
00675
00676 #if 0
00677 void SChannel::print_error( int errorcode, const char* place )
00678 {
00679 printf( "Win error at %s.\n", place );
00680 switch( errorcode )
00681 {
00682 case SEC_E_OK:
00683 printf( "\tValue:\tSEC_E_OK\n" );
00684 printf( "\tDesc:\tNot really an error. Everything is fine.\n" );
00685 break;
00686 case SEC_E_INSUFFICIENT_MEMORY:
00687 printf( "\tValue:\tSEC_E_INSUFFICIENT_MEMORY\n" );
00688 printf( "\tDesc:\tThere is not enough memory available to complete the requested action.\n" );
00689 break;
00690 case SEC_E_INTERNAL_ERROR:
00691 printf( "\tValue:\tSEC_E_INTERNAL_ERROR\n" );
00692 printf( "\tDesc:\tAn error occurred that did not map to an SSPI error code.\n" );
00693 break;
00694 case SEC_E_NO_CREDENTIALS:
00695 printf( "\tValue:\tSEC_E_NO_CREDENTIALS\n" );
00696 printf( "\tDesc:\tNo credentials are available in the security package.\n" );
00697 break;
00698 case SEC_E_NOT_OWNER:
00699 printf( "\tValue:\tSEC_E_NOT_OWNER\n" );
00700 printf( "\tDesc:\tThe caller of the function does not have the necessary credentials.\n" );
00701 break;
00702 case SEC_E_SECPKG_NOT_FOUND:
00703 printf( "\tValue:\tSEC_E_SECPKG_NOT_FOUND\n" );
00704 printf( "\tDesc:\tThe requested security package does not exist. \n" );
00705 break;
00706 case SEC_E_UNKNOWN_CREDENTIALS:
00707 printf( "\tValue:\tSEC_E_UNKNOWN_CREDENTIALS\n" );
00708 printf( "\tDesc:\tThe credentials supplied to the package were not recognized.\n" );
00709 break;
00710 case SEC_E_INCOMPLETE_MESSAGE:
00711 printf( "\tValue:\tSEC_E_INCOMPLETE_MESSAGE\n" );
00712 printf( "\tDesc:\tData for the whole message was not read from the wire.\n" );
00713 break;
00714 case SEC_E_INVALID_HANDLE:
00715 printf( "\tValue:\tSEC_E_INVALID_HANDLE\n" );
00716 printf( "\tDesc:\tThe handle passed to the function is invalid.\n" );
00717 break;
00718 case SEC_E_INVALID_TOKEN:
00719 printf( "\tValue:\tSEC_E_INVALID_TOKEN\n" );
00720 printf( "\tDesc:\tThe error is due to a malformed input token, such as a token "
00721 "corrupted in transit...\n" );
00722 break;
00723 case SEC_E_LOGON_DENIED:
00724 printf( "\tValue:\tSEC_E_LOGON_DENIED\n" );
00725 printf( "\tDesc:\tThe logon failed.\n" );
00726 break;
00727 case SEC_E_NO_AUTHENTICATING_AUTHORITY:
00728 printf( "\tValue:\tSEC_E_NO_AUTHENTICATING_AUTHORITY\n" );
00729 printf( "\tDesc:\tNo authority could be contacted for authentication...\n" );
00730 break;
00731 case SEC_E_TARGET_UNKNOWN:
00732 printf( "\tValue:\tSEC_E_TARGET_UNKNOWN\n" );
00733 printf( "\tDesc:\tThe target was not recognized.\n" );
00734 break;
00735 case SEC_E_UNSUPPORTED_FUNCTION:
00736 printf( "\tValue:\tSEC_E_UNSUPPORTED_FUNCTION\n" );
00737 printf( "\tDesc:\tAn invalid context attribute flag (ISC_REQ_DELEGATE or "
00738 "ISC_REQ_PROMPT_FOR_CREDS)...\n" );
00739 break;
00740 case SEC_E_WRONG_PRINCIPAL:
00741 printf( "\tValue:\tSEC_E_WRONG_PRINCIPAL\n" );
00742 printf( "\tDesc:\tThe principal that received the authentication request "
00743 "is not the same as the...\n" );
00744 break;
00745 case SEC_I_COMPLETE_AND_CONTINUE:
00746 printf( "\tValue:\tSEC_I_COMPLETE_AND_CONTINUE\n" );
00747 printf( "\tDesc:\tThe client must call CompleteAuthToken and then pass the output...\n" );
00748 break;
00749 case SEC_I_COMPLETE_NEEDED:
00750 printf( "\tValue:\tSEC_I_COMPLETE_NEEDED\n" );
00751 printf( "\tDesc:\tThe client must finish building the message and then "
00752 "call the CompleteAuthToken function.\n" );
00753 break;
00754 case SEC_I_CONTINUE_NEEDED:
00755 printf( "\tValue:\tSEC_I_CONTINUE_NEEDED\n" );
00756 printf( "\tDesc:\tThe client must send the output token to the server "
00757 "and wait for a return token...\n" );
00758 break;
00759 case SEC_I_INCOMPLETE_CREDENTIALS:
00760 printf( "\tValue:\tSEC_I_INCOMPLETE_CREDENTIALS\n" );
00761 printf( "\tDesc:\tThe server has requested client authentication, "
00762 "and the supplied credentials either...\n" );
00763 break;
00764 default:
00765 printf( "\tValue:\t%d\n", errorcode );
00766 printf( "\tDesc:\tUnknown error code.\n" );
00767 }
00768 }
00769 #endif
00770
00771 }
00772
00773 #endif // HAVE_WINTLS