예제 #1
0
static
VOID
_VMCAHttpsServiceShutdown(
    VOID
    )
{
    VMCA_LOG_INFO("%s: starting https rest server shutdown:", __FUNCTION__);

    _VMCARestFreeHandle(gpVMCAHTTPSHandle);
    gpVMCAHTTPSHandle = NULL;

    VMCA_LOG_INFO("%s: completed https rest server shutdown:", __FUNCTION__);
}
예제 #2
0
static
DWORD
InitializeDatabase(
    VOID
    )
{
    DWORD dwError = 0 ;
    PSTR pszCertDBPath = NULL;

    dwError = VMCACreateDataDirectory();
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCAGetCertsDBPath(&pszCertDBPath);
    BAIL_ON_VMCA_ERROR(dwError);

    VMCA_LOG_INFO(
            "Initializing database: [%s]",
            VMCA_SAFE_STRING(pszCertDBPath));

    dwError = VmcaDbInitialize(pszCertDBPath);
    BAIL_ON_VMCA_ERROR(dwError);

error:

    VMCA_SAFE_FREE_STRINGA(pszCertDBPath);

    return dwError;
}
예제 #3
0
DWORD
VMCACheckAccess(
    handle_t IDL_handle,
    BOOL bNeedAdminPrivilage
    )
{
    DWORD dwError = 0;
    rpc_authz_cred_handle_t hPriv = { 0 };
    DWORD dwProtectLevel = 0;
    ULONG rpc_status = rpc_s_ok;
    unsigned char *authPrinc = NULL;

    rpc_binding_inq_auth_caller(
                            IDL_handle,
                            &hPriv,
                            &authPrinc,
                            &dwProtectLevel,
                            NULL, /* unsigned32 *authn_svc, */
                            NULL, /* unsigned32 *authz_svc, */
                            &rpc_status);

    /* Deny if connection is not encrypted */
    if (dwProtectLevel < rpc_c_protect_level_pkt_privacy)
    {
        dwError = VMCA_KRB_ACCESS_DENIED;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    /* Deny if no auth identity is provided.  */
    if (rpc_status == rpc_s_binding_has_no_auth || !authPrinc || !*authPrinc)
    {
        dwError = VMCA_KRB_ACCESS_DENIED;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    VMCA_LOG_INFO("VMCACheckAccessKrb: Authenticated user %s", authPrinc);

    if (bNeedAdminPrivilage)
    {
        dwError = VMCALdapAccessCheck(authPrinc, VMCA_ADMINISTRATORS);
        BAIL_ON_VMCA_ERROR(dwError);
    }

error:
    if (authPrinc)
    {
        rpc_string_free((unsigned_char_t **)&authPrinc, &rpc_status);
    }
    return dwError;
}
예제 #4
0
파일: vecs.c 프로젝트: vmware/lightwave
DWORD
VMCAGetVecsMachineCert(
    PSTR*   ppszCert,
    PSTR*   ppszKey
    )
{
    DWORD            dwError = 0;
    VMCA_LIB_HANDLE  plibHandle = NULL;
    PSTR             pszCert = NULL;
    PSTR             pszKey = NULL;

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

    dwError = VMCAOpenVmAfdClientLib( &plibHandle );
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = _VMCAGetSSLCert( plibHandle, &pszCert, &pszKey );
    BAIL_ON_VMCA_ERROR(dwError);

    *ppszCert = pszCert;
    *ppszKey  = pszKey;

    VMCA_LOG_INFO("Acquired SSL Cert from VECS");

cleanup:
    VMCACloseLibrary( plibHandle );

    return dwError;

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

    goto cleanup;
}
예제 #5
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;
}
예제 #6
0
파일: snpolicy.c 프로젝트: vmware/lightwave
/*
 * VMCAPolicySNMatchAuthOUWithCSR is the heart of SN policy validation.
 *
 * It verifies if the CSR organizationName entries in the subjectName field comprise the DN of the requestor.
 *
 * Examples:
 *      * Pass:
 *          * Parameters:
 *              * Machine account DN: [email protected],ou=ex2,ou=ex1,ou=computers,dc=example,dc=com
 *              * organizationName entries: {ex1, ex2}
 *              * Config file match rule baseDN: ou=ex1,ou=computers,dc=example,dc=com
 *          * Result:
 *              * This will pass because the machine account lives under ou=ex2,ou=ex1 which is
 *              under the baseDN from the config file, and the CSR organizationName entries contain
 *              the OUs that the machine account lives under.
 *      * Pass:
 *          * Parameters:
 *              * Machine account DN: [email protected],ou=ex2,ou=ex1,ou=computers,dc=example,dc=com
 *              * organizationName entries: {ex2, ex1}
 *              * Config file match rule baseDN: ou=ex1,ou=computers,dc=example,dc=com
 *          * Result:
 *              * This will pass because the machine account lives under ou=ex2,ou=ex1 which is
 *              under the baseDN from the config file, and the CSR organizationName entries contain
 *              the OUs that the machine account lives under (order does not matter).
 *      * Fail:
 *          * Parameters:
 *              * Machine account DN: [email protected],ou=ex2,ou=ex1,ou=computers,dc=example,dc=com
 *              * organizationName entries: {ex2}
 *              * Config file match rule baseDN: ou=ex1,ou=computers,dc=example,dc=com
 *          * Result:
 *              * This will fail because the machine account lives under ou=ex2,ou=ex1 which is
 *              under the baseDN from the config file, but the CSR organizationName entries do not
 *              contain all of the OUs that the machine account lives under.
 *      * Fail:
 *          * Parameters:
 *              * Machine account DN: [email protected],ou=ex2,ou=ex1,ou=computers,dc=example,dc=com
 *              * organizationName entries: {ex2, ex2}
 *              * Config file match rule baseDN: ou=ex1,ou=computers,dc=example,dc=com
 *          * Result:
 *              * This will fail because the machine account lives under ou=ex2,ou=ex1 which is
 *              under the baseDN from the config file, but the CSR organizationName entries do not
 *              contain all of the OUs that the machine account lives under, even though the amount
 *              is the same.
 *      * Fail:
 *          * Parameters:
 *              * Machine account DN: [email protected],ou=ex2,ou=ex1,ou=computers,dc=example,dc=com
 *              * organizationName entries: {ex3, ex4}
 *              * Config file match rule baseDN: ou=ex1,ou=computers,dc=example,dc=com
 *          * Result:
 *              * This will fail because the machine account lives under ou=ex2,ou=ex1 which is
 *              under the baseDN from the config file, but the CSR organizationName entries do not
 *              contain any of the OUs that the machine account lives under.
 *
 * @param pcszAuthDN:               The DN of the CSR requestor
 * @param pcszAuthBaseDN:           The baes DN under which the requestor must live
 * @param dwOrgNamesLen:            The number of organizationName entries in the CSR subjectName field
 * @param ppcszOrgNames:            An array of the organizationName entries
 *
 * @return                          A status code indicating valid (0) or invalid (not 0) request
 */
static
DWORD
VMCAPolicySNMatchAuthOUWithCSR(
    PCSTR                           pcszAuthDN,
    PCSTR                           pcszAuthBaseDN,
    DWORD                           dwOrgNamesLen,
    PSTR* const                     ppcszOrgNames
    )
{
    DWORD                           dwError = 0;
    DWORD                           dwIdx = 0;
    DWORD                           dwNumRDNsInAuthDN = 0;
    DWORD                           dwNumAuthRDNsToValidate = 0;
    DWORD                           dwNumRDNsInBaseDn = 0;
    PSTR                            pszFormattedOrgName = NULL;
    PSTR                            *ppszAuthRDNs = NULL;
    PSTR                            *ppszAuthBaseRDNs = NULL;
    PSTR                            *ppszAuthRDNsNoUserObj = NULL;
    PSTR                            *ppszOrgNamesLocal = NULL;

    if (IsNullOrEmptyString(pcszAuthDN) ||
        IsNullOrEmptyString(pcszAuthBaseDN))
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    if (dwOrgNamesLen < 1 || !ppcszOrgNames)
    {
        VMCA_LOG_INFO(
                "[%s,%d] SNPolicy violation: CSR subjectName did not contain organizationName entries. User (%s)",
                __FUNCTION__,
                __LINE__,
                pcszAuthDN);
        dwError = VMCA_POLICY_VALIDATION_ERROR;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    dwError = VMCADNToRDNArray(
                        pcszAuthBaseDN,
                        FALSE,
                        &dwNumRDNsInBaseDn,
                        &ppszAuthBaseRDNs);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCADNToRDNArray(
                    pcszAuthDN,
                    FALSE,
                    &dwNumRDNsInAuthDN,
                    &ppszAuthRDNs);
    BAIL_ON_VMCA_ERROR(dwError);

    dwNumAuthRDNsToValidate = dwNumRDNsInAuthDN - dwNumRDNsInBaseDn;

    if (dwOrgNamesLen != dwNumAuthRDNsToValidate)
    {
        VMCA_LOG_INFO(
                "[%s,%d] SNPolicy violation: CSR subjectName does not have same number of organizationName entries as auth principal RDNs. User (%s)",
                __FUNCTION__,
                __LINE__,
                pcszAuthDN);
        dwError = VMCA_POLICY_VALIDATION_ERROR;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    dwError = VMCACopyStringArrayA(
                        &ppszOrgNamesLocal,
                        dwOrgNamesLen,
                        ppcszOrgNames,
                        dwOrgNamesLen);
    BAIL_ON_VMCA_ERROR(dwError);

    // Increment AuthRDN ptr array by 1 as first RDN will be machine account obj
    ppszAuthRDNsNoUserObj = ppszAuthRDNs + 1;
    qsort(ppszAuthRDNsNoUserObj, dwNumAuthRDNsToValidate, sizeof(PSTR), &VMCAPolicySNStrCmpWrapper);
    qsort(ppszOrgNamesLocal, dwOrgNamesLen, sizeof(PSTR), &VMCAPolicySNStrCmpWrapper);

    for (; dwIdx < dwNumAuthRDNsToValidate; ++dwIdx)
    {
        dwError = VMCAAllocateStringPrintfA(
                            &pszFormattedOrgName,
                            "ou=%s",
                            ppszOrgNamesLocal[dwIdx]);
        BAIL_ON_VMCA_ERROR(dwError);

        if (VMCAStringCompareA(ppszAuthRDNsNoUserObj[dwIdx], pszFormattedOrgName, TRUE))
        {
            VMCA_LOG_INFO(
                "[%s,%d] SNPolicy violation: CSR subjectName organizationName does not match auth principal DN. User (%s)",
                __FUNCTION__,
                __LINE__,
                pcszAuthDN);
            dwError = VMCA_POLICY_VALIDATION_ERROR;
            BAIL_ON_VMCA_ERROR(dwError);
        }

        VMCA_SAFE_FREE_STRINGA(pszFormattedOrgName);
    }


cleanup:

    VMCA_SAFE_FREE_STRINGA(pszFormattedOrgName);
    VMCAFreeStringArrayA(ppszAuthBaseRDNs, dwNumRDNsInBaseDn);
    VMCAFreeStringArrayA(ppszAuthRDNs, dwNumRDNsInAuthDN);
    VMCAFreeStringArrayA(ppszOrgNamesLocal, dwOrgNamesLen);

    return dwError;

error:

    goto cleanup;
}
예제 #7
0
파일: snpolicy.c 프로젝트: vmware/lightwave
DWORD
VMCAPolicySNValidate(
    PVMCA_POLICY                    pPolicy,
    PSTR                            pszPKCS10Request,
    PVMCA_REQ_CONTEXT               pReqContext,
    PBOOLEAN                        pbBypass,
    PBOOLEAN                        pbIsValid
    )
{
    DWORD                           dwError = 0;
    DWORD                           dwOrgNamesLen = 0;
    DWORD                           dwIdx = 0;
    int                             nCount = 0;
    PSTR                            *ppszOrgNames = NULL;
    PSTR                            pszAuthBaseDN = NULL;
    PSTR                            pszAuthDN = NULL;
    PVMCA_LDAP_CONTEXT              pLd = NULL;
    BOOLEAN                         bBypass = FALSE;
    BOOLEAN                         bIsValid = FALSE;

    if (!pPolicy ||
        IsNullOrEmptyString(pszPKCS10Request) ||
        !pReqContext ||
        !pbIsValid)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    dwError = VMCAOpenLocalLdapServer(&pLd);
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = VMCAConvertUPNToDN(
                        pLd,
                        pReqContext->pszAuthPrincipal,
                        &pszAuthDN);
    BAIL_ON_VMCA_ERROR(dwError);

    if (VMCAStringCompareA(pPolicy->Rules.SN.pMatch->pszData, VMCA_POLICY_REQ_UPN_DN, TRUE) == 0 &&
        VMCAStringCompareA(pPolicy->Rules.SN.pMatch->pszCondition, VMCA_POLICY_COND_BEGINS, TRUE) == 0)
    {
        dwError = VMCAStringCountSubstring(
                            pszAuthDN,
                            pPolicy->Rules.SN.pMatch->pszWith,
                            &nCount);
        BAIL_ON_VMCA_ERROR(dwError);

        if (nCount == 0)
        {
            VMCA_LOG_INFO(
                    "[%s,%d] CSR requestor (%s) is not a member of policy baseDN...bypassing enforcement",
                    __FUNCTION__,
                    __LINE__,
                    pszAuthDN);

            bIsValid = TRUE;
            bBypass = TRUE;
            goto ret;
        }
    }
    else
    {
        VMCA_LOG_INFO(
                "[%s,%d] Unknown SN policy match rules",
                __FUNCTION__,
                __LINE__);
        dwError = VMCA_POLICY_CONFIG_ERROR;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    for (dwIdx = 0; dwIdx < pPolicy->Rules.SN.dwValidateLen; ++dwIdx)
    {
        if (!VMCAStringCompareA(
                    pPolicy->Rules.SN.ppValidate[dwIdx]->pszData,
                    VMCA_POLICY_REQ_CSR_SUBJ_ORGS,
                    TRUE))
        {
            dwError = VMCAOpenSSLGetValuesFromSubjectName(
                                    pszPKCS10Request,
                                    VMCA_OPENSSL_NID_O,
                                    &dwOrgNamesLen,
                                    &ppszOrgNames);
            BAIL_ON_VMCA_ERROR(dwError);

            if (!VMCAStringCompareA(
                        pPolicy->Rules.SN.ppValidate[dwIdx]->pszWith,
                        VMCA_POLICY_REQ_UPN_RDN,
                        TRUE))
            {
                dwError = VMCAPolicySNMatchAuthOUWithCSR(
                                        pszAuthDN,
                                        pPolicy->Rules.SN.pMatch->pszWith,
                                        dwOrgNamesLen,
                                        ppszOrgNames);
                BAIL_ON_VMCA_ERROR(dwError);
            }
            else
            {
                VMCA_LOG_INFO(
                    "[%s,%d] Unknown SN policy validate rules",
                    __FUNCTION__,
                    __LINE__);
                dwError = VMCA_POLICY_CONFIG_ERROR;
                BAIL_ON_VMCA_ERROR(dwError);
            }

            VMCAFreeStringArrayA(ppszOrgNames, dwOrgNamesLen);
            ppszOrgNames = NULL;
            dwOrgNamesLen = 0;
        }
        else
        {
            VMCA_LOG_INFO(
                "[%s,%d] Unknown SN policy validate rules",
                __FUNCTION__,
                __LINE__);
            dwError = VMCA_POLICY_CONFIG_ERROR;
            BAIL_ON_VMCA_ERROR(dwError);
        }
    }

    bIsValid = TRUE;


ret:

    *pbBypass = bBypass;
    *pbIsValid = bIsValid;

cleanup:

    VMCA_SAFE_FREE_STRINGA(pszAuthDN);
    VMCA_SAFE_FREE_STRINGA(pszAuthBaseDN);
    VMCAFreeStringArrayA(ppszOrgNames, dwOrgNamesLen);
    if (pLd)
    {
        VMCALdapClose(pLd);
        pLd = NULL;
    }

    return dwError;

error:

    if (pbBypass)
    {
        *pbBypass = FALSE;
    }
    if (pbIsValid)
    {
        *pbIsValid = FALSE;
    }

    goto cleanup;
}
예제 #8
0
파일: main.c 프로젝트: vmware/lightwave
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;
}