// on success, ppOutTokenSuccessResponse will be non-null // on error, ppOutTokenErrorResponse might be non-null (it will carry error info returned by the server if any) // delete both when done, whether invocation is successful or not, using OidcTokenSuccessResponseDelete and OidcErrorResponseDelete SSOERROR OidcClientAcquireTokensBySolutionUserCredentials( PCOIDC_CLIENT p, PCSTRING pszCertificateSubjectDN, PCSTRING pszPrivateKeyPEM, PCSTRING pszScope, POIDC_TOKEN_SUCCESS_RESPONSE* ppOutTokenSuccessResponse, /* OUT */ POIDC_ERROR_RESPONSE* ppOutTokenErrorResponse /* OUT */) { SSOERROR e = SSOERROR_NONE; PSSO_KEY_VALUE_PAIR* ppPairs = NULL; int parameterCount = 3; PSTRING pszAssertionPayload = NULL; PSTRING pszAssertionJwtString = NULL; BAIL_ON_NULL_ARGUMENT(p); BAIL_ON_NULL_ARGUMENT(pszCertificateSubjectDN); BAIL_ON_NULL_ARGUMENT(pszPrivateKeyPEM); BAIL_ON_NULL_ARGUMENT(pszScope); BAIL_ON_NULL_ARGUMENT(ppOutTokenSuccessResponse); BAIL_ON_NULL_ARGUMENT(ppOutTokenErrorResponse); if (p->pszClientID != NULL) { parameterCount++; } e = OidcClientBuildSolutionUserAssertionPayload(p, pszCertificateSubjectDN, &pszAssertionPayload); BAIL_ON_ERROR(e); e = SSOJwtCreateSignedJwtString(pszAssertionPayload, pszPrivateKeyPEM, &pszAssertionJwtString); BAIL_ON_ERROR(e); e = SSOMemoryAllocateArray(parameterCount, sizeof(PSSO_KEY_VALUE_PAIR), (void**) &ppPairs); BAIL_ON_ERROR(e); e = SSOKeyValuePairNew(&ppPairs[0], "grant_type", "urn:vmware:grant_type:solution_user_credentials"); BAIL_ON_ERROR(e); e = SSOKeyValuePairNew(&ppPairs[1], "solution_user_assertion", pszAssertionJwtString); BAIL_ON_ERROR(e); e = SSOKeyValuePairNew(&ppPairs[2], "scope", pszScope); BAIL_ON_ERROR(e); if (p->pszClientID != NULL) { e = SSOKeyValuePairNew(&ppPairs[3], "client_id", p->pszClientID); BAIL_ON_ERROR(e); } e = OidcClientAcquireTokens(p, ppPairs, parameterCount, ppOutTokenSuccessResponse, ppOutTokenErrorResponse); BAIL_ON_ERROR(e); error: SSOMemoryFreeArrayOfObjects((void**) ppPairs, parameterCount, (GenericDestructorFunction) SSOKeyValuePairDelete); SSOStringFree(pszAssertionPayload); SSOStringFree(pszAssertionJwtString); return e; }
void SSOKeyValuePairDelete( PSSO_KEY_VALUE_PAIR p) { if (p != NULL) { SSOStringFree(p->pszKey); SSOStringFree(p->pszValue); SSOMemoryFree(p, sizeof(SSO_KEY_VALUE_PAIR)); } }
void OidcClientDelete( POIDC_CLIENT p) { if (p != NULL) { SSOStringFree(p->pszServer); SSOStringFree(p->pszClientID); SSOStringFree(p->pszTlsCAPath); SSOStringFree(p->pszTokenEndpointUrl); SSOStringFree(p->pszSigningCertificatePEM); SSOCdcDelete(p->pClientDCCache); SSOMemoryFree(p, sizeof(OIDC_CLIENT)); } }
SSOERROR SSOCdcGetAffinitizedHost( PCSSO_CDC pCdc, PCSTRING domainName, int cdcFlags, PSTRING* ppszAffinitizedHost) { SSOERROR e = SSOERROR_NONE; DWORD dwError = 0; PVMAFD_SERVER pServer = NULL; PCDC_DC_INFO_A pDCInfo = NULL; PSTRING pszAffinitizedHost = NULL; if (pCdc == NULL || ppszAffinitizedHost == NULL) { e = SSOERROR_INVALID_ARGUMENT; BAIL_ON_ERROR(e); } dwError = (*(DWORD (*)(PCSTR, PCSTR, PCSTR, PVMAFD_SERVER*))pCdc->pVmAfdOpenServer)(NULL, NULL, NULL, &pServer); if (dwError != 0) { e = SSOERROR_VMAFD_CALL_FAILURE; BAIL_ON_ERROR(e); } dwError = (*(DWORD (*)(PVMAFD_SERVER, PCSTR, GUID_A, PCSTR, DWORD, PCDC_DC_INFO_A*))pCdc->pCdcGetDCName)(pServer, domainName, NULL, NULL, cdcFlags, &pDCInfo); if (dwError != 0) { e = SSOERROR_VMAFD_CALL_FAILURE; BAIL_ON_ERROR(e); } e = SSOStringAllocate(pDCInfo->pszDCName, &pszAffinitizedHost); BAIL_ON_ERROR(e); *ppszAffinitizedHost = pszAffinitizedHost; error: if (e != SSOERROR_NONE) { SSOStringFree(pszAffinitizedHost); } // cleanup if (pServer != NULL) { (*(VOID (*)(PVMAFD_SERVER))pCdc->pVmAfdCloseServer)(pServer); } if (pDCInfo != NULL) { (*(VOID (*)(PCDC_DC_INFO_A))pCdc->pCdcFreeDomainControllerInfo)(pDCInfo); } return e; }
SSOERROR IdmResourceServerDelete( PCREST_CLIENT pClient, PCSTRING tenant, PCSTRING name, REST_SERVER_ERROR** ppError) { SSOERROR e = SSOERROR_NONE; PSTRING resourceUri = NULL; REST_SERVER_ERROR* pError = NULL; if (pClient == NULL || IS_NULL_OR_EMPTY_STRING(tenant) || IS_NULL_OR_EMPTY_STRING(name) || ppError == NULL) { e = SSOERROR_INVALID_ARGUMENT; BAIL_ON_ERROR(e); } e = RestBuildResourceUri( pClient, TENANT_URI, tenant, "resourceserver", name, NULL, &resourceUri); BAIL_ON_ERROR(e); e = RestBuildAndExecuteHttp( NULL, NULL, pClient->pAccessToken, resourceUri, REST_HTTP_METHOD_TYPE_DELETE, NULL, NULL, pClient->tlsCAPath, &pError); BAIL_ON_ERROR(e); error: if (e != SSOERROR_NONE) { *ppError = pError; } // cleanup SSOStringFree(resourceUri); return e; }
SSOERROR IdmResourceServerGetAll( PCREST_CLIENT pClient, PCSTRING tenant, IDM_RESOURCE_SERVER_ARRAY_DATA** ppResourceServerArrayReturn, REST_SERVER_ERROR** ppError) { SSOERROR e = SSOERROR_NONE; PSTRING resourceUri = NULL; IDM_RESOURCE_SERVER_ARRAY_DATA* pResourceServerArrayReturn = NULL; REST_SERVER_ERROR* pError = NULL; if (pClient == NULL || IS_NULL_OR_EMPTY_STRING(tenant) || ppResourceServerArrayReturn == NULL || ppError == NULL) { e = SSOERROR_INVALID_ARGUMENT; BAIL_ON_ERROR(e); } e = RestBuildResourceUri( pClient, TENANT_POST_URI, tenant, "resourceserver", NULL, NULL, &resourceUri); BAIL_ON_ERROR(e); e = RestBuildAndExecuteHttp( NULL, NULL, pClient->pAccessToken, resourceUri, REST_HTTP_METHOD_TYPE_POST, (JsonToDataObjectFunc) IdmJsonToResourceServerArrayData, (void**) &pResourceServerArrayReturn, pClient->tlsCAPath, &pError); BAIL_ON_ERROR(e); *ppResourceServerArrayReturn = pResourceServerArrayReturn; // debug if (DEBUG) { RestDebugJsonArray(*ppResourceServerArrayReturn, (DataObjectToJsonFunc) IdmResourceServerArrayDataToJson); } error: if (e != SSOERROR_NONE) { IdmResourceServerArrayDataDelete(pResourceServerArrayReturn); *ppError = pError; } // cleanup SSOStringFree(resourceUri); return e; }
static SSOERROR OidcClientAcquireTokens( PCOIDC_CLIENT p, PSSO_KEY_VALUE_PAIR* ppPairs, size_t parameterCount, POIDC_TOKEN_SUCCESS_RESPONSE* ppOutTokenSuccessResponse, /* OUT */ POIDC_ERROR_RESPONSE* ppOutTokenErrorResponse /* OUT */) { SSOERROR e = SSOERROR_NONE; POIDC_TOKEN_SUCCESS_RESPONSE pOutTokenSuccessResponse = NULL; POIDC_ERROR_RESPONSE pOutTokenErrorResponse = NULL; PSSO_HTTP_CLIENT pHttpClient = NULL; PSTRING pszJsonResponse = NULL; PSTRING pszAffinitizedTokenEndpointUrl = NULL; PSTRING pszAffinitizedHost = NULL; long httpStatusCode = 0; if (p->pClientDCCache != NULL) // highAvailabilityEnabled { e = SSOCdcGetAffinitizedHost( p->pClientDCCache, NULL, // PCSTRING domainName 0, // int cdcFlags, &pszAffinitizedHost); BAIL_ON_ERROR(e); if (!SSOStringEqual(pszAffinitizedHost, p->pszServer)) { e = SSOStringReplace(p->pszTokenEndpointUrl, p->pszServer, pszAffinitizedHost, &pszAffinitizedTokenEndpointUrl); BAIL_ON_ERROR(e); } } e = SSOHttpClientNew(&pHttpClient, p->pszTlsCAPath); BAIL_ON_ERROR(e); e = SSOHttpClientSendPostForm( pHttpClient, (pszAffinitizedTokenEndpointUrl != NULL) ? pszAffinitizedTokenEndpointUrl : p->pszTokenEndpointUrl, NULL, // pszHeaders 0, // headerCount ppPairs, parameterCount, &pszJsonResponse, &httpStatusCode); BAIL_ON_ERROR(e); if (200 == httpStatusCode) { e = OidcTokenSuccessResponseParse(&pOutTokenSuccessResponse, pszJsonResponse); BAIL_ON_ERROR(e); } else { e = OidcErrorResponseParse(&pOutTokenErrorResponse, pszJsonResponse); BAIL_ON_ERROR(e); } *ppOutTokenSuccessResponse = pOutTokenSuccessResponse; *ppOutTokenErrorResponse = pOutTokenErrorResponse; if (pOutTokenErrorResponse != NULL) { // if server return error response, we translate that into an SSOERROR code e = OidcErrorResponseGetErrorCode(pOutTokenErrorResponse); } error: SSOHttpClientDelete(pHttpClient); SSOStringFree(pszAffinitizedTokenEndpointUrl); SSOStringFree(pszAffinitizedHost); SSOStringFree(pszJsonResponse); return e; }
static SSOERROR OidcClientBuildSolutionUserAssertionPayload( PCOIDC_CLIENT p, PCSTRING pszCertificateSubjectDN, PSTRING* ppsz /* OUT */) { SSOERROR e = SSOERROR_NONE; PSTRING psz = NULL; PSSO_JSON pJson = NULL; PSSO_JSON pJsonValue = NULL; // do not delete this PSTRING pszJwtID = NULL; time_t currentTime = time(NULL); // use current time as the jwt-id (jti), not as good as uuid but simpler to generate e = SSOStringAllocateFromInt(currentTime, &pszJwtID); BAIL_ON_ERROR(e); e = SSOJsonObjectNew(&pJson); BAIL_ON_ERROR(e); e = SSOJsonStringNew(&pJsonValue, "solution_user_assertion"); BAIL_ON_ERROR(e); e = SSOJsonObjectSet(pJson, "token_class", pJsonValue); BAIL_ON_ERROR(e); SSOJsonDelete(pJsonValue); pJsonValue = NULL; e = SSOJsonStringNew(&pJsonValue, "Bearer"); BAIL_ON_ERROR(e); e = SSOJsonObjectSet(pJson, "token_type", pJsonValue); BAIL_ON_ERROR(e); SSOJsonDelete(pJsonValue); pJsonValue = NULL; e = SSOJsonStringNew(&pJsonValue, pszJwtID); BAIL_ON_ERROR(e); e = SSOJsonObjectSet(pJson, "jti", pJsonValue); BAIL_ON_ERROR(e); SSOJsonDelete(pJsonValue); pJsonValue = NULL; e = SSOJsonStringNew(&pJsonValue, pszCertificateSubjectDN); BAIL_ON_ERROR(e); e = SSOJsonObjectSet(pJson, "iss", pJsonValue); BAIL_ON_ERROR(e); SSOJsonDelete(pJsonValue); pJsonValue = NULL; e = SSOJsonStringNew(&pJsonValue, pszCertificateSubjectDN); BAIL_ON_ERROR(e); e = SSOJsonObjectSet(pJson, "sub", pJsonValue); BAIL_ON_ERROR(e); SSOJsonDelete(pJsonValue); pJsonValue = NULL; e = SSOJsonStringNew(&pJsonValue, p->pszTokenEndpointUrl); BAIL_ON_ERROR(e); e = SSOJsonObjectSet(pJson, "aud", pJsonValue); BAIL_ON_ERROR(e); SSOJsonDelete(pJsonValue); pJsonValue = NULL; e = SSOJsonLongNew(&pJsonValue, currentTime); BAIL_ON_ERROR(e); e = SSOJsonObjectSet(pJson, "iat", pJsonValue); BAIL_ON_ERROR(e); SSOJsonDelete(pJsonValue); pJsonValue = NULL; e = SSOJsonToString(pJson, &psz); BAIL_ON_ERROR(e); *ppsz = psz; error: if (e != SSOERROR_NONE) { SSOStringFree(psz); } SSOJsonDelete(pJson); // pJsonValue's will be deleted by the this call SSOJsonDelete(pJsonValue); SSOStringFree(pszJwtID); return e; }
SSOERROR SSOStringReplace( PCSTRING pszInput, PCSTRING pszFind, PCSTRING pszReplace, PSTRING* ppsz /* OUT */) { SSOERROR e = SSOERROR_NONE; PSTRING psz = NULL; PSTRING pszPrefix = NULL; PSTRING pszSuffix = NULL; PSTRING pszPrefixPlusReplace = NULL; char* pszLocation = strstr(pszInput, pszFind); ASSERT_NOT_NULL(pszInput); ASSERT_NOT_NULL(pszFind); ASSERT_NOT_NULL(pszReplace); ASSERT_NOT_NULL(ppsz); if (pszLocation != NULL) { size_t inputLength = strlen(pszInput); size_t findLength = strlen(pszFind); size_t locationLength = strlen(pszLocation); size_t prefixLength = inputLength - locationLength; size_t suffixLength = locationLength - findLength; if (prefixLength > 0) { e = SSOStringAllocateSubstring(pszInput, 0, prefixLength - 1, &pszPrefix); BAIL_ON_ERROR(e); } else { e = SSOStringAllocate("", &pszPrefix); BAIL_ON_ERROR(e); } if (suffixLength > 0) { e = SSOStringAllocateSubstring(pszInput, inputLength - suffixLength, inputLength - 1, &pszSuffix); BAIL_ON_ERROR(e); } else { e = SSOStringAllocate("", &pszSuffix); BAIL_ON_ERROR(e); } e = SSOStringConcatenate(pszPrefix, pszReplace, &pszPrefixPlusReplace); BAIL_ON_ERROR(e); e = SSOStringConcatenate(pszPrefixPlusReplace, pszSuffix, &psz); BAIL_ON_ERROR(e); } else { // not found, return a copy of the input e = SSOStringAllocate(pszInput, &psz); BAIL_ON_ERROR(e); } *ppsz = psz; error: if (e != SSOERROR_NONE) { SSOStringFree(psz); } SSOStringFree(pszPrefix); SSOStringFree(pszSuffix); SSOStringFree(pszPrefixPlusReplace); return e; }
SSOERROR IdmTenantCreate( PCREST_CLIENT pClient, const IDM_TENANT_DATA* pTenant, IDM_TENANT_DATA** ppTenantReturn, REST_SERVER_ERROR** ppError) { SSOERROR e = SSOERROR_NONE; PSTRING resourceUri = NULL; IDM_TENANT_DATA* pTenantReturn = NULL; REST_SERVER_ERROR* pError = NULL; if (pClient == NULL || pTenant == NULL || ppTenantReturn == NULL || ppError == NULL) { e = SSOERROR_INVALID_ARGUMENT; BAIL_ON_ERROR(e); } e = RestBuildResourceUri( pClient, TENANT_URI, NULL, NULL, NULL, NULL, &resourceUri); BAIL_ON_ERROR(e); e = RestBuildAndExecuteHttp( pTenant, (DataObjectToJsonFunc) IdmTenantDataToJson, pClient->pAccessToken, resourceUri, REST_HTTP_METHOD_TYPE_POST, (JsonToDataObjectFunc) IdmJsonToTenantData, (void**) &pTenantReturn, pClient->tlsCAPath, &pError); BAIL_ON_ERROR(e); *ppTenantReturn = pTenantReturn; // debug if (DEBUG) { RestDebugJsonObject(*ppTenantReturn, (DataObjectToJsonFunc) IdmTenantDataToJson); } error: if (e != SSOERROR_NONE) { IdmTenantDataDelete(pTenantReturn); *ppError = pError; } // cleanup SSOStringFree(resourceUri); return e; }
SSOERROR IdmTenantSearch( PCREST_CLIENT pClient, PCSTRING tenant, PCSTRING domain, PCSTRING query, IDM_MEMBER_TYPE memberType, IDM_SEARCH_TYPE searchBy, size_t limit, IDM_SEARCH_RESULT_DATA** ppSearchResultReturn, REST_SERVER_ERROR** ppError) { SSOERROR e = SSOERROR_NONE; PSTRING s = NULL; PSTRING resourceUri = NULL; IDM_SEARCH_RESULT_DATA* pSearchResultReturn = NULL; REST_SERVER_ERROR* pError = NULL; if (pClient == NULL || ppSearchResultReturn == NULL || ppError == NULL) { e = SSOERROR_INVALID_ARGUMENT; BAIL_ON_ERROR(e); } e = RestBuildResourceUri( pClient, TENANT_POST_URI, tenant, "search", NULL, NULL, &resourceUri); BAIL_ON_ERROR(e); e = RestAppendQueryStringOnResourceUri("domain", domain, true, resourceUri, &resourceUri); BAIL_ON_ERROR(e); e = RestAppendQueryStringOnResourceUri("query", query, false, resourceUri, &resourceUri); BAIL_ON_ERROR(e); e = RestAppendQueryStringOnResourceUri("type", IDM_MEMBER_TYPE_ENUMS[memberType], false, resourceUri, &resourceUri); BAIL_ON_ERROR(e); e = RestAppendQueryStringOnResourceUri("searchBy", IDM_SEARCH_TYPE_ENUMS[searchBy], false, resourceUri, &resourceUri); BAIL_ON_ERROR(e); e = SSOStringAllocateFromInt((int) limit, &s); BAIL_ON_ERROR(e); e = RestAppendQueryStringOnResourceUri("limit", s, false, resourceUri, &resourceUri); BAIL_ON_ERROR(e); e = RestBuildAndExecuteHttp( NULL, NULL, pClient->pAccessToken, resourceUri, REST_HTTP_METHOD_TYPE_POST, (JsonToDataObjectFunc) IdmJsonToSearchResultData, (void**) &pSearchResultReturn, pClient->tlsCAPath, &pError); BAIL_ON_ERROR(e); *ppSearchResultReturn = pSearchResultReturn; // debug if (DEBUG) { RestDebugJsonObject(*ppSearchResultReturn, (DataObjectToJsonFunc) IdmSearchResultDataToJson); } error: if (e != SSOERROR_NONE) { IdmSearchResultDataDelete(pSearchResultReturn); *ppError = pError; } // cleanup SSOStringFree(s); SSOStringFree(resourceUri); return e; }
SSOERROR IdmTenantGetConfig( PCREST_CLIENT pClient, PCSTRING tenant, IDM_TENANT_CONFIG_TYPE_ARRAY* pTenantConfigTypes, IDM_TENANT_CONFIGURATION_DATA** ppTenantConfigurationReturn, REST_SERVER_ERROR** ppError) { SSOERROR e = SSOERROR_NONE; PSTRING resourceUri = NULL; IDM_TENANT_CONFIGURATION_DATA* pTenantConfigurationReturn = NULL; REST_SERVER_ERROR* pError = NULL; size_t i = 0; if (pClient == NULL || IS_NULL_OR_EMPTY_STRING(tenant) || ppTenantConfigurationReturn == NULL || ppError == NULL) { e = SSOERROR_INVALID_ARGUMENT; BAIL_ON_ERROR(e); } e = RestBuildResourceUri( pClient, TENANT_POST_URI, tenant, "config", NULL, NULL, &resourceUri); BAIL_ON_ERROR(e); for (i = 0; i < pTenantConfigTypes->length; i++) { e = RestAppendQueryStringOnResourceUri( "type", IDM_TENANT_CONFIG_TYPE_ENUMS[*(pTenantConfigTypes->ppEntry[i])], i == 0, resourceUri, &resourceUri); BAIL_ON_ERROR(e); } e = RestBuildAndExecuteHttp( NULL, NULL, pClient->pAccessToken, resourceUri, REST_HTTP_METHOD_TYPE_POST, (JsonToDataObjectFunc) IdmJsonToTenantConfigurationData, (void**) &pTenantConfigurationReturn, pClient->tlsCAPath, &pError); BAIL_ON_ERROR(e); *ppTenantConfigurationReturn = pTenantConfigurationReturn; // debug if (DEBUG) { RestDebugJsonObject(*ppTenantConfigurationReturn, (DataObjectToJsonFunc) IdmTenantConfigurationDataToJson); } error: if (e != SSOERROR_NONE) { IdmTenantConfigurationDataDelete(pTenantConfigurationReturn); *ppError = pError; } // cleanup SSOStringFree(resourceUri); return e; }