Exemple #1
0
DWORD
VMCARestServiceStartup(
    VOID
    )
{
    DWORD dwError = 0;

    dwError = _VMCAHttpServiceStartup();
    BAIL_ON_VMREST_ERROR(dwError);

    dwError = _VMCAHttpsServiceStartup();
    //soft fail
    if (dwError != 0)
    {
        VMCA_LOG_ERROR("%s: failure while starting HTTPS service(expected before promote), error: %d",
                __FUNCTION__, dwError);
        dwError = 0;
    }

cleanup:
    return dwError;

error:
    VMCA_LOG_ERROR("%s: failure while starting REST service, error: %d", __FUNCTION__, dwError);
    goto cleanup;

}
Exemple #2
0
DWORD
VMCARestServerInit(
    VOID
    )
{
    DWORD dwError = 0;

    MODULE_REG_MAP stRegMap[] =
    {
        //{"endpoint", VMCARestFunctionModule},
        {NULL, NULL}
    };

    /*
     * We can use the same REST_API_SPEC for both HTTP and HTTPS
     * if the rest init code refers to common API definitions
     */
    dwError = coapi_load_from_file(REST_API_SPEC, &gpVMCARestApiDef);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = coapi_map_api_impl(gpVMCARestApiDef, stRegMap);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCAOpensslInit();
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = _VMCARestServerInitHTTPS();
    if (dwError != 0)
    {
        /*
         * Before promoting lightwave node, obtaining cert from VECS will fail which is expected
         * hence treat it as soft fail
         */
         VMCA_LOG_WARNING(
                 "VmRESTServerInit: HTTPS port init failed with error %d, (failure is expected before promote)",
                 dwError);
         dwError = 0;
    }

cleanup:
    return dwError;

error:
    if (VMCARestServerStop() == 0)
    {
        VMCARestServerShutdown();
    }
    VMCA_LOG_ERROR(
            "%s failed, error (%d)",
            __FUNCTION__,
            dwError);

    goto cleanup;
}
Exemple #3
0
static
DWORD
VMCASrvUpdateRootCerts(
    PVMCA_DIR_SYNC_PARAMS pDirSyncParams,
    PBOOLEAN              pbSynced
    )
{
    DWORD dwError = 0;
    PVMCA_X509_CA pCA = NULL;
    PSTR pszAccount = NULL;
    PSTR pszPassword = NULL;
    PSTR pszDomainName = NULL;
    PSTR pszCAContainerDN = NULL;
    PSTR pszCertificate = NULL;
    PSTR pszCRL = NULL;
    X509_CRL* pCrl = NULL;
    DWORD dwCount = 0;
    DWORD dwIndex = 0;
    PVMCA_LDAP_CONTEXT pContext = NULL;
    PSTR pszUPN = NULL;

    dwError = VMCASrvValidateCA();
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCASrvGetCA(&pCA);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCASrvGetMachineAccountInfoA(
                &pszAccount,
                &pszDomainName,
                &pszPassword);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCAAllocateStringPrintfA(
                &pszUPN,
                "%s@%s",
                pszAccount,
                pszDomainName);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCALdapConnect(
                    "localhost",
                    0, /* use default port */
                    pszUPN,
                    pszPassword,
                    &pContext);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCAGetDSERootAttribute(
                    pContext,
                    "configurationNamingContext",
                    &pszCAContainerDN);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VmcaSrvReGenCRL(
                     &pCrl
                     );
    BAIL_ON_VMCA_ERROR (dwError);

    dwError = VMCACRLToPEM(
                            pCrl,
                            &pszCRL
                          );
    BAIL_ON_VMCA_ERROR (dwError);

    dwCount = sk_X509_num(pCA->skCAChain);

    for (; dwIndex <dwCount; dwIndex++)
    {
        X509 *pCert = sk_X509_value(
                                    pCA->skCAChain,
                                    dwIndex
                                   );

        dwError = VMCAUpdatePkiCAAttribute(
                                           pContext,
                                           pszCAContainerDN,
                                           pCert
                                          );
        BAIL_ON_VMCA_ERROR(dwError);
    }

    dwError = VMCAUpdateCrlCAAttribute(
                    pContext,
                    pszCAContainerDN,
                    pszCRL
                    );
    BAIL_ON_VMCA_ERROR (dwError);

    *pbSynced = TRUE;

cleanup:

    VMCA_SAFE_FREE_STRINGA(pszUPN);
    VMCA_SAFE_FREE_STRINGA(pszDomainName);
    VMCA_SAFE_FREE_STRINGA(pszCertificate);
    VMCA_SAFE_FREE_STRINGA(pszAccount);
    VMCA_SAFE_FREE_STRINGA(pszPassword);
    VMCA_SAFE_FREE_STRINGA(pszCRL);

    if (pContext)
    {
        VMCALdapClose(pContext);
    }
    if (pCA)
    {
        VMCAReleaseCA(pCA);
    }

    return dwError;

error:

    *pbSynced = FALSE;

    VMCA_LOG_ERROR("Failed to update root certs due to error [%u]", dwError);

    // TODO : Check specific errors

    dwError = 0;

    goto cleanup;
}
Exemple #4
0
static
PVOID
VMCASrvDirSyncThrFunc(
    PVOID pData
    )
{
    DWORD dwError = 0;
    PVMCA_THREAD_DATA pThrData = (PVMCA_THREAD_DATA)pData;
    PVMCA_DIR_SYNC_PARAMS pDirSyncParams = NULL;
    BOOLEAN bShutdown = FALSE;

    VMCA_LOG_INFO("Directory sync thread starting");

    pDirSyncParams = VMCASrvAcquireDirSyncParams(
                        (PVMCA_DIR_SYNC_PARAMS)pThrData->pData);
    if (!pDirSyncParams)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    while (!bShutdown)
    {
        BOOLEAN bSynced   = FALSE;

        dwError = VMCACheckThreadShutdown(pThrData, &bShutdown);
        BAIL_ON_VMCA_ERROR(dwError);

        if (!bShutdown)
        {
            dwError = VMCASrvUpdateRootCerts(pDirSyncParams, &bSynced);
            BAIL_ON_VMCA_ERROR(dwError);

        }

        dwError = VMCACheckThreadShutdown(pThrData, &bShutdown);
        BAIL_ON_VMCA_ERROR(dwError);

        if (!bShutdown)
        {
            DWORD dwIntervalSecs = 60; // wait a minute on sync failure

            if (bSynced)
            {
                dwError = VMCASrvGetDirSyncNotifyInterval(
                                pDirSyncParams,
                                &dwIntervalSecs);
                BAIL_ON_VMCA_ERROR(dwError);
            }

            dwError = VMCAWaitNotifyThread(pThrData, dwIntervalSecs);
            if (dwError == ETIMEDOUT)
            {
                dwError = 0;
            }
            BAIL_ON_VMCA_ERROR(dwError);
        }
    }

cleanup:

    if (pDirSyncParams)
    {
        VMCASrvReleaseDirSyncParams(pDirSyncParams);
    }

    VMCA_LOG_INFO("Directory sync thread exiting");

    return NULL;

error:

    VMCA_LOG_ERROR("Directory sync thread exiting due to error [%u]", dwError);

    goto cleanup;
}
Exemple #5
0
DWORD
VMCAPolicySNLoad(
    json_t                          *pJsonRules,
    PVMCA_POLICY                    pPolicy
    )
{
    DWORD                           dwError = 0;
    json_t                          *pJsonRulesMatch = NULL;
    json_t                          *pJsonRulesValidate = NULL;
    VMCA_POLICY_RULES               rules = { 0 };

    if (!pJsonRules || !pPolicy)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    if (!(pJsonRulesMatch = json_object_get(pJsonRules, "match")))
    {
        VMCA_LOG_ERROR(
            "[%s,%d] Failed to get SN policy match rule from config (%s)",
            __FUNCTION__,
            __LINE__,
            VMCA_POLICY_FILE_PATH);
        dwError = VMCA_JSON_PARSE_ERROR;
        BAIL_ON_JSON_PARSE_ERROR(dwError);
    }

    if (!(pJsonRulesValidate  = json_object_get(pJsonRules, "validate")))
    {
        VMCA_LOG_ERROR(
            "[%s,%d] SN policy must have either validate rule or action rule in config (%s)",
            __FUNCTION__,
            __LINE__,
            VMCA_POLICY_FILE_PATH);
        dwError = VMCA_JSON_PARSE_ERROR;
        BAIL_ON_JSON_PARSE_ERROR(dwError);
    }

    dwError = VMCAPolicySNMatchOperationParse(
                            pJsonRulesMatch,
                            &rules.SN.pMatch);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCAPolicySNValidateOperationParse(
                            pJsonRulesValidate,
                            &rules.SN.dwValidateLen,
                            &rules.SN.ppValidate);
    BAIL_ON_VMCA_ERROR(dwError);

    rules.SN.bEnabled = TRUE;


    pPolicy->Rules = rules;


cleanup:

    return dwError;

error:

    VMCAPolicySNFree(&rules);
    if (pPolicy)
    {
        pPolicy->Rules.SN.bEnabled = FALSE;
        VMCAPolicySNOperationFree(pPolicy->Rules.SN.pMatch);
        VMCAPolicySNOperationArrayFree(pPolicy->Rules.SN.ppValidate, pPolicy->Rules.SN.dwValidateLen);
        pPolicy->Rules.SN.dwValidateLen = 0;
    }

    goto cleanup;
}
Exemple #6
0
static
DWORD
VMCAPolicySNValidateOperationParse(
    json_t                          *pJsonRule,
    PDWORD                          pdwOperationsLen,
    PVMCA_SNPOLICY_OPERATION        **pppOperations
    )
{
    DWORD                           dwError = 0;
    DWORD                           dwIdx = 0;
    PCSTR                           pcszDataTemp = NULL;
    PCSTR                           pcszWithTemp = NULL;
    size_t                          szArrayLen = 0;
    json_t                          *pJsonTemp = NULL;
    json_t                          *pJsonDataTemp = NULL;
    json_t                          *pJsonWithTemp = NULL;
    PVMCA_SNPOLICY_OPERATION        *ppOperations = NULL;

    if (!pJsonRule || !pppOperations)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    if (!json_is_array(pJsonRule))
    {
        VMCA_LOG_ERROR(
            "[%s,%d] SN policy validate rule in config (%s) must be an array",
            __FUNCTION__,
            __LINE__,
            VMCA_POLICY_FILE_PATH);
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    szArrayLen = json_array_size(pJsonRule);
    if (szArrayLen < 1)
    {
        VMCA_LOG_ERROR(
            "[%s,%d] SN policy rule validate in config (%s) must be an array with at least 1 object",
            __FUNCTION__,
            __LINE__,
            VMCA_POLICY_FILE_PATH);
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    dwError = VMCAAllocateMemory(
                        sizeof(PVMCA_SNPOLICY_OPERATION) * (DWORD)szArrayLen,
                        (PVOID *)&ppOperations);
    BAIL_ON_VMCA_ERROR(dwError);

    json_array_foreach(pJsonRule, dwIdx, pJsonTemp)
    {
        if (!(pJsonDataTemp = json_object_get(pJsonTemp, "data")))
        {
            VMCA_LOG_ERROR(
                "[%s,%d] SN policy rule validate in config (%s) must have \"data\" clause",
                __FUNCTION__,
                __LINE__,
                VMCA_POLICY_FILE_PATH);
            dwError = VMCA_JSON_PARSE_ERROR;
            BAIL_ON_JSON_PARSE_ERROR(dwError);
        }

        if (!(pJsonWithTemp = json_object_get(pJsonTemp, "with")))
        {
            VMCA_LOG_ERROR(
                "[%s,%d] SN policy validate rule in config (%s) must have \"with\" clause",
                __FUNCTION__,
                __LINE__,
                VMCA_POLICY_FILE_PATH);
            dwError = VMCA_JSON_PARSE_ERROR;
            BAIL_ON_JSON_PARSE_ERROR(dwError);
        }

        pcszDataTemp = json_string_value(pJsonDataTemp);
        if (IsNullOrEmptyString(pcszDataTemp))
        {
            VMCA_LOG_ERROR(
                "[%s,%d] SN policy validate rule in config (%s) cannot have empty \"data\" clause",
                __FUNCTION__,
                __LINE__,
                VMCA_POLICY_FILE_PATH);
            dwError = VMCA_POLICY_CONFIG_ERROR;
            BAIL_ON_VMCA_ERROR(dwError);
        }
        if (VMCAStringCompareA(pcszDataTemp, VMCA_POLICY_REQ_CSR_SUBJ_ORGS, TRUE))
        {
            VMCA_LOG_ERROR(
                "[%s,%d] Unknown SN policy validate rule \"data\" value. (%s)",
                __FUNCTION__,
                __LINE__,
                pcszDataTemp);
            dwError = VMCA_POLICY_CONFIG_ERROR;
            BAIL_ON_VMCA_ERROR(dwError);
        }

        pcszWithTemp = json_string_value(pJsonWithTemp);
        if (IsNullOrEmptyString(pcszWithTemp))
        {
            VMCA_LOG_ERROR(
                "[%s,%d] SN policy validate rule in config (%s) cannot have empty \"with\" clause",
                __FUNCTION__,
                __LINE__,
                VMCA_POLICY_FILE_PATH);
            dwError = VMCA_POLICY_CONFIG_ERROR;
            BAIL_ON_VMCA_ERROR(dwError);
        }
        if (VMCAStringCompareA(pcszWithTemp, VMCA_POLICY_REQ_UPN_RDN, TRUE))
        {
            VMCA_LOG_ERROR(
                "[%s,%d] Unknown SN policy validate rule \"with\" value. (%s)",
                __FUNCTION__,
                __LINE__,
                pcszWithTemp);
            dwError = VMCA_POLICY_CONFIG_ERROR;
            BAIL_ON_VMCA_ERROR(dwError);
        }

        dwError = VMCAAllocateMemory(
                            sizeof(VMCA_SNPOLICY_OPERATION),
                            (PVOID *)&ppOperations[dwIdx]);
        BAIL_ON_VMCA_ERROR(dwError);

        dwError = VMCAAllocateStringA(
                            pcszWithTemp,
                            &ppOperations[dwIdx]->pszWith);
        BAIL_ON_VMCA_ERROR(dwError);

        dwError = VMCAAllocateStringA(
                            pcszDataTemp,
                            &ppOperations[dwIdx]->pszData);
        BAIL_ON_VMCA_ERROR(dwError);
    }

    *pdwOperationsLen   = (DWORD)szArrayLen;
    *pppOperations      = ppOperations;

cleanup:

    return dwError;

error:

    VMCAPolicySNOperationArrayFree(ppOperations, (DWORD)szArrayLen);
    if (pppOperations)
    {
        *pppOperations = NULL;
    }

    goto cleanup;
}
Exemple #7
0
static
DWORD
VMCAPolicySNMatchOperationParse(
    json_t                          *pJsonRule,
    PVMCA_SNPOLICY_OPERATION        *ppOperation
    )
{
    DWORD                           dwError = 0;
    PCSTR                           pcszDataTemp = NULL;
    PCSTR                           pcszConditionTemp = NULL;
    PCSTR                           pcszWithTemp = NULL;
    json_t                          *pJsonDataTemp = NULL;
    json_t                          *pJsonWithTemp = NULL;
    json_t                          *pJsonConditionTemp = NULL;
    PVMCA_SNPOLICY_OPERATION        pOperation = NULL;

    if (!pJsonRule || !ppOperation)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    if (!(pJsonDataTemp = json_object_get(pJsonRule, "data")))
    {
        VMCA_LOG_ERROR(
            "[%s,%d] SN policy match rule in config (%s) must have \"data\" clause",
            __FUNCTION__,
            __LINE__,
            VMCA_POLICY_FILE_PATH);
        dwError = VMCA_JSON_PARSE_ERROR;
        BAIL_ON_JSON_PARSE_ERROR(dwError);
    }

    if (!(pJsonConditionTemp = json_object_get(pJsonRule, "condition")))
    {
        VMCA_LOG_ERROR(
            "[%s,%d] SN policy match rule in config (%s) must have \"condition\" clause",
            __FUNCTION__,
            __LINE__,
            VMCA_POLICY_FILE_PATH);
        dwError = VMCA_JSON_PARSE_ERROR;
        BAIL_ON_JSON_PARSE_ERROR(dwError);
    }

    if (!(pJsonWithTemp = json_object_get(pJsonRule, "with")))
    {
        VMCA_LOG_ERROR(
            "[%s,%d] SN policy match rule in config (%s) must have \"with\" clause",
            __FUNCTION__,
            __LINE__,
            VMCA_POLICY_FILE_PATH);
        dwError = VMCA_JSON_PARSE_ERROR;
        BAIL_ON_JSON_PARSE_ERROR(dwError);
    }

    pcszDataTemp = json_string_value(pJsonDataTemp);
    if (IsNullOrEmptyString(pcszDataTemp))
    {
        VMCA_LOG_ERROR(
            "[%s,%d] SN policy match rule in config (%s) cannot have empty \"data\" clause",
            __FUNCTION__,
            __LINE__,
            VMCA_POLICY_FILE_PATH);
        dwError = VMCA_POLICY_CONFIG_ERROR;
        BAIL_ON_VMCA_ERROR(dwError);
    }
    if (VMCAStringCompareA(pcszDataTemp, VMCA_POLICY_REQ_UPN_DN, TRUE))
    {
        VMCA_LOG_ERROR(
            "[%s,%d] Unknown SN policy match rule \"data\" value. (%s)",
            __FUNCTION__,
            __LINE__,
            pcszDataTemp);
        dwError = VMCA_POLICY_CONFIG_ERROR;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    pcszConditionTemp = json_string_value(pJsonConditionTemp);
    if (IsNullOrEmptyString(pcszConditionTemp))
    {
        VMCA_LOG_ERROR(
            "[%s,%d] SN policy match rule in config (%s) cannot have empty \"condition\" clause",
            __FUNCTION__,
            __LINE__,
            VMCA_POLICY_FILE_PATH);
        dwError = VMCA_POLICY_CONFIG_ERROR;
        BAIL_ON_VMCA_ERROR(dwError);
    }
    if (VMCAStringCompareA(pcszConditionTemp, VMCA_POLICY_COND_BEGINS, TRUE))
    {
        VMCA_LOG_ERROR(
            "[%s,%d] Unknown SN policy match rule \"condition\" value. (%s)",
            __FUNCTION__,
            __LINE__,
            pcszConditionTemp);
        dwError = VMCA_POLICY_CONFIG_ERROR;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    pcszWithTemp = json_string_value(pJsonWithTemp);
    if (IsNullOrEmptyString(pcszWithTemp))
    {
        VMCA_LOG_ERROR(
            "[%s,%d] SN policy match rule in config (%s) cannot have empty \"with\" clause",
            __FUNCTION__,
            __LINE__,
            VMCA_POLICY_FILE_PATH);
        dwError = VMCA_POLICY_CONFIG_ERROR;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    dwError = VMCAAllocateMemory(
                        sizeof(VMCA_SNPOLICY_OPERATION),
                        (PVOID *)&pOperation);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCAAllocateStringA(
                        pcszWithTemp,
                        &pOperation->pszWith);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCAAllocateStringA(
                        pcszConditionTemp,
                        &pOperation->pszCondition);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCAAllocateStringA(
                        pcszDataTemp,
                        &pOperation->pszData);
    BAIL_ON_VMCA_ERROR(dwError);


    *ppOperation = pOperation;


cleanup:

    return dwError;

error:

    VMCAPolicySNOperationFree(pOperation);
    if (ppOperation)
    {
        *ppOperation = NULL;
    }

    goto cleanup;

}
Exemple #8
0
static
DWORD
_VMCAGetSSLCert(
    VMCA_LIB_HANDLE plibHandle,
    PSTR*           ppszCert,
    PSTR*           ppszKey
    )
{
    DWORD   dwError = 0;
    PSTR    pszCert = NULL;
    PSTR    pszKey = NULL;
    PVECS_STORE         pVECSStore = NULL;
    PVECS_CERT_ENTRY_A  pCertEntry = NULL;

    if (plibHandle == NULL || ppszCert == NULL || ppszKey == NULL)
    {
        dwError = VMCA_ARGUMENT_ERROR;
        goto cleanup;
    }

    fpVecsOpenCertStoreA    fpOpenStore = NULL;
    fpVecsGetEntryByAliasA  fpGetEntry = NULL;
    fpVecsGetKeyByAliasA    fpGetKey = NULL;
    fpVecsCloseCertStore    fpCloseStore = NULL;
    fpVecsFreeCertEntryA    fpFreeEntry = NULL;

    if ( (fpOpenStore = (fpVecsOpenCertStoreA) VMCAGetLibSym(plibHandle, FN_VECS_OPEN_CERT_STORE_A) ) == NULL
          ||
         (fpGetEntry = (fpVecsGetEntryByAliasA) VMCAGetLibSym(plibHandle, FN_VECS_GET_ENTRY_BY_ALIAS_A) ) == NULL
          ||
         (fpGetKey = (fpVecsGetKeyByAliasA) VMCAGetLibSym(plibHandle, FN_VECS_GET_KEY_BY_ALIAS_A) ) == NULL
          ||
         (fpCloseStore = (fpVecsCloseCertStore) VMCAGetLibSym(plibHandle, FN_VECS_CLOSE_CERT_STORE) ) == NULL
          ||
         (fpFreeEntry = (fpVecsFreeCertEntryA) VMCAGetLibSym(plibHandle, FN_VECS_FREE_ENTRY_A) ) == NULL
       )
    {
#ifdef _WIN32
        VMCA_LOG_ERROR("VECS sym lookup failed, %d", WSAGetLastError());
#else
        VMCA_LOG_ERROR("VECS sym lookup failed, %s", VMCA_SAFE_STRING(dlerror()));
#endif
        dwError = VMCA_UNKNOW_ERROR;
    }
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = (*fpOpenStore)( "localhost", MACHINE_CERT_STORE_NAME, NULL, &pVECSStore );
    BAIL_ON_VECS_ERROR(dwError);

    dwError = (*fpGetEntry)( pVECSStore, MACHINE_CERT_ALIAS, ENTRY_INFO_LEVEL_2, &pCertEntry );
    BAIL_ON_VECS_ERROR(dwError);

    dwError = (*fpGetKey)( pVECSStore, MACHINE_CERT_ALIAS, NULL, &pszKey );
    BAIL_ON_VECS_ERROR(dwError);

    dwError = VMCAAllocateStringA( pCertEntry->pszCertificate, &pszCert );
    BAIL_ON_VECS_ERROR(dwError);

    *ppszCert = pszCert;
    *ppszKey  = pszKey;

cleanup:

    if ( fpFreeEntry && pCertEntry )
    {
        (*fpFreeEntry)(pCertEntry);
    }

    if ( fpCloseStore && pVECSStore )
    {
        (*fpCloseStore)(pVECSStore);
    }

    return dwError;

error:
    *ppszCert = NULL;
    *ppszKey = NULL;
    VMCA_SAFE_FREE_MEMORY(pszCert);
    VMCA_SAFE_FREE_MEMORY(pszKey);

    VMCA_LOG_ERROR("%s failed, error (%u)", __FUNCTION__, dwError);

    goto cleanup;

vecs_error:
    goto cleanup;
}
Exemple #9
0
static
DWORD
_VMCARestServerInitHTTPS(
    VOID
    )
{
    DWORD               dwError = 0;
    REST_CONF           config = {0};
    PREST_PROCESSOR     pHandlers = &sVMCARestApiHandlers;
    PREST_API_MODULE    pModule = NULL;
    PVMREST_HANDLE      pHTTPSHandle = NULL;

    config.serverPort = VMCA_HTTPS_V2_PORT_NUM;
    config.connTimeoutSec = VMCA_REST_CONN_TIMEOUT_SEC;
    config.maxDataPerConnMB = VMCA_MAX_DATA_PER_CONN_MB;
    config.pSSLContext = gVMCAServerGlobals.gpVMCASslCtx;
    config.nWorkerThr = VMCA_REST_WORKERTHCNT;
    config.nClientCnt = VMCA_REST_CLIENTCNT;
    config.SSLCtxOptionsFlag = 0;
    config.pszSSLCertificate = NULL;
    config.pszSSLKey = NULL;
    config.pszSSLCipherList = NULL;
    config.pszDebugLogFile = NULL;
    config.pszDaemonName = VMCA_DAEMON_NAME;
    config.isSecure = TRUE;
    config.useSysLog = TRUE;
    config.debugLogLevel = VMCAToCRestEngineLogLevel();

    dwError = VmRESTInit(&config, &pHTTPSHandle);
    BAIL_ON_VMCA_ERROR(dwError);

    for (pModule = gpVMCARestApiDef->pModules; pModule; pModule = pModule->pNext)
    {
        PREST_API_ENDPOINT pEndPoint = pModule->pEndPoints;
        for (; pEndPoint; pEndPoint = pEndPoint->pNext)
        {
            dwError = VmRESTRegisterHandler(
                    pHTTPSHandle, pEndPoint->pszName, pHandlers, NULL);
            BAIL_ON_VMCA_ERROR(dwError);
        }
    }

    dwError = VmRESTStart(pHTTPSHandle);
    BAIL_ON_VMCA_ERROR(dwError);

    gpVMCARestHTTPSHandle = pHTTPSHandle;

cleanup:
    return dwError;

error:
    if (_VMCAStopRestHandle(pHTTPSHandle) == 0)
    {
        _VMCAFreeRestHandle(pHTTPSHandle, gpVMCARestApiDef);
    }
    VMCA_LOG_ERROR(
            "%s failed, error (%d)",
            __FUNCTION__,
            dwError);

    goto cleanup;
}
Exemple #10
0
DWORD
VMCACopyTempCRLtoCRL()
{
    DWORD dwError = 0;
    PSTR pszTmpFile = NULL;
    PSTR pszCRLFile = NULL;
    BOOLEAN bLocked = FALSE;
    FILE* pIn = NULL;
    FILE* pOut = NULL;

    dwError = VMCAGetCRLNamePath(&pszCRLFile);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCAGetTempCRLNamePath(&pszTmpFile);
    BAIL_ON_VMCA_ERROR(dwError);

    VMCA_LOCK_MUTEX_EXCLUSIVE(&gVMCAServerGlobals.svcMutex, bLocked);

    if ((pIn = fopen(pszTmpFile, "rb")) == NULL)
    {
        dwError = LwErrnoToWin32Error(errno);

        VMCA_LOG_ERROR("Failed to open file [%s] for reading", pszTmpFile);

        BAIL_ON_VMCA_ERROR(dwError);
    }
    if ((pOut = fopen(pszCRLFile, "wb")) == NULL)
    {
        dwError = LwErrnoToWin32Error(errno);

        VMCA_LOG_ERROR("Failed to open file [%s] for writing", pszCRLFile);

        BAIL_ON_VMCA_ERROR(dwError);
    }

    while (!feof(pIn))
    {
        CHAR   szBuf[4096];
        size_t nRead = 0;
        
        nRead = fread(&szBuf[0], sizeof(szBuf[0]), sizeof(szBuf), pIn);

        if (nRead > 0)
        {
            size_t  nWritten = fwrite(&szBuf[0], sizeof(szBuf[0]), nRead, pOut);

            if (nWritten != nRead)
            {
#ifndef _WIN32
                dwError = LwErrnoToWin32Error(errno);
#else
                dwError = GetLastError();
#endif
                BAIL_ON_VMCA_ERROR(dwError);
            }
        }
    }

cleanup:

    VMCA_LOCK_MUTEX_UNLOCK(&gVMCAServerGlobals.svcMutex, bLocked);

    if (pIn)
    {
        fclose(pIn);
    }
    if (pOut)
    {
        fclose(pOut);
    }
    VMCA_SAFE_FREE_STRINGA(pszCRLFile);
    VMCA_SAFE_FREE_STRINGA(pszTmpFile);

    return dwError;

error:

    // TODO : Should we delete a partially written file?

    VMCA_LOG_ERROR("Failed to copy temporary CRL [Error code: %u ]", dwError);

    dwError = VMCA_FILE_IO_ERROR;

    goto cleanup;
}
Exemple #11
0
static
DWORD
_VMCAHttpsServiceStartup(
    VOID
    )
{
    DWORD dwError = 0;
    DWORD iter = 0;
    DWORD endPointCnt = 0;
    REST_CONF config = {0};
    PSTR  pszCert = NULL;
    PSTR  pszKey = NULL;
    DWORD dwPort = 0;
    PREST_PROCESSOR pHandlers = &sVmcaRestHandlers;
    PVMREST_HANDLE  pHTTPSHandle = NULL;

    (VOID)VMCAGetRegKeyValueDword(
                  VMCA_KEY_PARAMETERS,//VMCA_CONFIG_PARAMETER_KEY_PATH,
                  VMCA_HTTPS_PORT_REG_KEY,
                  &dwPort,
                  VMCA_HTTPS_PORT_NUM
                  );

    // port value '0' indicates don't start HTTPS service
    if (dwPort == 0)
    {
        goto cleanup;
    }

    config.serverPort = dwPort;
    config.connTimeoutSec = VMCA_REST_CONN_TIMEOUT_SEC;
    config.maxDataPerConnMB = VMCA_MAX_DATA_PER_CONN_MB;
    config.pSSLContext = NULL;
    config.nWorkerThr = VMCA_REST_WORKER_TH_CNT;
    config.nClientCnt = VMCA_REST_CLIENT_CNT;
    config.SSLCtxOptionsFlag = 0;
    config.pszSSLCertificate = NULL;
    config.pszSSLKey = NULL;
    config.pszSSLCipherList = NULL;
    config.pszDebugLogFile = NULL;
    config.pszDaemonName = VMCA_DAEMON_NAME;
    config.isSecure = TRUE;
    config.useSysLog = TRUE;
    config.debugLogLevel = VMREST_LOG_LEVEL_ERROR;

    //Get Certificate and Key from VECS and Set it to Rest Engine
    dwError = VMCAGetVecsMachineCert(&pszCert, &pszKey);
    BAIL_ON_VMREST_ERROR(dwError);

    dwError = VmRESTInit(&config, &pHTTPSHandle);
    BAIL_ON_VMREST_ERROR(dwError);

    dwError = VmRESTSetSSLInfo(pHTTPSHandle, pszCert, VMCAStringLenA(pszCert)+1, SSL_DATA_TYPE_CERT);
    BAIL_ON_VMREST_ERROR(dwError);

    dwError = VmRESTSetSSLInfo(pHTTPSHandle, pszKey, VMCAStringLenA(pszKey)+1, SSL_DATA_TYPE_KEY);
    BAIL_ON_VMREST_ERROR(dwError);

    endPointCnt = ARRAY_SIZE(restEndPoints);

    for (iter = 0; iter < endPointCnt; iter++)
    {
        dwError = VmRESTRegisterHandler(
                pHTTPSHandle,
                restEndPoints[iter],
                pHandlers,
                NULL);
        BAIL_ON_VMREST_ERROR(dwError);
    }

    dwError = VmRESTStart(pHTTPSHandle);
    BAIL_ON_VMREST_ERROR(dwError);

    gpVMCAHTTPSHandle = pHTTPSHandle;

cleanup:
    VMCA_SAFE_FREE_MEMORY(pszCert);
    VMCA_SAFE_FREE_MEMORY(pszKey);
    return dwError;

error:
    _VMCARestFreeHandle(pHTTPSHandle);
    VMCA_LOG_ERROR("%s: failure while starting REST HTTPS service, error: %d", __FUNCTION__, dwError);
    goto cleanup;
}
Exemple #12
0
int
main(
    int   argc,
    char* argv[]
    )
{
    DWORD dwError = 0;
    const char* pszSmNotify = NULL;
    int notifyFd = -1;
    int notifyCode = 0;
    int ret = -1;
    BOOL bEnableSysLog = FALSE;
    BOOL bConsoleLogging = FALSE;

    setlocale(LC_ALL, "");

    VMCABlockSelectedSignals();

    dwError = VMCAParseArgs(argc, argv, &bEnableSysLog, &bConsoleLogging);
    BAIL_ON_VMCA_ERROR(dwError);

    if (bEnableSysLog)
    {
        gVMCALogType = VMCA_LOG_TYPE_SYSLOG;
    }
    else if (bConsoleLogging)
    {
        gVMCALogType = VMCA_LOG_TYPE_CONSOLE;
    }
    else
    {
        gVMCALogType = VMCA_LOG_TYPE_FILE;
    }

    dwError  = VMCAInitialize(0, 0);
    BAIL_ON_VMCA_ERROR(dwError);

    VMCA_LOG_INFO("VM Certificate Service started.");

#ifdef REST_ENABLED
#ifndef _WIN32
    dwError = VMCARestServiceStartup();
    BAIL_ON_VMCA_ERROR(dwError);
    VMCA_LOG_INFO("VM Certificate ReST Protocol started.");
#endif
#endif

    PrintCurrentState();

    // interact with likewise service manager (start/stop control)
    if ((pszSmNotify = getenv("LIKEWISE_SM_NOTIFY")) != NULL)
    {
        notifyFd = atoi(pszSmNotify);

        do
        {
            ret = write(notifyFd, &notifyCode, sizeof(notifyCode));

        } while (ret != sizeof(notifyCode) && errno == EINTR);

        if (ret < 0)
        {
            VMCA_LOG_ERROR("Could not notify service manager: %s (%i)",
                            strerror(errno),
                            errno);
            dwError = LwErrnoToWin32Error(errno);
            BAIL_ON_VMCA_ERROR(dwError);
        }

        close(notifyFd);
    }

    // main thread waits on signals
    dwError = VMCAHandleSignals();
    BAIL_ON_VMCA_ERROR(dwError);

    VMCA_LOG_INFO("VM Certificate Service exiting...");

cleanup:

    VMCAShutdown();
#ifdef REST_ENABLED
#ifndef _WIN32
    VMCARestServiceShutdown();
#endif
#endif
    return (dwError);

error:

    VMCA_LOG_ERROR("VM Certificate exiting due to error [code:%d]", dwError);

    goto cleanup;
}
Exemple #13
0
DWORD
VMCAUpdateCrlCAAttribute(
    PVMCA_LDAP_CONTEXT pContext,
    PSTR pszConfigurationDN,
    PSTR pszCrl
    )
{
    DWORD   dwError = 0;
    PSTR pszCADN = NULL;
    PSTR pszCrlAuthorityKeyId = NULL;
    PSTR pszCAContainerDN = NULL;
    X509_CRL* pCrl = NULL;
    ATTR_SEARCH_RESULT attrSearchResult = ATTR_NOT_FOUND;
    X509_NAME* pIssuer = NULL;
    PSTR pszCAIssuerDN = NULL;
    PSTR pszFoundCADN = NULL;

    dwError = VMCAPEMToX509Crl(pszCrl, &pCrl);
    BAIL_ON_ERROR(dwError);

    dwError = VMCAAllocateStringPrintfA(
                    &pszCAContainerDN,
                    "CN=%s,%s",
                    CA_CONTAINER_NAME,
                    pszConfigurationDN);
    BAIL_ON_ERROR(dwError);

    dwError = VMCAGetCrlAuthKeyIdHexString(pCrl, &pszCrlAuthorityKeyId);
    if (dwError == ERROR_SUCCESS)
    {
        if (!IsNullOrEmptyString(pszCrlAuthorityKeyId))
        {
            dwError = VMCAAllocateStringPrintfA(
                    &pszCADN,
                    "CN=%s,%s",
                    pszCrlAuthorityKeyId,
                    pszCAContainerDN);
            BAIL_ON_ERROR(dwError);
        }
    }

    if (!pszCADN)
    {
        pIssuer = X509_CRL_get_issuer(pCrl); // Don't free
        dwError = VMCAGetX509Name(pIssuer, XN_FLAG_COMPAT, &pszCAIssuerDN);
        BAIL_ON_ERROR(dwError);

        if (pszCAIssuerDN == NULL)
        {
            dwError = ERROR_INVALID_PARAMETER;
            BAIL_ON_ERROR(dwError);
        }
    }

    dwError = VMCACheckCAObject(
                    pContext,
                    pszCAContainerDN,
                    pszCADN,
                    pszCAIssuerDN,
                    &pszFoundCADN
                    );
    if (dwError == ERROR_INVALID_STATE && pszCAIssuerDN)
    {
        VMCA_LOG_ERROR("More than one CA found with given issuer DN: %s",
            pszCAIssuerDN);
    }
    BAIL_ON_ERROR(dwError);

    if (!pszFoundCADN)
    {
        dwError = ERROR_NOT_FOUND;
        BAIL_ON_ERROR(dwError);
    }

    dwError = VMCACheckAttribute(
            pContext,
            pszFoundCADN,
            ATTR_CRL,
            pszCrl,
            &attrSearchResult
            );
    BAIL_ON_ERROR(dwError);

    if (attrSearchResult != ATTR_MATCH)
    {
        dwError = VMCAUpdateAttribute(pContext, pszFoundCADN,
                ATTR_CRL, pszCrl,
                (attrSearchResult == ATTR_NOT_FOUND));
        BAIL_ON_ERROR(dwError);
    }

cleanup:

    VMCA_SAFE_FREE_MEMORY(pszFoundCADN);
    VMCA_SAFE_FREE_MEMORY(pszCAIssuerDN);
    VMCA_SAFE_FREE_STRINGA(pszCADN);
    VMCA_SAFE_FREE_STRINGA(pszCrlAuthorityKeyId);
    VMCA_SAFE_FREE_STRINGA(pszCAContainerDN);
    if (pCrl)
    {
        X509_CRL_free(pCrl);
    }
    return dwError;

error:

    goto cleanup;
}
Exemple #14
0
DWORD
VMCAConvertUPNToDN(
    PVMCA_LDAP_CONTEXT              pConnection,
    PCSTR                           pszUPN,
    PSTR*                           ppszOutDN
    )
{
    DWORD                           dwError = 0;
    LDAPMessage*                    pEntry = NULL;
    LDAPMessage*                    pResult = NULL;
    PSTR                            pszFilter = NULL;
    PSTR                            pszEntryDN = NULL;
    PSTR                            pszOutDN = NULL;
    int                             iCount = 0;
    LDAP                            *pLd = NULL;

    if (!pConnection ||
        !pConnection->pConnection ||
        IsNullOrEmptyString(pszUPN) ||
        !ppszOutDN)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    pLd = pConnection->pConnection;

    dwError = VMCAAllocateStringPrintfA(
                    &pszFilter, "%s=%s",
                    ATTR_KRB_UPN,
                    pszUPN);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = ldap_search_ext_s(
                    pLd,
                    "",
                    LDAP_SCOPE_SUBTREE,
                    pszFilter,
                    NULL,
                    FALSE, /* get values      */
                    NULL,  /* server controls */
                    NULL,  /* client controls */
                    NULL,  /* timeout         */
                    0,     /* size limit      */
                    &pResult);
    BAIL_ON_VMCA_ERROR(dwError);

    iCount = ldap_count_entries(pLd, pResult);

    // should have either 0 or 1 result
    if (iCount > 1)
    {
        dwError = VMCA_ERROR_INVALID_STATE;
        BAIL_ON_VMCA_ERROR(dwError);
    }
    else if (iCount == 0)
    {
        dwError = VMCA_ERROR_ENTRY_NOT_FOUND;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    if ( (pEntry = ldap_first_entry(pLd, pResult)) != NULL )
    {
        pszEntryDN = ldap_get_dn(pLd, pEntry);

        dwError = VMCAAllocateStringA( pszEntryDN, &pszOutDN );
        BAIL_ON_VMCA_ERROR(dwError);

        *ppszOutDN = pszOutDN;
    }
    else
    {
        dwError = VMCA_ERROR_INVALID_ENTRY;
        BAIL_ON_VMCA_ERROR(dwError);
    }

cleanup:

    if (pszEntryDN)
    {
        ldap_memfree( pszEntryDN );
    }
    if (pResult)
    {
        ldap_msgfree( pResult );
    }
    VMCA_SAFE_FREE_MEMORY(pszFilter);

    return dwError;

error:

    VMCA_LOG_ERROR("[%s,%d] failed with error (%u)", __FUNCTION__, __LINE__, dwError);

    VMCA_SAFE_FREE_MEMORY(pszOutDN);
    if (ppszOutDN)
    {
        *ppszOutDN = NULL;
    }
    goto cleanup;
}