#include <stdio.h>
#include <stdlib.h>
#include "putty.h"
+#ifndef SECURITY_WIN32
+#define SECURITY_WIN32
+#endif
#include <security.h>
OSVERSIONINFO osVersion;
return filename_from_str(data);
}
+char filename_char_sanitise(char c)
+{
+ if (strchr("<>:\"/\\|?*", c))
+ return '.';
+ return c;
+}
+
#ifndef NO_SECUREZEROMEMORY
/*
* Windows implementation of smemclr (see misc.c) using SecureZeroMemory.
return got_username ? user : NULL;
}
+void dll_hijacking_protection(void)
+{
+ /*
+ * If the OS provides it, call SetDefaultDllDirectories() to
+ * prevent DLLs from being loaded from the directory containing
+ * our own binary, and instead only load from system32.
+ *
+ * This is a protection against hijacking attacks, if someone runs
+ * PuTTY directly from their web browser's download directory
+ * having previously been enticed into clicking on an unwise link
+ * that downloaded a malicious DLL to the same directory under one
+ * of various magic names that seem to be things that standard
+ * Windows DLLs delegate to.
+ *
+ * It shouldn't break deliberate loading of user-provided DLLs
+ * such as GSSAPI providers, because those are specified by their
+ * full pathname by the user-provided configuration.
+ */
+ static HMODULE kernel32_module;
+ DECL_WINDOWS_FUNCTION(static, BOOL, SetDefaultDllDirectories, (DWORD));
+
+ if (!kernel32_module) {
+ kernel32_module = load_system32_dll("kernel32.dll");
+ GET_WINDOWS_FUNCTION(kernel32_module, SetDefaultDllDirectories);
+ }
+
+ if (p_SetDefaultDllDirectories) {
+ /* LOAD_LIBRARY_SEARCH_SYSTEM32 | LOAD_LIBRARY_SEARCH_USER_DIRS only */
+ p_SetDefaultDllDirectories(0x800|0x400);
+ }
+}
+
+void dll_hijacking_protection_add_path(const wchar_t *path)
+{
+ static HMODULE kernel32_module;
+ DECL_WINDOWS_FUNCTION(static, BOOL, AddDllDirectory, (PCWSTR));
+
+ if (!kernel32_module) {
+ kernel32_module = load_system32_dll("kernel32.dll");
+ GET_WINDOWS_FUNCTION(kernel32_module, AddDllDirectory);
+ }
+
+ if (p_AddDllDirectory) {
+ p_AddDllDirectory(path);
+ }
+}
BOOL init_winver(void)
{
ZeroMemory(&osVersion, sizeof(osVersion));
return ret;
}
+/*
+ * A tree234 containing mappings from system error codes to strings.
+ */
+
+struct errstring {
+ int error;
+ char *text;
+};
+
+static int errstring_find(void *av, void *bv)
+{
+ int *a = (int *)av;
+ struct errstring *b = (struct errstring *)bv;
+ if (*a < b->error)
+ return -1;
+ if (*a > b->error)
+ return +1;
+ return 0;
+}
+static int errstring_compare(void *av, void *bv)
+{
+ struct errstring *a = (struct errstring *)av;
+ return errstring_find(&a->error, bv);
+}
+
+static tree234 *errstrings = NULL;
+
+const char *win_strerror(int error)
+{
+ struct errstring *es;
+
+ if (!errstrings)
+ errstrings = newtree234(errstring_compare);
+
+ es = find234(errstrings, &error, errstring_find);
+
+ if (!es) {
+ char msgtext[65536]; /* maximum size for FormatMessage is 64K */
+
+ es = snew(struct errstring);
+ es->error = error;
+ if (!FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS), NULL, error,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ msgtext, lenof(msgtext)-1, NULL)) {
+ sprintf(msgtext,
+ "(unable to format: FormatMessage returned %u)",
+ (unsigned int)GetLastError());
+ } else {
+ int len = strlen(msgtext);
+ if (len > 0 && msgtext[len-1] == '\n')
+ msgtext[len-1] = '\0';
+ }
+ es->text = dupprintf("Error %d: %s", error, msgtext);
+ add234(errstrings, es);
+ }
+
+ return es->text;
+}
+
#ifdef DEBUG
static FILE *debug_fp = NULL;
static HANDLE debug_hdl = INVALID_HANDLE_VALUE;
static int debug_got_console = 0;
-void dputs(char *buf)
+void dputs(const char *buf)
{
DWORD dw;