DWORD VMCAGetDataDirectory(PSTR *ppszDataDir) { #define DATA_PATH "DataPath" DWORD dwError = 0; #ifndef _WIN32 dwError = VMCAAllocateStringA(VMCA_ROOT_CERT_DIR, ppszDataDir); #else dwError = VMCAGetRegKeyString(DATA_PATH, ppszDataDir); #endif return dwError; }
DWORD VMCAGetLogDirectory(PSTR *ppszLogDir) { #define LOG_DIR "LogsPath" DWORD dwError = 0; #ifndef _WIN32 dwError = VMCAAllocateStringA(VMCA_LOG_DIR, ppszLogDir); #else dwError = VMCAGetRegKeyString(LOG_DIR, ppszLogDir); #endif return dwError; }
DWORD VMCACreateDirectory(PSTR pszDirectoryName, BOOL bRestrictAccess) { DWORD dwError = 0; PSTR pszDir = NULL; #ifdef _WIN32 PSTR pszTemp = NULL; int err = 0; #endif if (!pszDirectoryName || !*pszDirectoryName) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } #ifndef _WIN32 mkdir(pszDirectoryName, 700); goto error; #else dwError = VMCAAllocateStringA(pszDirectoryName, &pszDir); BAIL_ON_VMCA_ERROR(dwError); pszTemp = pszDir; if (strlen(pszDir) > 3 && pszDir[1] == ':' && pszDir[2] == '\\') { pszTemp += 3; } while ( (pszTemp = strchr(pszTemp, '\\')) ) { *pszTemp = '\0'; err = _mkdir(pszDir); if(err == -1 && errno != EEXIST) { dwError = ERROR_PATH_NOT_FOUND; BAIL_ON_VMCA_ERROR(dwError); } *pszTemp++ = '/'; } if (bRestrictAccess) { dwError = VMCARestrictDirectoryAccess(pszDir); BAIL_ON_VMCA_ERROR(dwError); } #endif error: VMCA_SAFE_FREE_STRINGA(pszDir); return dwError; }
DWORD VMCAGetRegKeyString(PSTR pszRegKey, PSTR *ppszValue) { #define MAX_REG_VALUE_SIZE 512 DWORD dwError = 0; #ifdef _WIN32 HKEY hKey; DWORD dwBufferSize = MAX_REG_VALUE_SIZE; char szBuffer[MAX_REG_VALUE_SIZE] = {0}; //HKEY_LOCAL_MACHINE\SOFTWARE\VMware, Inc.\VMware Certificate Services dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\VMware, Inc.\\VMware Certificate Services",0, KEY_READ, &hKey); BAIL_ON_ERROR(dwError); dwError = RegQueryValueEx(hKey, pszRegKey, 0, NULL, (LPBYTE) szBuffer,&dwBufferSize); BAIL_ON_ERROR(dwError); dwError = VMCAAllocateStringA(szBuffer, ppszValue); BAIL_ON_ERROR(dwError); error : RegCloseKey(hKey); #endif //_WIN32 return dwError; }
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; }
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; }
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; }
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; }
DWORD VMCAPrintCRLPrivate( PSTR pszFileName, PSTR *ppszCRLString ) { DWORD dwError = 0; X509_CRL *pCrl = NULL; BIO *pBioMem = NULL; BUF_MEM *pBuffMem = NULL; PSTR pszTempCrl = NULL; PSTR pTempCrl = NULL; if(IsNullOrEmptyString(pszFileName)){ dwError = ERROR_INVALID_PARAMETER; BAIL_ON_ERROR(dwError); } pBioMem = BIO_new(BIO_s_mem()); if (pBioMem == NULL) { dwError = VMCA_OUT_MEMORY_ERR; BAIL_ON_ERROR(dwError); } dwError = VMCAReadCRLFromFile(pszFileName, &pCrl); BAIL_ON_ERROR(dwError); dwError = X509_CRL_print(pBioMem, pCrl); BAIL_ON_SSL_ERROR(dwError, VMCA_CRL_DECODE_ERROR); BIO_get_mem_ptr(pBioMem, &pBuffMem); dwError = VMCAAllocateMemory((DWORD)pBuffMem->length, (PVOID*)&pTempCrl); BAIL_ON_ERROR(dwError); memcpy(pTempCrl, pBuffMem->data, pBuffMem->length - 1); dwError = VMCAAllocateStringA(pTempCrl, &pszTempCrl); BAIL_ON_ERROR(dwError); *ppszCRLString = pszTempCrl; pszTempCrl = NULL; cleanup: if (pCrl) { VMCACrlFree(pCrl); } if (pBioMem != NULL) { BIO_free(pBioMem); } VMCA_SAFE_FREE_MEMORY(pTempCrl); return dwError; error : VMCA_SAFE_FREE_STRINGA(pszTempCrl); goto cleanup; }
DWORD VMCADecodeCert( PSTR pszCertificate, PVMCA_DB_CERTIFICATE_ENTRY* ppEntry ) { DWORD dwError = 0; PVMCA_DB_CERTIFICATE_ENTRY pDBEntry = NULL; PSTR pszCertName = NULL; PSTR pszCertSerial = NULL; PSTR pszNotBefore = NULL; PSTR pszNotAfter = NULL; PSTR pszIssuerName = NULL; X509 *pCert = NULL; if (pszCertificate == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } if (ppEntry == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAAllocateMemory( sizeof(VMCA_DB_CERTIFICATE_ENTRY), (PVOID*) &pDBEntry); BAIL_ON_VMCA_ERROR(dwError); memset(pDBEntry,0, sizeof(VMCA_DB_CERTIFICATE_ENTRY)); VMCAAllocateStringA(pszCertificate, (PSTR*)&pDBEntry->pCertBlob); //pDBEntry->pCertBlob = (PBYTE) pszCertificate; pDBEntry->dwCertSize = (DWORD)strlen(pszCertificate); dwError = VMCAPEMToX509(pszCertificate, &pCert); BAIL_ON_VMCA_ERROR(dwError); if (X509_cmp_current_time(X509_get_notAfter(pCert)) < 0) { pDBEntry->dwRevoked = VMCA_CERTIFICATE_EXPIRED; } dwError = VMCAGetCertificateName(pCert, &pszCertName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszCertName, &pDBEntry->pwszCommonName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetCertificateSerial(pCert, &pszCertSerial); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszCertSerial, &pDBEntry->pwszSerial); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetIssuerName(pCert, &pszIssuerName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszIssuerName, &pDBEntry->pwszIssuerName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetCertificateTime(pCert, &pszNotBefore, &pszNotAfter); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszNotBefore, &pDBEntry->pwszTimeValidFrom); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszNotBefore, &pDBEntry->pwszTimeValidTo); BAIL_ON_VMCA_ERROR(dwError); *ppEntry = pDBEntry; cleanup: if(pCert) { X509_free(pCert); } VMCA_SAFE_FREE_STRINGA(pszCertName); VMCA_SAFE_FREE_STRINGA(pszCertSerial); VMCA_SAFE_FREE_STRINGA(pszNotBefore); VMCA_SAFE_FREE_STRINGA(pszNotAfter); VMCA_SAFE_FREE_STRINGA(pszIssuerName); return dwError; error : VMCAFreeDBEntryFields(pDBEntry); goto cleanup; }
static DWORD VMCAReadPassword( PCSTR pszUser, PCSTR pszPrompt, PSTR* ppszPassword ) { DWORD dwError = 0; CHAR szPassword[33] = ""; PSTR pszPassword = NULL; DWORD iChar = 0; BOOLEAN bConsole = FALSE; memset(szPassword, 0, sizeof(szPassword)); if (IsNullOrEmptyString(pszPrompt)) { fprintf(stdout, "Enter password for %s: ", pszUser); } else { fprintf(stdout, "%s:", pszPrompt); } fflush(stdout); bConsole = _isatty(0); // Is stdin console? // Read up to 32 characters of password for (; iChar < sizeof(szPassword); iChar++) { CHAR ch = bConsole ? _getch() : getchar(); if (ch == EOF || ch == '\r' || ch == '\n') { fprintf(stdout, "\r\n"); fflush(stdout); break; } else if (ch == '\b') /* backspace */ { if (iChar > 0) { iChar--; szPassword[iChar] = '\0'; } } else { szPassword[iChar] = ch; } } if (IsNullOrEmptyString(szPassword)) { dwError = ERROR_PASSWORD_RESTRICTION; BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAAllocateStringA(szPassword, &pszPassword); BAIL_ON_VMCA_ERROR(dwError); *ppszPassword = pszPassword; cleanup: return dwError; error: *ppszPassword = NULL; goto cleanup; }
static DWORD VMCAReadPassword( PCSTR pszUser, PCSTR pszPrompt, PSTR* ppszPassword ) { DWORD dwError = 0; struct termios orig, nonecho; CHAR szPassword[33] = ""; PSTR pszPassword = NULL; DWORD iChar = 0; memset(szPassword, 0, sizeof(szPassword)); if (IsNullOrEmptyString(pszPrompt)) { fprintf(stdout, "Enter password for %s: ", pszUser); } else { fprintf(stdout, "%s:", pszPrompt); } fflush(stdout); tcgetattr(0, &orig); // get current settings memcpy(&nonecho, &orig, sizeof(struct termios)); // copy settings nonecho.c_lflag &= ~(ECHO); // don't echo password characters tcsetattr(0, TCSANOW, &nonecho); // set current settings to not echo // Read up to 32 characters of password for (; iChar < sizeof(szPassword); iChar++) { ssize_t nRead = 0; CHAR ch; if ((nRead = read(STDIN_FILENO, &ch, 1)) < 0) { dwError = LwErrnoToWin32Error(errno); BAIL_ON_VMCA_ERROR(dwError); } if (nRead == 0 || ch == '\n') { fprintf(stdout, "\n"); fflush(stdout); break; } else if (ch == '\b') /* backspace */ { if (iChar > 0) { iChar--; szPassword[iChar] = '\0'; } } else { szPassword[iChar] = ch; } } if (IsNullOrEmptyString(szPassword)) { dwError = ERROR_PASSWORD_RESTRICTION; BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAAllocateStringA(szPassword, &pszPassword); BAIL_ON_VMCA_ERROR(dwError); *ppszPassword = pszPassword; cleanup: tcsetattr(0, TCSANOW, &orig); return dwError; error: *ppszPassword = NULL; goto cleanup; }
DWORD VMCAGetDSERootAttribute( PVMCA_LDAP_CONTEXT pContext, PSTR pszAttribute, PSTR* ppszAttrValue ) { DWORD dwError = 0; // LDAP_SUCCESS PSTR pAttribute = NULL; BerValue** ppValue = NULL; BerElement* pBer = NULL; LDAPMessage* pSearchResult = NULL; LDAPMessage* pResults = NULL; PCHAR pszFilter = "(objectClass=*)"; PCHAR ppszAttrs[] = { pszAttribute, NULL }; dwError = ldap_search_ext_s( pContext->pConnection, // Session handle "", // DN to start search LDAP_SCOPE_BASE, // Scope pszFilter, // Filter ppszAttrs, // Retrieve list of attributes 0, // Get both attributes and values NULL, NULL, NULL, 0, &pSearchResult); // [out] Search results BAIL_ON_ERROR(dwError); if (ldap_count_entries(pContext->pConnection, pSearchResult) != 1) { dwError = ERROR_INVALID_STATE; BAIL_ON_ERROR(dwError); } // There should be only one result for this type pResults = ldap_first_entry(pContext->pConnection, pSearchResult); if (pResults == NULL) { ldap_get_option(pContext->pConnection, LDAP_OPT_ERROR_NUMBER, &dwError); BAIL_ON_ERROR(dwError); } pAttribute = ldap_first_attribute(pContext->pConnection,pResults,&pBer); if(pAttribute == NULL) { ldap_get_option(pContext->pConnection, LDAP_OPT_ERROR_NUMBER, &dwError); BAIL_ON_ERROR(dwError); } ppValue = ldap_get_values_len(pContext->pConnection, pResults, pszAttribute); if(ppValue == NULL) { ldap_get_option(pContext->pConnection, LDAP_OPT_ERROR_NUMBER, &dwError); BAIL_ON_ERROR(dwError); } dwError = VMCAAllocateStringA(ppValue[0]->bv_val, ppszAttrValue); BAIL_ON_ERROR(dwError); error : if ( ppValue != NULL) { ldap_value_free_len(ppValue); } if(pAttribute != NULL) { ldap_memfree(pAttribute); } if(pBer != NULL) { ber_free(pBer,0); } if(pSearchResult != NULL) { ldap_msgfree(pSearchResult); } return dwError; }
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; }
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; }