MI_Result UpdateServerURLsToDSCCache( _In_ RegistrationManager *self, _Outptr_result_maybenull_ MI_Instance **cimErrorDetails) { MI_Application miApp = MI_APPLICATION_NULL; MI_Result result = MI_RESULT_OK; MI_Char* serverURLs = NULL; result = DSC_MI_Application_Initialize(0, NULL, NULL, &miApp); if (result != MI_RESULT_OK) { EH_Fail_(GetCimMIError(result, cimErrorDetails, ID_MODMAN_APPINIT_FAILED)); } result = FormatServerURLsForDscCache(self, &serverURLs, cimErrorDetails); EH_CheckResult(result); result = UpdateCurrentStatus(NULL, NULL, NULL, serverURLs, cimErrorDetails); EH_CheckResult(result); EH_UNWIND: if (serverURLs) { DSC_free(serverURLs); } MI_Application_Close(&miApp); return result; }
MI_Result CacheServerURL( _In_ RegistrationManager* self, _In_ MI_Instance* registrationData, _In_z_ MI_Char* thumbprint, _Outptr_result_maybenull_ MI_Instance **cimErrorDetails) { MI_Value value; MI_Result result = MI_RESULT_OK; if (cimErrorDetails) { *cimErrorDetails = NULL; } if (self->serverURLs == NULL) { InitializeServerURLs(self, cimErrorDetails); } result = MI_Instance_GetElement(registrationData, MSFT_ServerURL_Name, &value, NULL, NULL, NULL); EH_CheckResult(result); result = WriteServerURLToCache(self, value.string, thumbprint, cimErrorDetails); EH_CheckResult(result); EH_UNWIND: return result; }
static MI_Result WriteError(_In_ MI_Context* context, MI_Uint32 resultCode, _In_z_ const MI_Char* resultType, _In_z_ const MI_Char* errorMessage, _Out_ MI_Boolean *flag) { MI_Result returnValue = MI_RESULT_OK; MI_Instance* extendedError = NULL; NativeResourceProvider* nativeResourceProvider = (NativeResourceProvider*)context; if (!nativeResourceProvider->_private.resourceProviderClassLoaded) { DSC_EventUnSupportedHostMethodCalled(MI_T("PostIndication")); return MI_RESULT_NOT_SUPPORTED; } *flag = MI_TRUE; // TRUE indicates the provider can continue (this is a non-terminating error) returnValue = MI_Utilities_CimErrorFromErrorCode(resultCode, resultType, errorMessage, &extendedError); EH_CheckResult(returnValue); DoWriteError(NULL, nativeResourceProvider->_private.callbackContext, extendedError, NULL); EH_UNWIND; if (extendedError != NULL) MI_Instance_Delete(extendedError); return returnValue; }
MI_Result GetThumbprintForRegisteredServerURL( _In_ RegistrationManager* self, _In_ MI_Instance* registrationData, _Outptr_result_maybenull_z_ MI_Char** thumbprint, _Outptr_result_maybenull_ MI_Instance **cimErrorDetails) { size_t dwSize; MI_Value value; int retValue; MI_Uint32 i = 0; MI_Result result = MI_RESULT_OK; if (cimErrorDetails) { *cimErrorDetails = NULL; } *thumbprint = 0; if (self->serverURLs == NULL) { InitializeServerURLs(self, cimErrorDetails); } if (self->serverURLs != NULL) { result = MI_Instance_GetElement(registrationData, MSFT_ServerURL_Name, &value, NULL, NULL, NULL); EH_CheckResult(result); for (i = 0; i < self->numberOfServerURLs; i++) { if (self->serverURLs[i] != NULL && Tcscasecmp(self->serverURLs[i], value.string) == 0) { dwSize = Tcslen(self->serverCertificateThumbprints[i]) + 1; *thumbprint = (MI_Char*)DSC_malloc(dwSize*sizeof(MI_Char), NitsHere()); if (*thumbprint == NULL) { EH_Fail_(GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_LCMHELPER_MEMORY_ERROR)); } retValue = Stprintf(*thumbprint, dwSize, MI_T("%T"), self->serverCertificateThumbprints[i]); if (retValue == -1 || NitsShouldFault(NitsHere(), NitsAutomatic)) { DSC_free(*thumbprint); EH_Fail_(GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_LCMHELPER_PRINTF_ERROR)); } result = MI_RESULT_OK; break; } } } EH_UNWIND: return result; }
MI_Result WriteServerURLToCache( _In_ RegistrationManager* self, _In_z_ MI_Char* serverURL, _In_z_ MI_Char* thumbprint, _Outptr_result_maybenull_ MI_Instance **cimErrorDetails) { size_t dwSize; int retValue; MI_Result result = MI_RESULT_OK; if (cimErrorDetails) { *cimErrorDetails = NULL; } if (self->serverURLs == NULL) { result = InitializeServerURLs(self, cimErrorDetails); EH_CheckResult(result); } dwSize = Tcslen(serverURL) + 1; self->serverURLs[self->numberOfServerURLs] = (MI_Char*)DSC_malloc(dwSize* sizeof(MI_Char), NitsHere()); if (self->serverURLs[self->numberOfServerURLs] == NULL) { EH_Fail_(GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_LCMHELPER_MEMORY_ERROR)); } retValue = Stprintf(self->serverURLs[self->numberOfServerURLs], dwSize, MI_T("%T"), serverURL); if (retValue == -1 || NitsShouldFault(NitsHere(), NitsAutomatic)) { DSC_free(self->serverURLs[self->numberOfServerURLs]); EH_Fail_(GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_LCMHELPER_PRINTF_ERROR)); } dwSize = Tcslen(thumbprint) + 1; self->serverCertificateThumbprints[self->numberOfServerURLs] = (MI_Char*)DSC_malloc(dwSize* sizeof(MI_Char), NitsHere()); if (self->serverCertificateThumbprints[self->numberOfServerURLs] == NULL) { EH_Fail_(GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_LCMHELPER_MEMORY_ERROR)); } retValue = Stprintf(self->serverCertificateThumbprints[self->numberOfServerURLs], dwSize, MI_T("%T"), thumbprint); if (retValue == -1 || NitsShouldFault(NitsHere(), NitsAutomatic)) { DSC_free(self->serverCertificateThumbprints[self->numberOfServerURLs]); EH_Fail_(GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_LCMHELPER_PRINTF_ERROR)); } self->numberOfServerURLs++; EH_UNWIND: return result; }
/*Function to return true if registration needs to be done*/ MI_Boolean ShouldDoRegistration( _In_ RegistrationManager* self, _In_ RegistrationRequest* request, _Outptr_result_maybenull_ MI_Instance **cimErrorDetails) { MI_Result result = MI_RESULT_OK; MI_Uint32 i = 0; MI_Value value; MI_Char* url = NULL; MI_Type type; MI_Uint32 flags; if (cimErrorDetails) { *cimErrorDetails = NULL; } MI_Instance *registrationDataInstance = request->registrationData; result = MI_Instance_GetElement(registrationDataInstance, MSFT_ServerURL_Name, &value, NULL, NULL, NULL); EH_CheckResult(result); url = value.string; result = DSC_MI_Instance_GetElement(registrationDataInstance, MSFT_RegistrationKey_Name, &value, &type, &flags, NULL); if (result == MI_RESULT_OK && type == MI_STRING && (!(flags & MI_FLAG_NULL))) { if (Tcscasecmp(value.string, MI_T("")) != 0) { // This means that a non-empty RegistrationKey is specified. Then, we always do registration. // If RegistrationKey is not specified, then we check the cache and do/skip registration based on ServerURL DSC_EventWriteLCMAgentAttemptRegistration(g_ConfigurationDetails.jobGuidString, self->agentId, url); return MI_TRUE; } } for (i = 0; i < self->numberOfServerURLs; i++) { if (Tcscasecmp(self->serverURLs[i], url) == 0) { DSC_EventWriteLCMServerURLRegistered(g_ConfigurationDetails.jobGuidString, self->agentId, url); return MI_FALSE; } } EH_UNWIND: return MI_TRUE; }
MI_Result PopulateServerURLs( _In_ RegistrationManager* self, _Outptr_result_maybenull_ MI_Instance **cimErrorDetails) { MI_Result result = MI_RESULT_OK; MI_Char* registeredServerURLs = NULL; MI_Char* token = NULL; MI_Char* thumbprint = NULL; MI_Char *next_token = NULL; if (cimErrorDetails) { *cimErrorDetails = NULL; } result = GetRegisteredServerURLsFromCache(®isteredServerURLs, cimErrorDetails); // If we are not able to retrieve the URLs from the cache, we just initialize to an empty list. if (result != MI_RESULT_OK) { result = InitializeServerURLs(self, cimErrorDetails); EH_CheckResult(result); } else { if ((registeredServerURLs != NULL) || (g_DSCInternalCache != NULL)) { token = Tcstok(registeredServerURLs, ";", &next_token); while (token != NULL) { // thumbprint can be null as in http:\\xxx;;http:\\yyy;xxxxxx thumbprint = Tcstok(NULL, ";", &next_token); result = WriteServerURLToCache(self, token, thumbprint, cimErrorDetails); if (result != MI_RESULT_OK) { result = InitializeServerURLs(self, cimErrorDetails); EH_CheckResult(result); // There is no point in proceeding with the other URLs as we could hit the same error that we hit this time // So, initialize to Empty list and break break; } token = Tcstok(NULL, ";", &next_token); } } else { // We will be here in the following 2 cases // 1) Cache does not exist // 2) There were no Server URLs in the cache result = InitializeServerURLs(self, cimErrorDetails); EH_CheckResult(result); } } EH_UNWIND: if (registeredServerURLs != NULL) { DSC_free(registeredServerURLs); } return result; }
/*Function to perform registration*/ MI_Result Register( _In_ RegistrationManager* self, _In_ RegistrationRequest* request, _Outptr_result_maybenull_ MI_Instance **cimErrorDetails) { MI_Result result = MI_RESULT_OK; MI_Instance* registrationPayload = NULL; MI_Uint32 getActionStatusCode; MI_Char* resultStatus = NULL; MI_Char* thumbprint = NULL; MI_Value value; MI_Uint32 flags; int systemResult = 0; if (cimErrorDetails) { *cimErrorDetails = NULL; } // Check if RegistrationKey is specified. If not specified, do not attempt to register. result = MI_Instance_GetElement(request->registrationData, MSFT_RegistrationKey_Name, &value, NULL, &flags, NULL); if (result != MI_RESULT_OK || flags & MI_FLAG_NULL || value.string == NULL || value.string[0] == '\0') { return MI_RESULT_OK; } if ( (access(OAAS_KEYPATH, F_OK) == -1) || (access(OAAS_CERTPATH, F_OK) == -1) ) { system("touch " OAAS_KEYPATH "; chmod 0600 " OAAS_KEYPATH); system("touch " OAAS_KEYPATH "_old; chmod 0600 " OAAS_KEYPATH "_old"); systemResult = system("openssl req -subj '/CN=DSC-OaaS' -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout " OAAS_KEYPATH "_old -out " OAAS_CERTPATH " && openssl rsa -in " OAAS_KEYPATH "_old -out " OAAS_KEYPATH " && rm -f " OAAS_KEYPATH "_old"); if (systemResult != 0 && errno != 10) { DSC_EventWriteLCMServerRegCertGenFailed(g_ConfigurationDetails.jobGuidString, self->agentId); return GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_PULL_FAILEDTOGENERATECERT); } systemResult = system("openssl x509 -noout -in " OAAS_CERTPATH " -fingerprint | sed 's/^.*=//' > " OAAS_THUMBPRINTPATH); if (systemResult != 0 && errno != 10) { DSC_EventWriteLCMServerRegCertGenFailed(g_ConfigurationDetails.jobGuidString, self->agentId); return GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_PULL_FAILEDTOGENERATECERT); } { long length; FILE * fingerprint_file = fopen (OAAS_THUMBPRINTPATH, "r"); if (fingerprint_file) { fseek (fingerprint_file, 0, SEEK_END); length = ftell (fingerprint_file); fseek (fingerprint_file, 0, SEEK_SET); thumbprint = DSC_malloc (length * sizeof(MI_Char), NitsHere()); fread (thumbprint, 1, length, fingerprint_file); // There's a newline at the end, so null terminate overwriting it. thumbprint[length-1] = '\0'; fclose (fingerprint_file); } else { DSC_EventWriteLCMServerRegCertGenFailed(g_ConfigurationDetails.jobGuidString, self->agentId); return MI_RESULT_FAILED; } } // Cache this URL. // result = CacheServerURL(self, request->registrationData, thumbprint, cimErrorDetails); //EH_CheckResult(result); // Write this cache to DSC Cache //result = UpdateServerURLsToDSCCache(self, cimErrorDetails); //EH_CheckResult(result); } result = GetAgentInformation(®istrationPayload); EH_CheckResult(result); result = LCM_Do_Register((MI_Instance *)g_metaConfig, request->registrationData, self->agentId, thumbprint, registrationPayload, &request->configurationNames, request->typeOfManagerInstance, &resultStatus, &getActionStatusCode, cimErrorDetails); EH_CheckResult(result); EH_UNWIND: if (registrationPayload != NULL) { MI_Instance_Delete(registrationPayload); } if (thumbprint != NULL) { DSC_free(thumbprint); } #ifdef _MSC_VER DSC_GlobalFree(resultStatus); #else DSC_free(resultStatus); #endif return result; }