BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname) { int length; DWORD status; DWORD SpnLength; LPTSTR hostnameX; length = 0; #ifdef UNICODE length = strlen(hostname); hostnameX = (LPWSTR) malloc(length * sizeof(TCHAR)); MultiByteToWideChar(CP_ACP, 0, hostname, length, hostnameX, length); hostnameX[length] = 0; #else hostnameX = hostname; #endif SpnLength = 0; status = DsMakeSpn(ServiceClass, hostnameX, NULL, 0, NULL, &SpnLength, NULL); if (status != ERROR_BUFFER_OVERFLOW) return FALSE; ntlm->ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR)); status = DsMakeSpn(ServiceClass, hostnameX, NULL, 0, NULL, &SpnLength, ntlm->ServicePrincipalName); if (status != ERROR_SUCCESS) return -1; return TRUE; }
int TestDsMakeSpn(int argc, char* argv[]) { int rc = -1; LPTSTR Spn = NULL; DWORD status; DWORD SpnLength; SpnLength = -1; status = DsMakeSpn(testServiceClass, testServiceName, NULL, 0, NULL, &SpnLength, NULL); if (status != ERROR_INVALID_PARAMETER) { _tprintf(_T("DsMakeSpn: expected ERROR_INVALID_PARAMETER\n")); goto fail; } SpnLength = 0; status = DsMakeSpn(testServiceClass, testServiceName, NULL, 0, NULL, &SpnLength, NULL); if (status != ERROR_BUFFER_OVERFLOW) { _tprintf(_T("DsMakeSpn: expected ERROR_BUFFER_OVERFLOW\n")); goto fail; } if (SpnLength != 37) { _tprintf(_T("DsMakeSpn: SpnLength mismatch: Actual: %")_T(PRIu32)_T(", Expected: 37\n"), SpnLength); goto fail; } /* SpnLength includes null terminator */ Spn = (LPTSTR) calloc(SpnLength, sizeof(TCHAR)); if (!Spn) { _tprintf(_T("DsMakeSpn: Unable to allocate memroy\n")); goto fail; } status = DsMakeSpn(testServiceClass, testServiceName, NULL, 0, NULL, &SpnLength, Spn); if (status != ERROR_SUCCESS) { _tprintf(_T("DsMakeSpn: expected ERROR_SUCCESS\n")); goto fail; } if (_tcscmp(Spn, testSpn) != 0) { _tprintf(_T("DsMakeSpn: SPN mismatch: Actual: %s, Expected: %s\n"), Spn, testSpn); goto fail; } _tprintf(_T("DsMakeSpn: %s\n"), Spn); rc = 0; fail: free(Spn); return rc; }
LPTSTR nla_make_spn(const char* ServiceClass, const char* hostname) { DWORD status; DWORD SpnLength; LPTSTR hostnameX = NULL; LPTSTR ServiceClassX = NULL; LPTSTR ServicePrincipalName = NULL; #ifdef UNICODE ConvertToUnicode(CP_UTF8, 0, hostname, -1, &hostnameX, 0); ConvertToUnicode(CP_UTF8, 0, ServiceClass, -1, &ServiceClassX, 0); #else hostnameX = _strdup(hostname); ServiceClassX = _strdup(ServiceClass); #endif if (!hostnameX || !ServiceClassX) { free(hostnameX); free(ServiceClassX); return NULL; } if (!ServiceClass) { ServicePrincipalName = (LPTSTR) _tcsdup(hostnameX); free(ServiceClassX); free(hostnameX); return ServicePrincipalName; } SpnLength = 0; status = DsMakeSpn(ServiceClassX, hostnameX, NULL, 0, NULL, &SpnLength, NULL); if (status != ERROR_BUFFER_OVERFLOW) { free(ServiceClassX); free(hostnameX); return NULL; } ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR)); if (!ServicePrincipalName) return NULL; status = DsMakeSpn(ServiceClassX, hostnameX, NULL, 0, NULL, &SpnLength, ServicePrincipalName); if (status != ERROR_SUCCESS) { free(ServicePrincipalName); free(ServiceClassX); free(hostnameX); return NULL; } free(ServiceClassX); free(hostnameX); return ServicePrincipalName; }
BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname) { BOOL status = FALSE; DWORD SpnLength = 0; LPTSTR hostnameX = NULL; #ifdef UNICODE ConvertToUnicode(CP_UTF8, 0, hostname, -1, (LPWSTR*) &hostnameX, 0); #else hostnameX = _strdup(hostname); #endif if (!hostnameX) return FALSE; if (!ServiceClass) { ntlm->ServicePrincipalName = (LPTSTR) _tcsdup(hostnameX); free(hostnameX); if (!ntlm->ServicePrincipalName) return FALSE; return TRUE; } if (DsMakeSpn(ServiceClass, hostnameX, NULL, 0, NULL, &SpnLength, NULL) != ERROR_BUFFER_OVERFLOW) goto error; ntlm->ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR)); if (!ntlm->ServicePrincipalName) goto error; if (DsMakeSpn(ServiceClass, hostnameX, NULL, 0, NULL, &SpnLength, ntlm->ServicePrincipalName) != ERROR_SUCCESS) goto error; status = TRUE; error: free(hostnameX); return status; }
int smpd_lookup_spn(char *target, int length, const char *host, int port) { int result; char err_msg[256]; ULONG len = length/*SMPD_MAX_NAME_LENGTH*/; char *env; smpd_host_spn_node_t *iter; env = getenv("MPICH_SPN"); if (env) { MPIU_Strncpy(target, env, SMPD_MAX_NAME_LENGTH); return SMPD_SUCCESS; } smpd_build_spn_list(); iter = spn_list; while (iter != NULL) { if (stricmp(iter->host, host) == 0) { MPIU_Strncpy(target, iter->spn, SMPD_MAX_NAME_LENGTH); return SMPD_SUCCESS; } if (stricmp(iter->dnshost, host) == 0) { MPIU_Strncpy(target, iter->spn, SMPD_MAX_NAME_LENGTH); return SMPD_SUCCESS; } iter = iter->next; } result = DsMakeSpn(SMPD_SERVICE_NAME, NULL, host, (USHORT)port, NULL, &len, target); if (result != ERROR_SUCCESS) { smpd_translate_win_error(result, err_msg, 255, NULL); smpd_err_printf("DsMakeSpn(%s, %s, %d) failed: %s\n", SMPD_SERVICE_NAME, host, port, err_msg); return SMPD_FAIL; } /*result = DsMakeSpn(SMPD_SERVICE_NAME, SMPD_SERVICE_NAME, NULL, 0, NULL, &len, target);*/ /* char **spns; result = DsGetSpn(DS_SPN_DNS_HOST, SMPD_SERVICE_NAME, NULL, port, 1, &host, NULL, &len, &spns); if (result != ERROR_SUCCESS) { smpd_translate_win_error(result, err_msg, 255, NULL); smpd_err_printf("DsGetSpn failed: %s\n", err_msg); return SMPD_FAIL; } MPIU_Strncpy(target, spns[0], SMPD_MAX_NAME_LENGTH); DsFreeSpnArray(1, spns); */ /*MPIU_Snprintf(target, SMPD_MAX_NAME_LENGTH, "%s/%s:%d", SMPD_SERVICE_NAME, host, port);*/ return SMPD_SUCCESS; }
BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* password) { SECURITY_STATUS status; sspi_GlobalInit(); #ifdef WITH_NATIVE_SSPI { HMODULE hSSPI; INIT_SECURITY_INTERFACE InitSecurityInterface; PSecurityFunctionTable pSecurityInterface = NULL; hSSPI = LoadLibrary(_T("secur32.dll")); #ifdef UNICODE InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceW"); #else InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceA"); #endif ntlm->table = (*InitSecurityInterface)(); } #else ntlm->table = InitSecurityInterface(); #endif sspi_SetAuthIdentity(&(ntlm->identity), user, domain, password); if (http) { DWORD status; DWORD SpnLength; SpnLength = 0; status = DsMakeSpn(_T("HTTP"), _T("LAB1-W2K8R2-GW.lab1.awake.local"), NULL, 0, NULL, &SpnLength, NULL); if (status != ERROR_BUFFER_OVERFLOW) { _tprintf(_T("DsMakeSpn: expected ERROR_BUFFER_OVERFLOW\n")); return -1; } ntlm->ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR)); status = DsMakeSpn(_T("HTTP"), _T("LAB1-W2K8R2-GW.lab1.awake.local"), NULL, 0, NULL, &SpnLength, ntlm->ServicePrincipalName); } status = ntlm->table->QuerySecurityPackageInfo(NTLMSP_NAME, &ntlm->pPackageInfo); if (status != SEC_E_OK) { printf("QuerySecurityPackageInfo status: 0x%08X\n", status); return FALSE; } ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken; status = ntlm->table->AcquireCredentialsHandle(NULL, NTLMSP_NAME, SECPKG_CRED_OUTBOUND, NULL, &ntlm->identity, NULL, NULL, &ntlm->credentials, &ntlm->expiration); if (status != SEC_E_OK) { printf("AcquireCredentialsHandle status: 0x%08X\n", status); return FALSE; } ntlm->haveContext = FALSE; ntlm->haveInputBuffer = FALSE; ZeroMemory(&ntlm->inputBuffer, sizeof(SecBuffer)); ZeroMemory(&ntlm->outputBuffer, sizeof(SecBuffer)); ZeroMemory(&ntlm->ContextSizes, sizeof(SecPkgContext_Sizes)); ntlm->fContextReq = 0; if (http) { /* flags for HTTP authentication */ ntlm->fContextReq |= ISC_REQ_CONFIDENTIALITY; } else { /** * flags for RPC authentication: * RPC_C_AUTHN_LEVEL_PKT_INTEGRITY: * ISC_REQ_USE_DCE_STYLE | ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH | * ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT */ ntlm->fContextReq |= ISC_REQ_USE_DCE_STYLE; ntlm->fContextReq |= ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH; ntlm->fContextReq |= ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT; } return TRUE; }