VirtualBox

Changeset 105124 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Jul 3, 2024 5:50:46 PM (7 months ago)
Author:
vboxsync
Message:

Certificate repair function added - bugref:10310

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/VRDEServerImpl.h

    r104570 r105124  
    6060    HRESULT i_loadSettings(const settings::VRDESettings &data);
    6161    HRESULT i_saveSettings(settings::VRDESettings &data);
     62    int certificateRepair(BOOL &certificateGenerated);
    6263    int i_generateServerCertificate();
    6364    void i_rollback();
  • trunk/src/VBox/Main/src-server/VRDEServerImpl.cpp

    r104745 r105124  
    241241int VRDEServer::i_generateServerCertificate()
    242242{
    243     Utf8Str strServerCertificate("server_cert.pem");
     243    Utf8Str strServerCertificate("VRDEAutoGeneratedCert.pem");
    244244    int vrc = mParent->i_calculateFullPath(strServerCertificate, strServerCertificate);
    245245    AssertRCReturn(vrc, vrc);
    246246
    247     Utf8Str strServerPrivateKey("server_key_private.pem");
     247    Utf8Str strServerPrivateKey("VRDEAutoGeneratedPrivateKey.pem");
    248248    vrc = mParent->i_calculateFullPath(strServerPrivateKey, strServerPrivateKey);
    249249    AssertRCReturn(vrc, vrc);
    250250
     251    AutoReadLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
     252    Utf8Str strVMName = mParent->i_getName();
     253    mlock.release();
     254
    251255    vrc = RTCrX509Certificate_GenerateSelfSignedRsa(RTDIGESTTYPE_SHA1, 2048 /*cBits*/, 10 * 365 * RT_SEC_1DAY,
    252                                                     0 /*fKeyUsage*/, 0 /*fExtKeyUsage*/, NULL /*pvSubjectTodo*/,
     256                                                    0 /*fKeyUsage*/, 0 /*fExtKeyUsage*/, strVMName.c_str() /*pvSubject*/,
    253257                                                    strServerCertificate.c_str(), strServerPrivateKey.c_str(), NULL /*pErrInfo*/);
    254258    if (RT_SUCCESS(vrc))
     
    281285}
    282286
     287/**
     288 * Checks validity of auto-generated certificates, sets VRDE properties, and deletes files if necessary.
     289 *
     290 * @note Locks this object for writing.
     291 */
     292int VRDEServer::certificateRepair(BOOL &certificateGenerated)
     293{
     294    int vrc = VINF_SUCCESS;
     295    if ( (mData->mapProperties["Security/Method"] != "RDP" || mData->mapProperties["Security/Method"] != "None"))
     296    {
     297        Utf8Str strServerCertificate("VRDEAutoGeneratedCert.pem");
     298        vrc = mParent->i_calculateFullPath(strServerCertificate, strServerCertificate);
     299        AssertRCReturn(vrc, vrc);
     300
     301        Utf8Str strServerPrivateKey("VRDEAutoGeneratedPrivateKey.pem");
     302        vrc = mParent->i_calculateFullPath(strServerPrivateKey, strServerPrivateKey);
     303        AssertRCReturn(vrc, vrc);
     304
     305        if ( RTFileExists(strServerPrivateKey.c_str()) && RTFileExists(strServerCertificate.c_str()) )
     306        {
     307            /* Check validity of certificate */
     308            RTCRX509CERTIFICATE pCertificate;
     309            BOOL validCert = false;
     310            vrc = RTCrX509Certificate_ReadFromFile(&pCertificate, strServerCertificate.c_str(), RTCRX509CERT_READ_F_PEM_ONLY,
     311                                                   &g_RTAsn1DefaultAllocator, NULL);
     312            if(RT_FAILURE(vrc))
     313            {
     314                RTCrX509Certificate_Delete(&pCertificate);
     315                return setError(VBOX_E_IPRT_ERROR, tr("Failed to read server certificate: (%Rrc)\n"), vrc);
     316            }
     317
     318            RTTIMESPEC Now;
     319            if ( RTCrX509Validity_IsValidAtTimeSpec(&(&pCertificate)->TbsCertificate.Validity, RTTimeNow(&Now)) )
     320                validCert = true;
     321
     322            RTCrX509Certificate_Delete(&pCertificate);
     323
     324            Utf8Str strPath = mData->mapProperties["Security/ServerCertificate"];
     325            if ( strPath.isEmpty() && validCert )
     326            {
     327                /*
     328                 * Valid auto-generated certificate and private key files exist but are not assigned to vm property
     329                 */
     330                AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     331                mData.backup();
     332                mData->mapProperties["Security/Method"] = Utf8Str("TLS");
     333                mData->mapProperties["Security/ServerCertificate"] = strServerCertificate;
     334                mData->mapProperties["Security/ServerPrivateKey"] = strServerPrivateKey;
     335                /* Done with the properties access. */
     336                alock.release();
     337                certificateGenerated = true;
     338                RTCrX509Certificate_Delete(&pCertificate);
     339            }
     340            else if ( (strPath.isEmpty() || strstr(strPath.c_str(),"VRDEAutoGeneratedCert.pem")) && !validCert)
     341            {
     342                /* Certificate is not valid so delete the files and create new ones */
     343                RTFileDelete(strServerPrivateKey.c_str());
     344                RTFileDelete(strServerCertificate.c_str());
     345                vrc = i_generateServerCertificate();
     346                if (RT_FAILURE(vrc))
     347                {
     348                    RTCrX509Certificate_Delete(&pCertificate);
     349                    i_rollback();
     350                    return setError(VBOX_E_IPRT_ERROR, tr("Failed to auto generate server key and certificate: (%Rrc)\n"), vrc);
     351                }
     352                certificateGenerated = true;
     353            }
     354        }
     355        else if (RTFileExists(strServerPrivateKey.c_str())) /* If only one of cert/key pair exists */
     356        {
     357            RTFileDelete(strServerPrivateKey.c_str());
     358            vrc = i_generateServerCertificate();
     359            if (RT_FAILURE(vrc))
     360            {
     361                i_rollback();
     362                return setError(VBOX_E_IPRT_ERROR, tr("Failed to auto generate server key and certificate: (%Rrc)\n"), vrc);
     363            }
     364            certificateGenerated = true;
     365        }
     366        else if (RTFileExists(strServerCertificate.c_str()))
     367        {
     368            RTFileDelete(strServerCertificate.c_str());
     369            vrc = i_generateServerCertificate();
     370            if (RT_FAILURE(vrc))
     371            {
     372                i_rollback();
     373                return setError(VBOX_E_IPRT_ERROR, tr("Failed to auto generate server key and certificate: (%Rrc)\n"), vrc);
     374            }
     375            certificateGenerated = true;
     376        }
     377        else
     378        {
     379            /*
     380             * Auto-generated certificate and key files do not exist
     381             * If the server certificate property is not set
     382             * or indicates an auto-generated certificate should exist, create one
     383             */
     384            Utf8Str strPath = mData->mapProperties["Security/ServerCertificate"];
     385            if (strPath.isEmpty() || strstr(strPath.c_str(),"VRDEAutoGeneratedCert.pem"))
     386            {
     387                vrc = i_generateServerCertificate();
     388                if (RT_FAILURE(vrc))
     389                {
     390                    i_rollback();
     391                    return setError(VBOX_E_IPRT_ERROR, tr("Failed to auto generate server key and certificate: (%Rrc)\n"), vrc);
     392                }
     393                certificateGenerated = true;
     394            }
     395        }
     396    }
     397    return vrc;
     398}
     399
    283400// IVRDEServer properties
    284401/////////////////////////////////////////////////////////////////////////////
     
    312429
    313430        /*
    314          * If TLS is not explicitly disabled and there is not an existing certificate
     431         * If enabling VRDE and TLS is not explicitly disabled
     432         * and there is not an existing certificate
    315433         * then auto-generate a self-signed certificate for this VM.
    316434         */
    317         Utf8Str strPath = mData->mapProperties["Security/ServerCertificate"];
    318         if (aEnabled && strPath.isEmpty())
    319         {
    320             if (mData->mapProperties["Security/Method"] != "RDP")
    321             {
    322                 int vrc = i_generateServerCertificate();
    323                 if (RT_FAILURE(vrc))
    324                     LogRel(("Failed to auto generate server key and certificate: (%Rrc)\n", vrc));
    325             }
     435        if (aEnabled)
     436        {
     437            BOOL certificateGenerated = false;
     438            int vrc = certificateRepair(certificateGenerated);
     439            if (RT_FAILURE(vrc))
     440                LogRel((("Failed to auto generate server key and certificate: (%Rrc)\n"), vrc));
    326441        }
    327442
     
    514629HRESULT VRDEServer::getVRDEProperty(const com::Utf8Str &aKey, com::Utf8Str &aValue)
    515630{
     631    /* Special case for the server certificate because it might be created automatically by the code below. */
     632    if (   aKey == "Security/ServerCertificate"
     633        || aKey == "Security/ServerPrivateKey")
     634    {
     635        BOOL certificateGenerated = false;
     636        int vrc = certificateRepair(certificateGenerated);
     637        if ( RT_FAILURE(vrc) )
     638            LogRel((("Failed to auto generate server key and certificate: (%Rrc)\n"), vrc));
     639        else if (certificateGenerated)
     640        {
     641            AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS);
     642            mParent->i_setModified(Machine::IsModified_VRDEServer);
     643            mlock.release();
     644        }
     645    }
    516646    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    517647    settings::StringsMap::const_iterator it = mData->mapProperties.find(aKey);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette