(file) Return to SSLContext.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/SSLContext.cpp between version 1.51 and 1.72

version 1.51, 2005/03/29 21:57:24 version 1.72, 2006/08/22 17:49:09
Line 1 
Line 1 
 //%2005////////////////////////////////////////////////////////////////////////  //%2006////////////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
Line 8 
Line 8 
 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 // EMC Corporation; VERITAS Software Corporation; The Open Group. // EMC Corporation; VERITAS Software Corporation; The Open Group.
   // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
   // EMC Corporation; Symantec Corporation; The Open Group.
 // //
 // Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to // of this software and associated documentation files (the "Software"), to
Line 34 
Line 36 
 //              Sushma Fernandes, Hewlett-Packard Company (sushma_fernandes@hp.com) //              Sushma Fernandes, Hewlett-Packard Company (sushma_fernandes@hp.com)
 //              Heather Sterling, IBM (hsterl@us.ibm.com) //              Heather Sterling, IBM (hsterl@us.ibm.com)
 //              Amit K Arora, IBM (amita@in.ibm.com) for Bug#1090 //              Amit K Arora, IBM (amita@in.ibm.com) for Bug#1090
   //              David Dillard, Symantec Corp. (david_dillard@symantec.com)
   //              Aruran, IBM (ashanmug@in.ibm.com) for Bug#4422
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #ifdef PEGASUS_HAS_SSL #ifdef PEGASUS_HAS_SSL
  
 #ifdef PEGASUS_PLATFORM_WIN32_IX86_MSVC  #include <Pegasus/Common/Config.h>
 //Bugzilla 2366  
 //Use the X509_NAME in wincrypt.h on Windows.  See X509.h for more info.  #include "Network.h"
 #include <windows.h>  
 #include <wincrypt.h>  
 #endif  
  
 #define OPENSSL_NO_KRB5 1 #define OPENSSL_NO_KRB5 1
 #include <openssl/err.h> #include <openssl/err.h>
Line 53 
Line 54 
 #else #else
 #define SSL_CTX void #define SSL_CTX void
 #endif // end of PEGASUS_HAS_SSL #endif // end of PEGASUS_HAS_SSL
 #include <Pegasus/Common/Destroyer.h>  
 #include <Pegasus/Common/Socket.h> #include <Pegasus/Common/Socket.h>
 #include <Pegasus/Common/Tracer.h> #include <Pegasus/Common/Tracer.h>
 #include <Pegasus/Common/FileSystem.h> #include <Pegasus/Common/FileSystem.h>
Line 64 
Line 64 
 #include "SSLContext.h" #include "SSLContext.h"
 #include "SSLContextRep.h" #include "SSLContextRep.h"
  
   #ifdef PEGASUS_OS_OS400
   #include "SSLWrapperOS400.h"
   #endif
  
 // //
 // Typedef's for OpenSSL callback functions. // Typedef's for OpenSSL callback functions.
Line 102 
Line 105 
 // //
 #ifdef PEGASUS_HAS_SSL #ifdef PEGASUS_HAS_SSL
  
 // Mutex for SSL locks.  // Mutex for SSL locks which will get initialized by AutoArrayPtr constructor.
 Mutex* SSLContextRep::_sslLocks = 0;  AutoArrayPtr<Mutex> SSLContextRep::_sslLocks;
  
 // Mutex for _countRep. // Mutex for _countRep.
 Mutex SSLContextRep::_countRepMutex; Mutex SSLContextRep::_countRepMutex;
Line 218 
Line 221 
     if (sslCRLStore == NULL)     if (sslCRLStore == NULL)
     {     {
         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: CRL store is NULL");         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: CRL store is NULL");
           PEG_METHOD_EXIT();
         return 0;         return 0;
     }     }
  
Line 251 
Line 255 
     if (X509_STORE_get_by_subject(&crlStoreCtx, X509_LU_CRL, issuerName, &obj) <= 0)     if (X509_STORE_get_by_subject(&crlStoreCtx, X509_LU_CRL, issuerName, &obj) <= 0)
     {     {
         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: No CRL by that issuer");         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "---> SSL: No CRL by that issuer");
           PEG_METHOD_EXIT();
         return 0;         return 0;
     }     }
     X509_STORE_CTX_cleanup(&crlStoreCtx);     X509_STORE_CTX_cleanup(&crlStoreCtx);
Line 260 
Line 265 
     if (crl == NULL)     if (crl == NULL)
     {     {
         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: CRL is null");         PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "---> SSL: CRL is null");
           PEG_METHOD_EXIT();
         return 0;         return 0;
     } else     } else
     {     {
Line 283 
Line 289 
         {         {
             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2, "---> SSL: Certificate is revoked");             PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL2, "---> SSL: Certificate is revoked");
             X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);             X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
               PEG_METHOD_EXIT();
             return 1;             return 1;
         }         }
     }     }
Line 319 
Line 326 
     ssl = (SSL*) X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());     ssl = (SSL*) X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
     SSLCallbackInfo* exData = (SSLCallbackInfo*) SSL_get_ex_data(ssl, SSLCallbackInfo::SSL_CALLBACK_INDEX);     SSLCallbackInfo* exData = (SSLCallbackInfo*) SSL_get_ex_data(ssl, SSLCallbackInfo::SSL_CALLBACK_INDEX);
  
     //  
     // If the SSLContext does not have an additional callback  
     // simply return the preverification error (or check the CRL)  
     // We do not need to go through the additional steps.  
     //  
     if (exData->verifyCertificateCallback == NULL)  
     {  
         Tracer::trace(TRC_SSL, Tracer::LEVEL4,  
                       "--->SSL: No verification callback specified");  
   
         if (exData->_crlStore != NULL)  
         {  
             revoked = verificationCRLCallback(preVerifyOk,ctx,exData->_crlStore);  
             Tracer::trace(TRC_SSL, Tracer::LEVEL4, "---> SSL: CRL callback returned %d", revoked);  
   
             if (revoked) //with the SSL callbacks '0' indicates failure  
             {  
                 PEG_METHOD_EXIT();  
                 return 0;  
             }  
         }  
     }  
  
   #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
     //     //
     // Check to see if a CRL path is defined     // Check to see if a CRL path is defined
     //     //
     if (exData->_crlStore != NULL)      if (exData->_rep->crlStore != NULL)
     {     {
         revoked = verificationCRLCallback(preVerifyOk,ctx,exData->_crlStore);          revoked = verificationCRLCallback(preVerifyOk,ctx,exData->_rep->crlStore);
         Tracer::trace(TRC_SSL, Tracer::LEVEL4, "---> SSL: CRL callback returned %d", revoked);         Tracer::trace(TRC_SSL, Tracer::LEVEL4, "---> SSL: CRL callback returned %d", revoked);
  
         if (revoked) //with the SSL callbacks '0' indicates failure         if (revoked) //with the SSL callbacks '0' indicates failure
Line 358 
Line 344 
     }     }
  
     Tracer::trace(TRC_SSL, Tracer::LEVEL4, "---> SSL: CRL callback returned %d", revoked);     Tracer::trace(TRC_SSL, Tracer::LEVEL4, "---> SSL: CRL callback returned %d", revoked);
   #endif
  
     //     //
     // get the current certificate     // get the current certificate
Line 414 
Line 401 
     //     //
     // get the issuer name on the certificate     // get the issuer name on the certificate
     //     //
     if (!preVerifyOk && (errorCode == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT))  
     {  
         X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);  
     }  
     else  
     {  
         X509_NAME_oneline(X509_get_issuer_name(currentCert), buf, 256);         X509_NAME_oneline(X509_get_issuer_name(currentCert), buf, 256);
     }  
     String issuerName = String(buf);     String issuerName = String(buf);
  
     //     //
     // Create the certificate object     // Create the certificate object
     //     //
     exData->_peerCertificate = new SSLCertificateInfo(subjectName, issuerName, version, serialNumber,  
         notBefore, notAfter, depth, errorCode, errorStr, preVerifyOk);      //insert at the beginning of the array so that the peer certificate is first and the root CA is last
       exData->_rep->peerCertificate.insert(0, new SSLCertificateInfo(subjectName, issuerName, version, serialNumber,
           notBefore, notAfter, depth, errorCode, errorStr, preVerifyOk));
   
       PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "Created SSLCertificateInfo");
   
       // NOT_YET_VALID checks do not work correctly on subsequent tries -- Bugzilla#4283
       // call this prior to calling the user-specified callback in case they want to override it
       if (errorCode == X509_V_OK && (CIMDateTime::getDifference(CIMDateTime::getCurrentDateTime(), notBefore) > 0))
       {
           PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "Certificate was not yet valid.");
           X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_NOT_YET_VALID);
       }
  
     //     //
     // Call the application callback.      // Call the user-specified application callback if it is specified.  If it is null, return OpenSSL's verification code.
     // Note that the verification result does not automatically get set to X509_V_OK if the callback is successful.     // Note that the verification result does not automatically get set to X509_V_OK if the callback is successful.
     // This is because OpenSSL retains the original default error in case we want to use it later.     // This is because OpenSSL retains the original default error in case we want to use it later.
     // To set the error, we could use X509_STORE_CTX_set_error(ctx, verifyError); but there is no real benefit to doing that here.     // To set the error, we could use X509_STORE_CTX_set_error(ctx, verifyError); but there is no real benefit to doing that here.
     //     //
     if (exData->verifyCertificateCallback(*exData->_peerCertificate))      if (exData->_rep->verifyCertificateCallback == NULL)
       {
           return preVerifyOk;
   
       } else
       {
           if (exData->_rep->verifyCertificateCallback(*exData->_rep->peerCertificate[0]))
     {     {
         Tracer::trace(TRC_SSL, Tracer::LEVEL4,         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
             "--> SSL: verifyCertificateCallback() returned X509_V_OK");                  "--> SSL: _rep->verifyCertificateCallback() returned X509_V_OK");
  
         PEG_METHOD_EXIT();         PEG_METHOD_EXIT();
         return 1;         return 1;
Line 447 
Line 445 
     else // verification failed, handshake will be immediately terminated     else // verification failed, handshake will be immediately terminated
     {     {
         Tracer::trace(TRC_SSL, Tracer::LEVEL4,         Tracer::trace(TRC_SSL, Tracer::LEVEL4,
             "--> SSL: verifyCertificateCallback() returned error %d", exData->_peerCertificate->getErrorCode());                  "--> SSL: _rep->verifyCertificateCallback() returned error %d", exData->_rep->peerCertificate[0]->getErrorCode());
  
         PEG_METHOD_EXIT();         PEG_METHOD_EXIT();
         return 0;         return 0;
     }     }
 } }
   }
  
 // //
 // Callback function called by OpenSSL.  This request is merely forwarded to the static // Callback function called by OpenSSL.  This request is merely forwarded to the static
Line 477 
Line 476 
     if ( mode & CRYPTO_LOCK )     if ( mode & CRYPTO_LOCK )
     {     {
         /*Tracer::trace(TRC_SSL, Tracer::LEVEL4,         /*Tracer::trace(TRC_SSL, Tracer::LEVEL4,
                 "Now locking for %d", pegasus_thread_self());*/                  "Now locking for %d", Threads::id());*/
         SSLContextRep::_sslLocks[type].lock( pegasus_thread_self() );          SSLContextRep::_sslLocks.get()[type].lock( );
     }     }
     else     else
     {     {
         /*Tracer::trace(TRC_SSL, Tracer::LEVEL4,         /*Tracer::trace(TRC_SSL, Tracer::LEVEL4,
                 "Now unlocking for %d", pegasus_thread_self());*/                  "Now unlocking for %d", Threads::id());*/
         SSLContextRep::_sslLocks[type].unlock( );          SSLContextRep::_sslLocks.get()[type].unlock( );
     }     }
 } }
  
   static unsigned long _get_thread_id()
   {
   #if defined(PEGASUS_HAVE_PTHREADS)
       return pthread_self();
   #else
       return 0;
   #endif
   }
   
 // //
 // Initialize OpenSSL Locking and id callbacks. // Initialize OpenSSL Locking and id callbacks.
 // //
Line 498 
Line 506 
      PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,      PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
            "Initialized SSL callback.");            "Initialized SSL callback.");
  
      _sslLocks= new Mutex[CRYPTO_num_locks()];  #ifdef PEGASUS_OS_OS400
        // Load the OpenSSL library and get the exports
        SSL_OS400_Init();
   #endif
   
        _sslLocks.reset(new Mutex[CRYPTO_num_locks()]);
  
      // Set the ID callback. The ID callback returns a thread ID.      // Set the ID callback. The ID callback returns a thread ID.
  
      CRYPTO_set_id_callback((CRYPTO_SET_ID_CALLBACK) pegasus_thread_self);       CRYPTO_set_id_callback((CRYPTO_SET_ID_CALLBACK)_get_thread_id);
  
      // Set the locking callback to pegasus_locking_callback.      // Set the locking callback to pegasus_locking_callback.
  
Line 519 
Line 532 
     CRYPTO_set_id_callback     (NULL);     CRYPTO_set_id_callback     (NULL);
     PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,     PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4,
              "Freed SSL callback.");              "Freed SSL callback.");
       _sslLocks.reset();
     delete []_sslLocks;  
 } }
  
  
Line 580 
Line 592 
             // load SSL library             // load SSL library
             //             //
             Tracer::trace(TRC_SSL, Tracer::LEVEL4,             Tracer::trace(TRC_SSL, Tracer::LEVEL4,
                 "Before calling SSL_load_error_strings %d", pegasus_thread_self());                  "Before calling SSL_load_error_strings %d", Threads::id());
  
             SSL_load_error_strings();             SSL_load_error_strings();
  
             Tracer::trace(TRC_SSL, Tracer::LEVEL4,             Tracer::trace(TRC_SSL, Tracer::LEVEL4,
                 "After calling SSL_load_error_strings %d", pegasus_thread_self());                  "After calling SSL_load_error_strings %d", Threads::id());
  
             Tracer::trace(TRC_SSL, Tracer::LEVEL4,             Tracer::trace(TRC_SSL, Tracer::LEVEL4,
                 "Before calling SSL_library_init %d", pegasus_thread_self());                  "Before calling SSL_library_init %d", Threads::id());
  
             SSL_library_init();             SSL_library_init();
  
             Tracer::trace(TRC_SSL, Tracer::LEVEL4,             Tracer::trace(TRC_SSL, Tracer::LEVEL4,
                 "After calling SSL_library_init %d", pegasus_thread_self());                  "After calling SSL_library_init %d", Threads::id());
   
         }         }
  
     _countRep++;     _countRep++;
Line 732 
Line 743 
             // Try to do more seeding             // Try to do more seeding
             //             //
             long seedNumber;             long seedNumber;
         #if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC)          #if defined(PEGASUS_COMPILER_MSVC)
             srand((unsigned int)time(NULL)); // Initialize             srand((unsigned int)time(NULL)); // Initialize
             seedNumber = rand();             seedNumber = rand();
         #else         #else
Line 812 
Line 823 
  
     SSL_CTX_set_quiet_shutdown(sslContext, 1);     SSL_CTX_set_quiet_shutdown(sslContext, 1);
     SSL_CTX_set_mode(sslContext, SSL_MODE_AUTO_RETRY);     SSL_CTX_set_mode(sslContext, SSL_MODE_AUTO_RETRY);
       SSL_CTX_set_mode(sslContext, SSL_MODE_ENABLE_PARTIAL_WRITE);
     SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF);     SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF);
  
     int options = SSL_OP_ALL;     int options = SSL_OP_ALL;
Line 1098 
Line 1110 
     return _keyPath;     return _keyPath;
 } }
  
   #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
   String SSLContextRep::getTrustStoreUserName() const
   {
       return String::EMPTY;
   }
   #endif
   
 String SSLContextRep::getCRLPath() const String SSLContextRep::getCRLPath() const
 { {
     return _crlPath;     return _crlPath;
Line 1154 
Line 1173 
  
 String SSLContextRep::getKeyPath() const { return String::EMPTY; } String SSLContextRep::getKeyPath() const { return String::EMPTY; }
  
   #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
   String SSLContextRep::getTrustStoreUserName() const { return String::EMPTY; }
   #endif
   
 String SSLContextRep::getCRLPath() const { return String::EMPTY; } String SSLContextRep::getCRLPath() const { return String::EMPTY; }
  
 X509_STORE* SSLContextRep::getCRLStore() const { return NULL; } X509_STORE* SSLContextRep::getCRLStore() const { return NULL; }
Line 1204 
Line 1227 
         SSLCertificateVerifyFunction* verifyCert,         SSLCertificateVerifyFunction* verifyCert,
         const String& randomFile)         const String& randomFile)
 { {
   #ifndef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
       if ( crlPath.size() > 0 )
       {
           MessageLoaderParms parms("Common.Exception.SSL_CRL_NOT_ENABLED_EXCEPTION",
                                    "SSL CRL verification is not enabled.");
           throw Exception(parms);
       }
   #endif
     _rep = new SSLContextRep(trustStore, certPath, keyPath, crlPath, verifyCert, randomFile);     _rep = new SSLContextRep(trustStore, certPath, keyPath, crlPath, verifyCert, randomFile);
 } }
  
   #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
   SSLContext::SSLContext(
       const String& trustStore,
       const String& certPath,
       const String& keyPath,
       SSLCertificateVerifyFunction* verifyCert,
       String trustStoreUserName,
       const String& randomFile)
   {
       _rep = new SSLContextRep(trustStore, certPath, keyPath, String::EMPTY, verifyCert, randomFile);
   }
   #endif
   
 SSLContext::SSLContext(const SSLContext& sslContext) SSLContext::SSLContext(const SSLContext& sslContext)
 { {
     _rep = new SSLContextRep(*sslContext._rep);     _rep = new SSLContextRep(*sslContext._rep);
Line 1239 
Line 1283 
  
 String SSLContext::getCRLPath() const String SSLContext::getCRLPath() const
 { {
   #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
     return (_rep->getCRLPath());     return (_rep->getCRLPath());
   #else
       MessageLoaderParms parms("Common.Exception.SSL_CRL_NOT_ENABLED_EXCEPTION",
                                "SSL CRL verification is not enabled.");
       throw Exception(parms);
   #endif
 } }
  
 X509_STORE* SSLContext::getCRLStore() const X509_STORE* SSLContext::getCRLStore() const
 { {
   #ifdef PEGASUS_ENABLE_SSL_CRL_VERIFICATION
     return (_rep->getCRLStore());     return (_rep->getCRLStore());
   #else
       MessageLoaderParms parms("Common.Exception.SSL_CRL_NOT_ENABLED_EXCEPTION",
                                "SSL CRL verification is not enabled.");
       throw Exception(parms);
   #endif
 } }
  
 Boolean SSLContext::isPeerVerificationEnabled() const Boolean SSLContext::isPeerVerificationEnabled() const
Line 1252 
Line 1308 
     return (_rep->isPeerVerificationEnabled());     return (_rep->isPeerVerificationEnabled());
 } }
  
   #ifdef PEGASUS_USE_DEPRECATED_INTERFACES
   String SSLContext::getTrustStoreUserName() const
   {
           return (_rep->getTrustStoreUserName());
   }
   #endif
   
 SSLCertificateVerifyFunction* SSLContext::getSSLCertificateVerifyFunction() const SSLCertificateVerifyFunction* SSLContext::getSSLCertificateVerifyFunction() const
 { {
     return (_rep->getSSLCertificateVerifyFunction());     return (_rep->getSSLCertificateVerifyFunction());
Line 1478 
Line 1541 
     sprintf(buf, "Version number: %d\n", _rep->versionNumber);     sprintf(buf, "Version number: %d\n", _rep->versionNumber);
     s.append(buf);     s.append(buf);
  
     sprintf(buf, "Serial number: %ld\n", _rep->serialNumber);      sprintf(buf, "Serial number: %lu\n", _rep->serialNumber);
     s.append(buf);     s.append(buf);
  
     s.append("Not before date: ");     s.append("Not before date: ");
Line 1492 
Line 1555 
     return s;     return s;
 } }
  
   ///////////////////////////////////////////////////////////////////////////////
   //
   // SSLCallbackInfo
   //
   ///////////////////////////////////////////////////////////////////////////////
   
   SSLCallbackInfo::SSLCallbackInfo(SSLCertificateVerifyFunction* verifyCert)
   {
       _rep = new SSLCallbackInfoRep();
       _rep->verifyCertificateCallback = verifyCert;
       _rep->crlStore = NULL;
   }
   
 SSLCallbackInfo::SSLCallbackInfo(SSLCertificateVerifyFunction* verifyCert, X509_STORE* crlStore) SSLCallbackInfo::SSLCallbackInfo(SSLCertificateVerifyFunction* verifyCert, X509_STORE* crlStore)
 { {
     verifyCertificateCallback = verifyCert;      _rep = new SSLCallbackInfoRep();
     _crlStore = crlStore;      _rep->verifyCertificateCallback = verifyCert;
     _peerCertificate = NULL;      _rep->crlStore = crlStore;
 } }
  
 SSLCallbackInfo::~SSLCallbackInfo() SSLCallbackInfo::~SSLCallbackInfo()
 { {
     if (_peerCertificate)      PEG_METHOD_ENTER(TRC_SSL, "SSLCallbackInfo::~SSLCallbackInfo");
       for (Uint32 i = 0; i < _rep->peerCertificate.size(); i++)
     {     {
         delete _peerCertificate;          delete _rep->peerCertificate[i];
     }     }
       delete _rep;
       PEG_METHOD_EXIT();
 } }
  
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.51  
changed lines
  Added in v.1.72

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2