jboolean shaj_init(loginfo_t* logger) { hSecDllReference = LoadSecurityDll(logger); if (hSecDllReference == NULL) { shaj_log_error(logger, "problem loading security dll"); return JNI_FALSE; } return JNI_TRUE; }
static void* mydlsym(void* libhandle, const char* fname, loginfo_t* logger) { char* error; void* fn; fn = dlsym(libhandle, fname); error = dlerror(); if (error != NULL) { shaj_log_error(logger, "dlsym could not find %s: %s\n", fname, error); return NULL; } return fn; }
/* return 1 on success */ static jboolean mypam__init(loginfo_t* logger) { if (logger->isdebug) { shaj_log_debug(logger, "attempting to load libpam.so"); } libpam = dlopen ("libpam.so", RTLD_NOW | RTLD_GLOBAL); if (libpam == NULL) { shaj_log_error(logger, "Could not dlopen libpam.so with RTLD_NOW|RTLD_GLOBAL: %s\n", dlerror());; return JNI_FALSE; } real_pam_start = (FUNC_pam_start*) mydlsym(libpam, "pam_start", logger); if (real_pam_start == NULL) { return JNI_FALSE; } real_pam_end = (FUNC_pam_end*) mydlsym(libpam, "pam_end", logger); if (real_pam_end == NULL) { return JNI_FALSE; } real_pam_authenticate = (FUNC_pam_authenticate*) mydlsym(libpam, "pam_authenticate", logger); if (real_pam_authenticate == NULL) { return JNI_FALSE; } real_pam_strerror = (FUNC_pam_strerror*) mydlsym(libpam, "pam_strerror", logger); if (real_pam_strerror == NULL) { return JNI_FALSE; } real_pam_setcred = (FUNC_pam_setcred*) mydlsym(libpam, "pam_setcred", logger); if (real_pam_setcred == NULL) { return JNI_FALSE; } return JNI_TRUE; }
static int ourpam_conversation(int nmsgs, #ifndef OS_IS_SOLARIS const #endif struct pam_message **msg, struct pam_response **resp, void *authdatap) { /* * strings we pass to PAM in the reply objects are freed by * PAM as described here * http://www.opengroup.org/onlinepubs/8329799/chap5.htm */ int replies = 0; struct pam_response *reply = 0; struct ourpam_authdata *authdata = (struct ourpam_authdata *) authdatap; loginfo_t* logger = authdata->logger; reply = (struct pam_response *) calloc(nmsgs, sizeof(*reply)); if (!reply) return PAM_CONV_ERR; for (replies = 0; replies < nmsgs; replies++) { switch (msg[replies]->msg_style) { case PAM_PROMPT_ECHO_ON: reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = strdup(authdata->user); shaj_log_debug(logger, " PAM ECHO_ON(\"%s\") ==> \"%s\"", msg[replies]->msg, reply[replies].resp); break; case PAM_PROMPT_ECHO_OFF: reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = strdup(authdata->password); shaj_log_debug(logger, " PAM ECHO_OFF(\"%s\") ==> password", /*msg[replies]->msg*/ "(masked)"); break; case PAM_TEXT_INFO: /* ignore */ reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = 0; shaj_log_debug(logger, " PAM TEXT_INFO(\"%s\") ==> ignored", msg[replies]->msg); break; case PAM_ERROR_MSG: /* ignore it */ reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = 0; shaj_log_debug(logger, " PAM ERROR_MSG(\"%s\") ==> ignored", msg[replies]->msg); break; default: /* fail at this point */ free (reply); shaj_log_error(logger, " PAM unknown %d(\"%s\") ==> ignored", msg[replies]->msg_style, msg[replies]->msg); return PAM_CONV_ERR; } } *resp = reply; return PAM_SUCCESS; }
HMODULE LoadSecurityDll(loginfo_t* logger) { HMODULE hModule; BOOL fAllFunctionsLoaded = FALSE; TCHAR lpszDLL[MAX_PATH]; OSVERSIONINFO VerInfo; // // Find out which security DLL to use, depending on // whether we are on NT or Win95 or 2000 or XP or Windows Server 2003 // We have to use security.dll on Windows NT 4.0. // All other operating systems, we have to use Secur32.dll // VerInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (!GetVersionEx (&VerInfo)) // If this fails, something has gone wrong { shaj_log_error(logger, "problem determining windows version"); return FALSE; } if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && VerInfo.dwMajorVersion == 4 && VerInfo.dwMinorVersion == 0) { lstrcpy (lpszDLL, _T("security.dll")); } else { lstrcpy (lpszDLL, _T("secur32.dll")); } hModule = LoadLibrary(lpszDLL); if (!hModule) { shaj_log_error(logger, "problem loading %s", (char*)lpszDLL); return NULL; } __try { _AcceptSecurityContext = (ACCEPT_SECURITY_CONTEXT_FN) GetProcAddress(hModule, "AcceptSecurityContext"); if (!_AcceptSecurityContext) { shaj_log_error(logger, "problem with function AcceptSecurityContext"); __leave; } #ifdef UNICODE _AcquireCredentialsHandle = (ACQUIRE_CREDENTIALS_HANDLE_FN) GetProcAddress(hModule, "AcquireCredentialsHandleW"); #else _AcquireCredentialsHandle = (ACQUIRE_CREDENTIALS_HANDLE_FN) GetProcAddress(hModule, "AcquireCredentialsHandleA"); #endif if (!_AcquireCredentialsHandle) { shaj_log_error(logger, "problem with function AcquireCredentialsHandle"); __leave; } // CompleteAuthToken is not present on Windows 9x Secur32.dll // Do not check for the availablity of the function if it is NULL; _CompleteAuthToken = (COMPLETE_AUTH_TOKEN_FN) GetProcAddress(hModule, "CompleteAuthToken"); _DeleteSecurityContext = (DELETE_SECURITY_CONTEXT_FN) GetProcAddress(hModule, "DeleteSecurityContext"); if (!_DeleteSecurityContext) { shaj_log_error(logger, "problem with function DeleteSecurityContext"); __leave; } _FreeContextBuffer = (FREE_CONTEXT_BUFFER_FN) GetProcAddress(hModule, "FreeContextBuffer"); if (!_FreeContextBuffer) { shaj_log_error(logger, "problem with function FreeContextBuffer"); __leave; } _FreeCredentialsHandle = (FREE_CREDENTIALS_HANDLE_FN) GetProcAddress(hModule, "FreeCredentialsHandle"); if (!_FreeCredentialsHandle) { shaj_log_error(logger, "problem with function FreeCredentialsHandle"); __leave; } #ifdef UNICODE _InitializeSecurityContext = (INITIALIZE_SECURITY_CONTEXT_FN) GetProcAddress(hModule, "InitializeSecurityContextW"); #else _InitializeSecurityContext = (INITIALIZE_SECURITY_CONTEXT_FN) GetProcAddress(hModule, "InitializeSecurityContextA"); #endif if (!_InitializeSecurityContext) { shaj_log_error(logger, "problem with function InitializeSecurityContext"); __leave; } #ifdef UNICODE _QuerySecurityPackageInfo = (QUERY_SECURITY_PACKAGE_INFO_FN) GetProcAddress(hModule, "QuerySecurityPackageInfoW"); #else _QuerySecurityPackageInfo = (QUERY_SECURITY_PACKAGE_INFO_FN) GetProcAddress(hModule, "QuerySecurityPackageInfoA"); #endif if (!_QuerySecurityPackageInfo) { shaj_log_error(logger, "problem with function QuerySecurityPackageInfo"); __leave; } fAllFunctionsLoaded = TRUE; } __finally { if (!fAllFunctionsLoaded) { UnloadSecurityDll(hModule); hModule = NULL; } } return hModule; }
BOOL GenServerContext(PAUTH_SEQ pAS, PVOID pIn, DWORD cbIn, PVOID pOut, PDWORD pcbOut, PBOOL pfDone, loginfo_t* logger) { /*++ Routine Description: Takes an input buffer coming from the client and returns a buffer to be sent to the client. Also returns an indication of whether or not the context is complete. Return Value: Returns TRUE if successful; otherwise FALSE. --*/ SECURITY_STATUS ss; TimeStamp tsExpiry; SecBufferDesc sbdOut; SecBuffer sbOut; SecBufferDesc sbdIn; SecBuffer sbIn; ULONG fContextAttr; if (!pAS->fInitialized) { ss = _AcquireCredentialsHandle(NULL, _T("NTLM"), SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &pAS->hcred, &tsExpiry); if (ss < 0) { shaj_log_error(logger, "AcquireCredentialsHandle failed with %08X\n", ss); return FALSE; } pAS->fHaveCredHandle = TRUE; } // Prepare output buffer sbdOut.ulVersion = 0; sbdOut.cBuffers = 1; sbdOut.pBuffers = &sbOut; sbOut.cbBuffer = *pcbOut; sbOut.BufferType = SECBUFFER_TOKEN; sbOut.pvBuffer = pOut; // Prepare input buffer sbdIn.ulVersion = 0; sbdIn.cBuffers = 1; sbdIn.pBuffers = &sbIn; sbIn.cbBuffer = cbIn; sbIn.BufferType = SECBUFFER_TOKEN; sbIn.pvBuffer = pIn; ss = _AcceptSecurityContext(&pAS->hcred, pAS->fInitialized ? &pAS->hctxt : NULL, &sbdIn, 0, SECURITY_NATIVE_DREP, &pAS->hctxt, &sbdOut, &fContextAttr, &tsExpiry); if (ss < 0) { shaj_log_debug(logger, "AcceptSecurityContext failed with %08X\n", ss); return FALSE; } pAS->fHaveCtxtHandle = TRUE; // If necessary, complete token if (ss == SEC_I_COMPLETE_NEEDED || ss == SEC_I_COMPLETE_AND_CONTINUE) { if (_CompleteAuthToken) { ss = _CompleteAuthToken(&pAS->hctxt, &sbdOut); if (ss < 0) { shaj_log_debug(logger, "CompleteAuthToken failed with %08X\n", ss); return FALSE; } } else { shaj_log_debug(logger, "CompleteAuthToken not supported.\n"); return FALSE; } } *pcbOut = sbOut.cbBuffer; if (!pAS->fInitialized) pAS->fInitialized = TRUE; *pfDone = !(ss = SEC_I_CONTINUE_NEEDED || ss == SEC_I_COMPLETE_AND_CONTINUE); return TRUE; }