static int init_advapi(void) { advapi = load_system32_dll("advapi32.dll"); return advapi && GET_WINDOWS_FUNCTION(advapi, OpenProcessToken) && GET_WINDOWS_FUNCTION(advapi, GetTokenInformation) && GET_WINDOWS_FUNCTION(advapi, InitializeSecurityDescriptor) && GET_WINDOWS_FUNCTION(advapi, SetSecurityDescriptorOwner); }
static char *sk_handle_peer_info(Socket s) { Handle_Socket ps = (Handle_Socket) s; ULONG pid; static HMODULE kernel32_module; DECL_WINDOWS_FUNCTION(static, BOOL, GetNamedPipeClientProcessId, (HANDLE, PULONG)); if (!kernel32_module) { kernel32_module = load_system32_dll("kernel32.dll"); #if (defined _MSC_VER && _MSC_VER < 1900) || defined __MINGW32__ || defined COVERITY /* For older Visual Studio, and MinGW too (at least as of * Ubuntu 16.04), this function isn't available in the header * files to type-check. Ditto the toolchain I use for * Coveritying the Windows code. */ GET_WINDOWS_FUNCTION_NO_TYPECHECK( kernel32_module, GetNamedPipeClientProcessId); #else GET_WINDOWS_FUNCTION( kernel32_module, GetNamedPipeClientProcessId); #endif } /* * Of course, not all handles managed by this module will be * server ends of named pipes, but if they are, then it's useful * to log what we can find out about the client end. */ if (p_GetNamedPipeClientProcessId && p_GetNamedPipeClientProcessId(ps->send_H, &pid)) return dupprintf("process id %lu", (unsigned long)pid); return NULL; }
char *get_username(void) { DWORD namelen; char *user; int got_username = FALSE; DECL_WINDOWS_FUNCTION(static, BOOLEAN, GetUserNameExA, (EXTENDED_NAME_FORMAT, LPSTR, PULONG)); { static int tried_usernameex = FALSE; if (!tried_usernameex) { /* Not available on Win9x, so load dynamically */ HMODULE secur32 = load_system32_dll("secur32.dll"); GET_WINDOWS_FUNCTION(secur32, GetUserNameExA); tried_usernameex = TRUE; } } if (p_GetUserNameExA) { /* * If available, use the principal -- this avoids the problem * that the local username is case-insensitive but Kerberos * usernames are case-sensitive. */ /* Get the length */ namelen = 0; (void) p_GetUserNameExA(NameUserPrincipal, NULL, &namelen); user = snewn(namelen, char); got_username = p_GetUserNameExA(NameUserPrincipal, user, &namelen); if (got_username) { char *p = strchr(user, '@'); if (p) *p = 0; } else { sfree(user); } } if (!got_username) { /* Fall back to local user name */ namelen = 0; if (GetUserName(NULL, &namelen) == FALSE) { /* * Apparently this doesn't work at least on Windows XP SP2. * Thus assume a maximum of 256. It will fail again if it * doesn't fit. */ namelen = 256; } user = snewn(namelen, char); got_username = GetUserName(user, &namelen); if (!got_username) { sfree(user); } }
void noise_get_heavy(void (*func) (void *, int)) { HANDLE srch; WIN32_FIND_DATA finddata; DWORD pid; HCRYPTPROV crypt_provider; char winpath[MAX_PATH + 3]; GetWindowsDirectory(winpath, sizeof(winpath)); strcat(winpath, "\\*"); srch = FindFirstFile(winpath, &finddata); if (srch != INVALID_HANDLE_VALUE) { do { func(&finddata, sizeof(finddata)); } while (FindNextFile(srch, &finddata)); FindClose(srch); } pid = GetCurrentProcessId(); func(&pid, sizeof(pid)); if (!wincrypt_module) { wincrypt_module = load_system32_dll("advapi32.dll"); GET_WINDOWS_FUNCTION(wincrypt_module, CryptAcquireContextA); GET_WINDOWS_FUNCTION(wincrypt_module, CryptGenRandom); GET_WINDOWS_FUNCTION(wincrypt_module, CryptReleaseContext); } if (wincrypt_module && p_CryptAcquireContextA && p_CryptGenRandom && p_CryptReleaseContext && p_CryptAcquireContextA(&crypt_provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { BYTE buf[32]; if (p_CryptGenRandom(crypt_provider, 32, buf)) { func(buf, sizeof(buf)); } p_CryptReleaseContext(crypt_provider, 0); } read_random_seed(func); /* Update the seed immediately, in case another instance uses it. */ random_save_seed(); }
bool win_read_random(void *buf, unsigned wanted) { bool toret = false; HCRYPTPROV crypt_provider; if (!wincrypt_module) { wincrypt_module = load_system32_dll("advapi32.dll"); GET_WINDOWS_FUNCTION(wincrypt_module, CryptAcquireContextA); GET_WINDOWS_FUNCTION(wincrypt_module, CryptGenRandom); GET_WINDOWS_FUNCTION(wincrypt_module, CryptReleaseContext); } if (wincrypt_module && p_CryptAcquireContextA && p_CryptGenRandom && p_CryptReleaseContext && p_CryptAcquireContextA(&crypt_provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { toret = p_CryptGenRandom(crypt_provider, wanted, buf); p_CryptReleaseContext(crypt_provider, 0); } return toret; }
int got_crypt(void) { static int attempted = FALSE; static int successful; static HMODULE crypt; if (!attempted) { attempted = TRUE; crypt = load_system32_dll("crypt32.dll"); successful = crypt && GET_WINDOWS_FUNCTION(crypt, CryptProtectMemory); } return successful; }
void init_help(void) { char b[2048], *p, *q, *r; FILE *fp; GetModuleFileName(NULL, b, sizeof(b) - 1); r = b; p = strrchr(b, '\\'); if (p && p >= r) r = p+1; q = strrchr(b, ':'); if (q && q >= r) r = q+1; strcpy(r, PUTTY_HELP_FILE); if ( (fp = fopen(b, "r")) != NULL) { help_path = dupstr(b); fclose(fp); } else help_path = NULL; strcpy(r, PUTTY_HELP_CONTENTS); if ( (fp = fopen(b, "r")) != NULL) { help_has_contents = TRUE; fclose(fp); } else help_has_contents = FALSE; #ifndef NO_HTMLHELP strcpy(r, PUTTY_CHM_FILE); if ( (fp = fopen(b, "r")) != NULL) { chm_path = dupstr(b); fclose(fp); } else chm_path = NULL; if (chm_path) { HINSTANCE dllHH = load_system32_dll("hhctrl.ocx"); GET_WINDOWS_FUNCTION(dllHH, HtmlHelpA); if (!p_HtmlHelpA) { chm_path = NULL; if (dllHH) FreeLibrary(dllHH); } } #endif /* NO_HTMLHELP */ }
int ssh_gss_init(void) { if (security_module) return 1; /* already initialised */ security_module = LoadLibrary("secur32.dll"); if (security_module) { GET_WINDOWS_FUNCTION(security_module, AcquireCredentialsHandleA); GET_WINDOWS_FUNCTION(security_module, InitializeSecurityContextA); GET_WINDOWS_FUNCTION(security_module, FreeContextBuffer); GET_WINDOWS_FUNCTION(security_module, FreeCredentialsHandle); GET_WINDOWS_FUNCTION(security_module, DeleteSecurityContext); GET_WINDOWS_FUNCTION(security_module, QueryContextAttributesA); GET_WINDOWS_FUNCTION(security_module, MakeSignature); return 1; } return 0; }
bool got_crypt(void) { static bool attempted = false; static bool successful; static HMODULE crypt; if (!attempted) { attempted = true; crypt = load_system32_dll("crypt32.dll"); successful = crypt && #ifdef COVERITY /* The build toolchain I use with Coverity doesn't know * about this function, so can't type-check it */ GET_WINDOWS_FUNCTION_NO_TYPECHECK(crypt, CryptProtectMemory) #else GET_WINDOWS_FUNCTION(crypt, CryptProtectMemory) #endif ; } return successful; }
int got_advapi(void) { static int attempted = FALSE; static int successful; static HMODULE advapi; if (!attempted) { attempted = TRUE; advapi = load_system32_dll("advapi32.dll"); successful = advapi && GET_WINDOWS_FUNCTION(advapi, GetSecurityInfo) && GET_WINDOWS_FUNCTION(advapi, SetSecurityInfo) && GET_WINDOWS_FUNCTION(advapi, OpenProcessToken) && GET_WINDOWS_FUNCTION(advapi, GetTokenInformation) && GET_WINDOWS_FUNCTION(advapi, InitializeSecurityDescriptor) && GET_WINDOWS_FUNCTION(advapi, SetSecurityDescriptorOwner) && GET_WINDOWS_FUNCTION(advapi, SetEntriesInAclA); } return successful; }
static char *sk_handle_peer_info(Socket s) { Handle_Socket ps = (Handle_Socket) s; ULONG pid; static HMODULE kernel32_module; DECL_WINDOWS_FUNCTION(static, BOOL, GetNamedPipeClientProcessId, (HANDLE, PULONG)); if (!kernel32_module) { kernel32_module = load_system32_dll("kernel32.dll"); GET_WINDOWS_FUNCTION(kernel32_module, GetNamedPipeClientProcessId); } /* * Of course, not all handles managed by this module will be * server ends of named pipes, but if they are, then it's useful * to log what we can find out about the client end. */ if (p_GetNamedPipeClientProcessId && p_GetNamedPipeClientProcessId(ps->send_H, &pid)) return dupprintf("process id %lu", (unsigned long)pid); return NULL; }
void sk_init(void) { #ifndef NO_IPV6 winsock2_module = #endif winsock_module = load_system32_dll("ws2_32.dll"); if (!winsock_module) { winsock_module = load_system32_dll("wsock32.dll"); } if (!winsock_module) { fatalbox("Unable to load any WinSock library"); } #ifndef NO_IPV6 /* Check if we have getaddrinfo in Winsock */ if (GetProcAddress(winsock_module, "getaddrinfo") != NULL) { #ifdef NET_SETUP_DIAGNOSTICS logevent(NULL, "Native WinSock IPv6 support detected"); #endif GET_WINDOWS_FUNCTION(winsock_module, getaddrinfo); GET_WINDOWS_FUNCTION(winsock_module, freeaddrinfo); GET_WINDOWS_FUNCTION(winsock_module, getnameinfo); GET_WINDOWS_FUNCTION(winsock_module, gai_strerror); } else { /* Fall back to wship6.dll for Windows 2000 */ wship6_module = load_system32_dll("wship6.dll"); if (wship6_module) { #ifdef NET_SETUP_DIAGNOSTICS logevent(NULL, "WSH IPv6 support detected"); #endif GET_WINDOWS_FUNCTION(wship6_module, getaddrinfo); GET_WINDOWS_FUNCTION(wship6_module, freeaddrinfo); GET_WINDOWS_FUNCTION(wship6_module, getnameinfo); GET_WINDOWS_FUNCTION(wship6_module, gai_strerror); } else { #ifdef NET_SETUP_DIAGNOSTICS logevent(NULL, "No IPv6 support detected"); #endif } } GET_WINDOWS_FUNCTION(winsock2_module, WSAAddressToStringA); #else #ifdef NET_SETUP_DIAGNOSTICS logevent(NULL, "PuTTY was built without IPv6 support"); #endif #endif GET_WINDOWS_FUNCTION(winsock_module, WSAAsyncSelect); GET_WINDOWS_FUNCTION(winsock_module, WSAEventSelect); GET_WINDOWS_FUNCTION(winsock_module, select); GET_WINDOWS_FUNCTION(winsock_module, WSAGetLastError); GET_WINDOWS_FUNCTION(winsock_module, WSAEnumNetworkEvents); GET_WINDOWS_FUNCTION(winsock_module, WSAStartup); GET_WINDOWS_FUNCTION(winsock_module, WSACleanup); GET_WINDOWS_FUNCTION(winsock_module, closesocket); GET_WINDOWS_FUNCTION(winsock_module, ntohl); GET_WINDOWS_FUNCTION(winsock_module, htonl); GET_WINDOWS_FUNCTION(winsock_module, htons); GET_WINDOWS_FUNCTION(winsock_module, ntohs); GET_WINDOWS_FUNCTION(winsock_module, gethostname); GET_WINDOWS_FUNCTION(winsock_module, gethostbyname); GET_WINDOWS_FUNCTION(winsock_module, getservbyname); GET_WINDOWS_FUNCTION(winsock_module, inet_addr); GET_WINDOWS_FUNCTION(winsock_module, inet_ntoa); GET_WINDOWS_FUNCTION(winsock_module, connect); GET_WINDOWS_FUNCTION(winsock_module, bind); #ifdef MPEXT GET_WINDOWS_FUNCTION(winsock_module, getsockopt); #endif GET_WINDOWS_FUNCTION(winsock_module, setsockopt); GET_WINDOWS_FUNCTION(winsock_module, socket); GET_WINDOWS_FUNCTION(winsock_module, listen); GET_WINDOWS_FUNCTION(winsock_module, send); GET_WINDOWS_FUNCTION(winsock_module, ioctlsocket); GET_WINDOWS_FUNCTION(winsock_module, accept); GET_WINDOWS_FUNCTION(winsock_module, recv); GET_WINDOWS_FUNCTION(winsock_module, WSAIoctl); /* Try to get the best WinSock version we can get */ if (!sk_startup(2,2) && !sk_startup(2,0) && !sk_startup(1,1)) { fatalbox("Unable to initialise WinSock"); } sktree = newtree234(cmpfortree); }
void sk_init(void) { #ifndef NO_IPV6 winsock2_module = #endif winsock_module = load_system32_dll("ws2_32.dll"); if (!winsock_module) { winsock_module = load_system32_dll("wsock32.dll"); } if (!winsock_module) modalfatalbox("Unable to load any WinSock library"); #ifndef NO_IPV6 /* Check if we have getaddrinfo in Winsock */ if (GetProcAddress(winsock_module, "getaddrinfo") != NULL) { GET_WINDOWS_FUNCTION(winsock_module, getaddrinfo); GET_WINDOWS_FUNCTION(winsock_module, freeaddrinfo); GET_WINDOWS_FUNCTION(winsock_module, getnameinfo); /* This function would fail its type-check if we did one, * because the VS header file provides an inline definition * which is __cdecl instead of WINAPI. */ GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gai_strerror); } else { /* Fall back to wship6.dll for Windows 2000 */ wship6_module = load_system32_dll("wship6.dll"); if (wship6_module) { GET_WINDOWS_FUNCTION(wship6_module, getaddrinfo); GET_WINDOWS_FUNCTION(wship6_module, freeaddrinfo); GET_WINDOWS_FUNCTION(wship6_module, getnameinfo); /* See comment above about type check */ GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gai_strerror); } else { } } GET_WINDOWS_FUNCTION(winsock2_module, WSAAddressToStringA); #endif GET_WINDOWS_FUNCTION(winsock_module, WSAAsyncSelect); GET_WINDOWS_FUNCTION(winsock_module, WSAEventSelect); /* We don't type-check select because at least some MinGW versions * of the Windows API headers seem to disagree with the * documentation on whether the 'struct timeval *' pointer is * const or not. */ GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, select); GET_WINDOWS_FUNCTION(winsock_module, WSAGetLastError); GET_WINDOWS_FUNCTION(winsock_module, WSAEnumNetworkEvents); GET_WINDOWS_FUNCTION(winsock_module, WSAStartup); GET_WINDOWS_FUNCTION(winsock_module, WSACleanup); GET_WINDOWS_FUNCTION(winsock_module, closesocket); #ifndef COVERITY GET_WINDOWS_FUNCTION(winsock_module, ntohl); GET_WINDOWS_FUNCTION(winsock_module, htonl); GET_WINDOWS_FUNCTION(winsock_module, htons); GET_WINDOWS_FUNCTION(winsock_module, ntohs); GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gethostname); #else /* The toolchain I use for Windows Coverity builds doesn't know * the type signatures of these */ GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, ntohl); GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, htonl); GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, htons); GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, ntohs); GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gethostname); #endif GET_WINDOWS_FUNCTION(winsock_module, gethostbyname); GET_WINDOWS_FUNCTION(winsock_module, getservbyname); GET_WINDOWS_FUNCTION(winsock_module, inet_addr); GET_WINDOWS_FUNCTION(winsock_module, inet_ntoa); #if (defined _MSC_VER && _MSC_VER < 1900) || defined __MINGW32__ /* Older Visual Studio, and MinGW as of Ubuntu 16.04, don't know * about this function at all, so can't type-check it */ GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, inet_ntop); #else GET_WINDOWS_FUNCTION(winsock_module, inet_ntop); #endif GET_WINDOWS_FUNCTION(winsock_module, connect); GET_WINDOWS_FUNCTION(winsock_module, bind); GET_WINDOWS_FUNCTION(winsock_module, setsockopt); GET_WINDOWS_FUNCTION(winsock_module, socket); GET_WINDOWS_FUNCTION(winsock_module, listen); GET_WINDOWS_FUNCTION(winsock_module, send); GET_WINDOWS_FUNCTION(winsock_module, shutdown); GET_WINDOWS_FUNCTION(winsock_module, ioctlsocket); GET_WINDOWS_FUNCTION(winsock_module, accept); GET_WINDOWS_FUNCTION(winsock_module, getpeername); GET_WINDOWS_FUNCTION(winsock_module, recv); GET_WINDOWS_FUNCTION(winsock_module, WSAIoctl); /* Try to get the best WinSock version we can get */ if (!sk_startup(2,2) && !sk_startup(2,0) && !sk_startup(1,1)) { modalfatalbox("Unable to initialise WinSock"); } sktree = newtree234(cmpfortree); }
char *get_username(void) { DWORD namelen; char *user; int got_username = FALSE; DECL_WINDOWS_FUNCTION(static, BOOLEAN, GetUserNameExA, (EXTENDED_NAME_FORMAT, LPSTR, PULONG)); { static int tried_usernameex = FALSE; if (!tried_usernameex) { /* Not available on Win9x, so load dynamically */ HMODULE secur32 = load_system32_dll("secur32.dll"); /* If MIT Kerberos is installed, the following call to GET_WINDOWS_FUNCTION makes Windows implicitly load sspicli.dll WITHOUT proper path sanitizing, so better load it properly before */ HMODULE sspicli = load_system32_dll("sspicli.dll"); (void)sspicli; /* squash compiler warning about unused variable */ GET_WINDOWS_FUNCTION(secur32, GetUserNameExA); tried_usernameex = TRUE; } } if (p_GetUserNameExA) { /* * If available, use the principal -- this avoids the problem * that the local username is case-insensitive but Kerberos * usernames are case-sensitive. */ /* Get the length */ namelen = 0; (void) p_GetUserNameExA(NameUserPrincipal, NULL, &namelen); user = snewn(namelen, char); got_username = p_GetUserNameExA(NameUserPrincipal, user, &namelen); if (got_username) { char *p = strchr(user, '@'); if (p) *p = 0; } else { sfree(user); } } if (!got_username) { /* Fall back to local user name */ namelen = 0; if (GetUserName(NULL, &namelen) == FALSE) { /* * Apparently this doesn't work at least on Windows XP SP2. * Thus assume a maximum of 256. It will fail again if it * doesn't fit. */ namelen = 256; } user = snewn(namelen, char); got_username = GetUserName(user, &namelen); if (!got_username) { sfree(user); } }