Exemplo n.º 1
0
static DWORD
VMCABackupFiles(
    PCSTR pszBaseFilePath
    )
{
    DWORD dwError = ERROR_SUCCESS;
    const DWORD MAX_NUMBER_OF_BAKUPS = 32;
    struct STAT st = { 0 };
    DWORD dwCounter;

    PSTR pszDestFile = NULL;
    PSTR pszSourceFile = NULL;

    for (dwCounter = MAX_NUMBER_OF_BAKUPS; dwCounter > 0; --dwCounter)
    {
        dwError = VMCAAllocateStringPrintfA(
                              &pszDestFile,
                              "%s.%d",
                              pszBaseFilePath,
                              dwCounter);
        BAIL_ON_ERROR(dwError);

        if(STAT(pszDestFile, &st) == ERROR_SUCCESS ) 
        {
            UNLINK(pszDestFile);
        }

        dwError = VMCAAllocateStringPrintfA(
                              &pszSourceFile,
                              "%s.%d",
                              pszBaseFilePath,
                              dwCounter - 1);
        BAIL_ON_ERROR(dwError);

        RENAME(pszSourceFile, pszDestFile);

        VMCA_SAFE_FREE_STRINGA(pszDestFile);
        VMCA_SAFE_FREE_STRINGA(pszSourceFile);

        pszDestFile = NULL;
        pszSourceFile = NULL;
    }

    VMCA_SAFE_FREE_STRINGA(pszDestFile);

    dwError = VMCAAllocateStringPrintfA(
                          &pszDestFile,
                          "%s.%d",
                          pszBaseFilePath,
                          0);
    BAIL_ON_ERROR(dwError);

    RENAME(pszBaseFilePath, pszDestFile);

error:
    VMCA_SAFE_FREE_STRINGA(pszDestFile);
    VMCA_SAFE_FREE_STRINGA(pszSourceFile);

    return dwError;
}
Exemplo n.º 2
0
uint32_t
make_negotiate_token(
    gss_buffer_desc *pBuffer,
    char **ppszNegotiate
    )
{
    uint32_t dwError = 0;
    char *pszEncodedData = NULL;
    char *pszNegotiate = NULL;
    //int len = 0;

    if (pBuffer)
    {
        dwError = base64_encode(
                      pBuffer->value,
                      pBuffer->length,
                      &pszEncodedData);
        BAIL_ON_VMCA_ERROR(dwError);
    }

    dwError =  VMCAAllocateStringPrintfA(
                   &pszNegotiate,
                   "Negotiate %s",
                   pszEncodedData ? pszEncodedData : "");
    BAIL_ON_VMCA_ERROR(dwError);

    *ppszNegotiate = pszNegotiate;

cleanup:
    VMCA_SAFE_FREE_MEMORY(pszEncodedData);
    return dwError;
error:
    VMCA_SAFE_FREE_MEMORY(pszNegotiate);
    goto cleanup;
}
Exemplo n.º 3
0
DWORD
VMCACreatePrimaryLog(PSTR pszLogDir)
{
    DWORD dwError = 0;
    PSTR pszDestFile = NULL;
    if(pszLogDir == NULL) {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    dwError = VMCAAllocateStringPrintfA(
                  &pszDestFile,
                  FORMATSTR,
                  pszLogDir,
                  VMCA_LOG_STRING,
                  0);// This is always the Current Log File
    BAIL_ON_VMCA_ERROR(dwError);

    if (fpCurrentLog != NULL) {
        fclose(fpCurrentLog);
        fpCurrentLog = NULL;
    }

    fpCurrentLog = fopen(pszDestFile, "a");

    gVMCACurrentLogSizeBytes = 0;

error :
    VMCA_SAFE_FREE_STRINGA(pszDestFile);
    return dwError;
}
Exemplo n.º 4
0
DWORD
VMCARESTSetResponsePayload(
    PVMREST_HANDLE  pRESTHandle,
    PREST_RESPONSE* ppResponse,
    PSTR            pszRespPayload
    )
{
    DWORD   dwError = 0;
    DWORD   bytesWritten = 0;
    PSTR    pszPyldLen = NULL;
    size_t  pyldLen = 0;
    size_t  sentLen = 0;

    pyldLen = VMCAStringLenA(VMCA_SAFE_STRING(pszRespPayload));

    dwError = VMCAAllocateStringPrintfA(&pszPyldLen, "%ld", pyldLen);
    BAIL_ON_VMREST_ERROR(dwError);

    dwError = VmRESTSetDataLength(
            ppResponse,
            pyldLen > VMCARESTMAXPAYLOADLENGTH ? NULL : pszPyldLen);
    BAIL_ON_VMREST_ERROR(dwError);

    do
    {
        size_t chunkLen = pyldLen > VMCARESTMAXPAYLOADLENGTH ?
                VMCARESTMAXPAYLOADLENGTH : pyldLen;

        dwError = VmRESTSetData(
                pRESTHandle,
                ppResponse,
                VMCA_SAFE_STRING(pszRespPayload) + sentLen,
                chunkLen,
                &bytesWritten);

        sentLen += bytesWritten;
        pyldLen -= bytesWritten;
    }
    while (dwError == REST_ENGINE_MORE_IO_REQUIRED);
    BAIL_ON_VMREST_ERROR(dwError);

cleanup:
    VMCA_SAFE_FREE_MEMORY(pszPyldLen);
    return dwError;

error:
    goto cleanup;
}
Exemplo n.º 5
0
DWORD
VMCAGetTempCRLNamePath(PSTR *pszPrivPath)
{
   PSTR pszDataPath = NULL;
   DWORD dwError = 0;
   dwError = VMCAGetDataDirectory(&pszDataPath);
   BAIL_ON_ERROR(dwError);
   dwError = VMCAAllocateStringPrintfA(pszPrivPath,"%s%s%s",pszDataPath,VMCA_PATH_SEPARATOR,VMCA_CRL_TMP_NAME);
   BAIL_ON_ERROR(dwError);

error:
	if(pszDataPath  != NULL){
		VMCAFreeStringA(pszDataPath);
   }
   return dwError;
}
Exemplo n.º 6
0
DWORD
VMCAGetCertsDBPath(PSTR *pszPrivPath)
{
   PSTR pszDataPath = NULL;
   DWORD dwError = 0;
   dwError = VMCAGetDataDirectory(&pszDataPath);
   BAIL_ON_ERROR(dwError);
   dwError = VMCAAllocateStringPrintfA(pszPrivPath,"%s%s%s",pszDataPath,VMCA_PATH_SEPARATOR,CERTS_DB);
   BAIL_ON_ERROR(dwError);

error:
	if(pszDataPath  != NULL){
		VMCAFreeStringA(pszDataPath);
   }
   return dwError;
}
Exemplo n.º 7
0
DWORD
VMCAGetPrivateKeyPasswordPath(PSTR *pszPrivPath)
{
   PSTR pszDataPath = NULL;
   DWORD dwError = 0;
   dwError = VMCAGetDataDirectory(&pszDataPath);
   BAIL_ON_ERROR(dwError);
   dwError = VMCAAllocateStringPrintfA(pszPrivPath,"%s%s%s",pszDataPath,VMCA_PATH_SEPARATOR,PRIVATE_PASSWORD);
   BAIL_ON_ERROR(dwError);

error:
	if(pszDataPath  != NULL){
		VMCAFreeStringA(pszDataPath);
   }
   return dwError;
}
Exemplo n.º 8
0
DWORD
VMCAGetRootCertificateFilePath(PSTR *pszRootPath)
{
   PSTR pszDataPath = NULL;
   DWORD dwError = 0;
   dwError = VMCAGetDataDirectory(&pszDataPath);
   BAIL_ON_ERROR(dwError);
   dwError = VMCAAllocateStringPrintfA(pszRootPath,"%s%s%s",pszDataPath,VMCA_PATH_SEPARATOR,ROOT_CER);
   BAIL_ON_ERROR(dwError);

error:
   if(pszDataPath  != NULL){
		VMCAFreeStringA(pszDataPath);
   }
   return dwError;
}
Exemplo n.º 9
0
/*
 * 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;
}
Exemplo n.º 10
0
// This function renames logs to rotate.
// for example if max old log is 5, then
// vmca.log.4 -> vmca.log.5
// vmca.log.3 -> vmca.log.4
// vmca.log.2 -> vmca.log.3
// vmca.log.1 -> vmca.log.2
// vmca.log.0 -> vmca.log.1
// where vmca.log.1 is the most current log.
DWORD
VMCARenameLogs()
{
    int nCounter = 0;
    PSTR pszSourceFile = NULL;
    PSTR pszDestFile = NULL;
    PSTR pszLogDir = NULL;
    struct STAT st = { 0 };
    DWORD dwError = 0;

    dwError = VMCAGetLogFileDirectory(&pszLogDir);
    BAIL_ON_VMCA_ERROR(dwError);

    if (fpCurrentLog)
    {
        fclose(fpCurrentLog);
        fpCurrentLog = NULL;
    }

    for ( nCounter = (int)gVMCAMaxOldLogs; nCounter > 0 ;
            nCounter --) {

        dwError = VMCAAllocateStringPrintfA(
                      &pszDestFile,
                      FORMATSTR,
                      pszLogDir,
                      VMCA_LOG_STRING,
                      nCounter);

        BAIL_ON_VMCA_ERROR(dwError);

        if(STAT(pszDestFile, &st) == VMCA_OK ) {
            UNLINK(pszDestFile);
        }

        dwError = VMCAAllocateStringPrintfA(
                      &pszSourceFile,
                      FORMATSTR,
                      pszLogDir,
                      VMCA_LOG_STRING,
                      nCounter - 1);

        BAIL_ON_VMCA_ERROR(dwError);

        if (RENAME(pszSourceFile, pszDestFile) != VMCA_OK ) {
            // Emit an Error Event once we have support for that
        }

        VMCA_SAFE_FREE_STRINGA(pszDestFile);
        pszDestFile = NULL;
        VMCA_SAFE_FREE_STRINGA(pszSourceFile);
        pszSourceFile = NULL;
    }

cleanup :
    VMCA_SAFE_FREE_STRINGA(pszLogDir);
    return dwError;
error :
    VMCA_SAFE_FREE_STRINGA(pszDestFile);
    VMCA_SAFE_FREE_STRINGA(pszSourceFile);
    goto cleanup;
}
Exemplo n.º 11
0
DWORD
VMCAUpdatePkiCAAttribute(
    PVMCA_LDAP_CONTEXT pContext,
    PSTR    pszConfigurationDN,
    X509*   pCertificate
    )
{
    DWORD   dwError = 0;
    PSTR pszCertificate   = NULL;
    PSTR pszCAContainerDN = NULL;
    PSTR pszCADN = NULL;
    PSTR pszCACN = NULL;
    PSTR pszCAIssuerDN = NULL;
    PSTR pszFoundCADN = NULL;
    X509_NAME *pCertName = NULL;
    ATTR_SEARCH_RESULT attrSearchResult = ATTR_NOT_FOUND;

    if (!pCertificate ||
        !pContext ||
        IsNullOrEmptyString(pszConfigurationDN)
       )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_ERROR (dwError);
    }

    dwError = VMCACertToPEM(
                            pCertificate,
                            &pszCertificate
                           );
    BAIL_ON_ERROR (dwError);

    pCertName = X509_get_subject_name(pCertificate);
    if ( pCertName == NULL) // Don't free
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_ERROR(dwError);
    }

    dwError = VMCAGetX509Name(pCertName, XN_FLAG_COMPAT, &pszCAIssuerDN);
    BAIL_ON_ERROR(dwError);

    dwError = VMCAGenerateCACNForLdap(pCertificate, &pszCACN);
    BAIL_ON_ERROR(dwError);

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

    dwError = VMCAAllocateStringPrintfA(
                    &pszCADN,
                    "CN=%s,%s",
                    pszCACN,
                    pszCAContainerDN);
    BAIL_ON_ERROR(dwError);

    dwError = VMCACheckCAObject(
                    pContext,
                    NULL,
                    pszCADN,
                    NULL,
                    &pszFoundCADN
                    );
    BAIL_ON_ERROR(dwError);

    if (IsNullOrEmptyString(pszFoundCADN))
    {
        dwError = VMCACreateCAObject(
                    pContext,
                    pszCACN,
                    pszCADN
                    );
        BAIL_ON_ERROR(dwError);
    }

    dwError = VMCACheckAttribute(
                    pContext,
                    pszCADN,
                    ATTR_CA_CERTIFICATE,
                    pszCertificate,
                    &attrSearchResult);
    BAIL_ON_ERROR(dwError);

    if (attrSearchResult != ATTR_MATCH)
    {
        dwError = VMCAUpdateAttribute(pContext, pszCADN,
                ATTR_CA_CERTIFICATE, pszCertificate,
                (attrSearchResult == ATTR_NOT_FOUND));
        BAIL_ON_ERROR(dwError);
    }

    dwError = VMCACheckAttribute(
                    pContext,
                    pszCADN,
                    ATTR_CA_CERTIFICATE_DN,
                    pszCAIssuerDN,
                    &attrSearchResult);
    BAIL_ON_ERROR(dwError);

    if (attrSearchResult != ATTR_MATCH)
    {
        dwError = VMCAUpdateAttribute(pContext, pszCADN,
                ATTR_CA_CERTIFICATE_DN, pszCAIssuerDN,
                (attrSearchResult == ATTR_NOT_FOUND));
        BAIL_ON_ERROR(dwError);
    }

cleanup:

    VMCA_SAFE_FREE_STRINGA(pszCertificate);
    VMCA_SAFE_FREE_STRINGA(pszFoundCADN);
    VMCA_SAFE_FREE_STRINGA(pszCAContainerDN);
    VMCA_SAFE_FREE_STRINGA(pszCACN);
    VMCA_SAFE_FREE_STRINGA(pszCADN);
    VMCA_SAFE_FREE_STRINGA(pszCAIssuerDN);
    return dwError;

error:

    goto cleanup;
}
Exemplo n.º 12
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;
}
Exemplo n.º 13
0
DWORD
VMCALdapConnect(
    PSTR   pszHostName,
    DWORD  dwPort,
    PSTR   pszUsername,
    PSTR   pszPassword,
    PVMCA_LDAP_CONTEXT* ppLotus
    )
{

    DWORD dwError = 0;
    PVMCA_LDAP_CONTEXT pContext = NULL;
    PSTR pszUrl = NULL;
    BerValue ldapBindPwd = {0};

//LDAP_SUCCESS is defined as Zero in the Standard
// Which plays well with our BAIL_ON_ERROR macro

    DWORD dwVersion = LDAP_VERSION3;
    DWORD dwReturns = 20;


    if(dwPort == 0) {
        // Let us use the default LDAP_PORT, 389
        dwPort = LDAP_PORT;
    }

    dwError = VMCAAllocateMemory(sizeof(*pContext), (PVOID*)&pContext);
    BAIL_ON_ERROR(dwError);

    if (VMCAIsIPV6AddrFormat(pszHostName))
    {
        dwError = VMCAAllocateStringPrintfA(
                    &pszUrl,
                    "ldap://[%s]:%d",
                    pszHostName,
                    dwPort);
    }
    else
    {
        dwError = VMCAAllocateStringPrintfA(
                    &pszUrl,
                    "ldap://%s:%d",
                    pszHostName,
                    dwPort);
    }
    BAIL_ON_ERROR(dwError);

    if(IsNullOrEmptyString(pszPassword))
    {   // no credentials, do anonymous bind.
        dwError =  ldap_initialize(&pContext->pConnection, pszUrl);
        BAIL_ON_ERROR(dwError);

        if (pContext->pConnection == NULL) {
            ldap_get_option(pContext->pConnection, LDAP_OPT_ERROR_NUMBER, &dwError);
            //dwError = ld_errno; //LdapGetLastError();
            BAIL_ON_ERROR(dwError);
        }

        dwError = ldap_set_option(pContext->pConnection,
                                  LDAP_OPT_PROTOCOL_VERSION,
                                  (void*)&dwVersion);
        BAIL_ON_ERROR(dwError);

        dwError = ldap_set_option(pContext->pConnection,
                                  LDAP_OPT_SIZELIMIT,
                                  (void*)& dwReturns);
        BAIL_ON_ERROR(dwError);

        dwError = ldap_sasl_bind_s(
                    pContext->pConnection,
                    pszUsername,
                    LDAP_SASL_SIMPLE,
                    &ldapBindPwd,  // no credentials
                    NULL,
                    NULL,
                    NULL);
    }
    else
    {
        dwError = VmCASASLSRPBind(
                    &pContext->pConnection,
                    pszUrl,
                    pszUsername,
                    pszPassword);
    }

#ifdef LDAP_ERROR_MESSAGE
    if(dwError != 0) {
        printf("Error :%s\n",ldap_err2string(dwError));
    }
#endif
    BAIL_ON_ERROR(dwError);

    *ppLotus = pContext;

cleanup:
    VMCA_SAFE_FREE_STRINGA(pszUrl);
    return dwError;

error:
    if ((dwError != 0) && pContext)
    {
        VMCALdapClose(pContext);
    }
    goto cleanup;
}
Exemplo n.º 14
0
DWORD
VMCALdapGetMemberships(
    PVMCA_LDAP_CONTEXT pConnection,
    PCSTR pszUPNName,
    PSTR  **pppszMemberships,
    PDWORD pdwMemberships
    )
{
    DWORD dwError = 0;
    PSTR pszFilter = NULL;
    PSTR pszAttrMemberOf = ATTR_MEMBEROF; // memberOf
    PSTR  ppszAttrs[] = { pszAttrMemberOf, NULL};
    DWORD dwCount = 0;
    LDAPMessage *pResult = NULL;
    LDAPMessage *pEntry = NULL;
    struct berval** ppValues = NULL;
    PSTR *ppszMemberships = NULL;
    DWORD dwMemberships = 0;
    DWORD i = 0;
    LDAP *pLd = NULL;

    if (pConnection == NULL ||
        pConnection->pConnection == NULL ||
        IsNullOrEmptyString(pszUPNName) ||
        pppszMemberships == NULL ||
        pdwMemberships == NULL)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    pLd = pConnection->pConnection;

    dwError = VMCAAllocateStringPrintfA(&pszFilter, "(%s=%s)", ATTR_KRB_UPN, pszUPNName); // userPrincipalName
    BAIL_ON_VMCA_ERROR(dwError);

    dwError = ldap_search_ext_s(
                    pLd,
                    "",
                    LDAP_SCOPE_SUBTREE,
                    pszFilter,
                    (PSTR*)ppszAttrs,
                    0,
                    NULL,
                    NULL,
                    NULL,
                    -1,
                    &pResult);
    BAIL_ON_VMCA_ERROR(dwError);

    dwCount = ldap_count_entries(pLd, pResult);
    if (dwCount == 0)
    {
        dwError = LDAP_NO_SUCH_OBJECT;
        BAIL_ON_VMCA_ERROR(dwError);
    }
    else if (dwCount > 1)
    {
        dwError = LDAP_OPERATIONS_ERROR;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    pEntry = ldap_first_entry(pLd, pResult);
    if (!pEntry)
    {
        dwError = LDAP_NO_SUCH_OBJECT;
        BAIL_ON_VMCA_ERROR(dwError);
    }

    ppValues = ldap_get_values_len(pLd, pEntry, pszAttrMemberOf);
    if (!ppValues)
    {
        dwMemberships = 0;
    }
    else
    {
        dwMemberships = ldap_count_values_len(ppValues);
    }

    if (dwMemberships)
    {
        dwError = VMCAAllocateMemory(dwMemberships * sizeof(PSTR), (PVOID*)&ppszMemberships);
        BAIL_ON_VMCA_ERROR(dwError);

        for (i = 0; ppValues[i] != NULL; i++)
        {
            PCSTR pszMemberOf = ppValues[i]->bv_val;

            dwError = VMCAAllocateStringA(pszMemberOf, &ppszMemberships[i]);
            BAIL_ON_VMCA_ERROR(dwError);
        }
    }

    *pppszMemberships = ppszMemberships;
    *pdwMemberships = dwMemberships;

cleanup:

    if(ppValues)
    {
        ldap_value_free_len(ppValues);
    }

    if (pResult)
    {
        ldap_msgfree(pResult);
    }

    VMCA_SAFE_FREE_MEMORY(pszFilter);

    return dwError;

error:
    if (ppszMemberships != NULL && dwMemberships > 0)
    {
        for (i = 0; i < dwMemberships; i++)
        {
            VMCA_SAFE_FREE_STRINGA(ppszMemberships[i]);
        }
        VMCA_SAFE_FREE_MEMORY(ppszMemberships);
    }
    goto cleanup;
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
0
static
DWORD
VMCALdapFindObject(
    PVMCA_LDAP_CONTEXT pContext,
    PCSTR    pszBaseDN,
    ber_int_t scope,
    PCSTR    pszAttribute,
    PCSTR    pszValue,
    PSTR     *ppszObjectDN
    )
{
    DWORD dwError = 0;
    DWORD dwNumEntries = 0;
    LDAPMessage* pResult = NULL;
    LDAPMessage* pEntry = NULL;
    PSTR pszFilter = NULL;
    PSTR pszObjectDN = NULL;

    if (pszAttribute && pszValue)
    {
        VMCAAllocateStringPrintfA(&pszFilter, "(%s=%s)", pszAttribute, pszValue);
    }

    dwError = ldap_search_ext_s(
                  pContext->pConnection,
                  (PSTR)pszBaseDN,
                  scope,
                  pszFilter,
                  NULL,      /* attributes      */
                  TRUE,
                  NULL,      /* server controls */
                  NULL,      /* client controls */
                  NULL,      /* timeout         */
                  0,
                  &pResult);
    BAIL_ON_ERROR(dwError);

    dwNumEntries = ldap_count_entries(pContext->pConnection, pResult);
    if (dwNumEntries > 1)
    {
        dwError = ERROR_INVALID_STATE;
        BAIL_ON_ERROR(dwError);
    }
    else if (dwNumEntries == 0)
    {
        dwError = ERROR_NOT_FOUND;
        BAIL_ON_ERROR(dwError);
    }
    else
    {
        pEntry = ldap_first_entry(pContext->pConnection, pResult);
        if (!pEntry)
        {
            dwError = ERROR_INVALID_STATE;
            BAIL_ON_ERROR(dwError);
        }

        pszObjectDN = ldap_get_dn(pContext->pConnection, pEntry);
        if (IsNullOrEmptyString(pszObjectDN))
        {
            dwError = ERROR_INVALID_STATE;
            BAIL_ON_ERROR(dwError);
        }

        *ppszObjectDN = pszObjectDN;
    }

cleanup:

    if (pResult)
    {
        ldap_msgfree(pResult);
    }

    VMCA_SAFE_FREE_STRINGA(pszFilter);

    return dwError;

error :
    VMCA_SAFE_FREE_STRINGA(pszObjectDN);

    if (dwError == LDAP_NO_SUCH_OBJECT)
    {
        dwError = 0;
    }

    goto cleanup;
}
Exemplo n.º 17
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;
}
Exemplo n.º 18
0
DWORD
VMCARESTVerifyKrbAuth(
    PVMCA_AUTHORIZATION_PARAM pAuthorization,
    PVMCA_ACCESS_TOKEN* ppAccessToken
    )
{
    DWORD dwError = 0;
    PSTR pszNegotiate = NULL;
    PSTR pszDecode = NULL;
    PSTR pszUser = NULL;
    char *pszToken = NULL;
    int nLength = 0;
    OM_uint32 major_status;
    OM_uint32 minor_status;
    gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc display_name = GSS_C_EMPTY_BUFFER;
    gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
    gss_name_t client_name = GSS_C_NO_NAME;
    static gss_OID_desc gss_spnego_mech_oid_desc =
                                 {6, (void *)"\x2b\x06\x01\x05\x05\x02"};
    static gss_OID gss_spnego_mech_oid = &gss_spnego_mech_oid_desc;
    gss_cred_id_t server_creds;

    pszNegotiate = pAuthorization->pszAuthorizationToken;
    if ( IsNullOrEmptyString(pszNegotiate) )
    {
        dwError = EACCES;
        BAIL_ON_VMREST_ERROR(dwError);
    }

    if (!strcmp(pszNegotiate,"testing"))
    // TODO: REMOVE
    // TODO: DO NOT CHECK IN
    {// Kerberos backdoor for testing
        dwError = VMCARESTMakeKrbAccessToken(ppAccessToken);
        BAIL_ON_VMREST_ERROR(dwError);
        goto cleanup;
    }
    dwError = base64_decode(
                        pszNegotiate,
                        &pszDecode,
                        &nLength
                        );
    BAIL_ON_VMREST_ERROR(dwError);

    dwError = server_acquire_creds(
                            "HTTP",
                            &gss_spnego_mech_oid_desc,
                            &server_creds
                            );
    BAIL_ON_VMREST_ERROR(dwError);

    input_token.length = nLength;
    input_token.value = pszDecode;

    major_status = gss_accept_sec_context(
                                    &minor_status,
                                    &gss_context,
                                    server_creds,
                                    &input_token,
                                    GSS_C_NO_CHANNEL_BINDINGS,
                                    &client_name,
                                    &gss_spnego_mech_oid,
                                    &output_token,
                                    NULL,
                                    NULL,
                                    NULL
                                    );

    if (GSS_ERROR(major_status) )
    {
        //TODO: insert show error
        dwError = EACCES;
        BAIL_ON_VMREST_ERROR(dwError);
    }

    if (output_token.length)
    {
        dwError = make_negotiate_token(&output_token, &pszToken);
        BAIL_ON_VMREST_ERROR(dwError);
    }

    if (major_status == GSS_S_CONTINUE_NEEDED)
    {
        OM_uint32 min2;
        gss_buffer_desc mech_msg = GSS_C_EMPTY_BUFFER;
        gss_buffer_desc gss_msg = GSS_C_EMPTY_BUFFER;
        gss_buffer_desc minor_msg = GSS_C_EMPTY_BUFFER;
        OM_uint32 msg_ctx = 0;
        PSTR pszError = NULL;

        gss_oid_to_str(&min2, gss_spnego_mech_oid, &mech_msg);
        gss_display_status(&min2, major_status, GSS_C_GSS_CODE, gss_spnego_mech_oid, &msg_ctx, &gss_msg);
        gss_display_status(&min2, minor_status, GSS_C_MECH_CODE, gss_spnego_mech_oid, &msg_ctx, &minor_msg);

        VMCAAllocateStringPrintfA(&pszError, "gss_rc[%d:%*s] mech[%*s] minor[%u:%*s]",
            major_status, (int)gss_msg.length,
            (const char *)(gss_msg.value?gss_msg.value:""),
            (int)mech_msg.length,
            (const char *)(mech_msg.value?mech_msg.value:""),
            minor_status, (int)minor_msg.length,
            (const char *)(minor_msg.value?minor_msg.value:""));

        gss_release_buffer(&min2, &mech_msg);
        gss_release_buffer(&min2, &gss_msg);
        gss_release_buffer(&min2, &minor_msg);
    }
    if (major_status == GSS_S_COMPLETE)
    {
        gss_display_name(&minor_status, client_name, &display_name, NULL);

        dwError = VMCAAllocateStringA(display_name.value, &pszUser);
        BAIL_ON_VMREST_ERROR(dwError);
    }

    dwError = VMCARESTMakeKrbAccessToken(ppAccessToken);
    BAIL_ON_VMREST_ERROR(dwError);

cleanup:
    if (pszUser)
    {
        VMCA_SAFE_FREE_MEMORY(pszUser);
    }
    return dwError;

error:
    goto cleanup;
}