X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/d5859615f641e5bbd853cd42aafd4fa577da17eb..8df7a775f6f8b0f81f84eafe28cd0bb8d4c6d1f4:/winstore.c diff --git a/winstore.c b/winstore.c index bc3ab181..55977648 100644 --- a/winstore.c +++ b/winstore.c @@ -8,6 +8,8 @@ #include "putty.h" #include "storage.h" +static const char *const puttystr = PUTTY_REG_POS "\\Sessions"; + static char seedpath[2*MAX_PATH+10] = "\0"; static char hex[16] = "0123456789ABCDEF"; @@ -30,7 +32,7 @@ static void mungestr(char *in, char *out) { return; } -static void unmungestr(char *in, char *out) { +static void unmungestr(char *in, char *out, int outlen) { while (*in) { if (*in == '%' && in[1] && in[2]) { int i, j; @@ -39,31 +41,171 @@ static void unmungestr(char *in, char *out) { j = in[2] - '0'; j -= (j > 9 ? 7 : 0); *out++ = (i<<4) + j; + if (!--outlen) return; in += 3; - } else + } else { *out++ = *in++; + if (!--outlen) return; + } } *out = '\0'; return; } -void *open_settings_w(char *sessionname); -void write_setting_s(void *handle, char *key, char *value); -void write_setting_i(void *handle, char *key, int value); -void *close_settings_w(void *handle); +void *open_settings_w(char *sessionname) { + HKEY subkey1, sesskey; + int ret; + char *p; + + p = malloc(3*strlen(sessionname)+1); + mungestr(sessionname, p); + + ret = RegCreateKey(HKEY_CURRENT_USER, puttystr, &subkey1); + if (ret != ERROR_SUCCESS) { + free(p); + return NULL; + } + ret = RegCreateKey(subkey1, p, &sesskey); + free(p); + RegCloseKey(subkey1); + if (ret != ERROR_SUCCESS) + return NULL; + return (void *)sesskey; +} + +void write_setting_s(void *handle, char *key, char *value) { + if (handle) + RegSetValueEx((HKEY)handle, key, 0, REG_SZ, value, 1+strlen(value)); +} + +void write_setting_i(void *handle, char *key, int value) { + if (handle) + RegSetValueEx((HKEY)handle, key, 0, REG_DWORD, + (CONST BYTE *)&value, sizeof(value)); +} + +void close_settings_w(void *handle) { + RegCloseKey((HKEY)handle); +} + +void *open_settings_r(char *sessionname) { + HKEY subkey1, sesskey; + char *p; -void *open_settings_r(char *sessionname); -char *read_setting_s(void *handle, char *key, char *buffer, int buflen); -int read_setting_i(void *handle, char *key, int defvalue); -void *close_settings_r(void *handle); + p = malloc(3*strlen(sessionname)+1); + mungestr(sessionname, p); -static void hostkey_regname(char *buffer, char *hostname, char *keytype) { + if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS) { + sesskey = NULL; + } else { + if (RegOpenKey(subkey1, p, &sesskey) != ERROR_SUCCESS) { + sesskey = NULL; + } + RegCloseKey(subkey1); + } + + free(p); + + return (void *)sesskey; +} + +char *read_setting_s(void *handle, char *key, char *buffer, int buflen) { + DWORD type, size; + size = buflen; + + if (!handle || + RegQueryValueEx((HKEY)handle, key, 0, + &type, buffer, &size) != ERROR_SUCCESS || + type != REG_SZ) + return NULL; + else + return buffer; +} + +int read_setting_i(void *handle, char *key, int defvalue) { + DWORD type, val, size; + size = sizeof(val); + + if (!handle || + RegQueryValueEx((HKEY)handle, key, 0, &type, + (BYTE *)&val, &size) != ERROR_SUCCESS || + size != sizeof(val) || type != REG_DWORD) + return defvalue; + else + return val; +} + +void close_settings_r(void *handle) { + RegCloseKey((HKEY)handle); +} + +void del_settings (char *sessionname) { + HKEY subkey1; + char *p; + + if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS) + return; + + p = malloc(3*strlen(sessionname)+1); + mungestr(sessionname, p); + RegDeleteKey(subkey1, p); + free(p); + + RegCloseKey(subkey1); +} + +struct enumsettings { + HKEY key; + int i; +}; + +void *enum_settings_start(void) { + struct enumsettings *ret; + HKEY key; + + if (RegCreateKey(HKEY_CURRENT_USER, puttystr, &key) != ERROR_SUCCESS) + return NULL; + + ret = malloc(sizeof(*ret)); + if (ret) { + ret->key = key; + ret->i = 0; + } + + return ret; +} + +char *enum_settings_next(void *handle, char *buffer, int buflen) { + struct enumsettings *e = (struct enumsettings *)handle; + char *otherbuf; + otherbuf = malloc(3*buflen); + if (otherbuf && RegEnumKey(e->key, e->i++, otherbuf, + 3*buflen) == ERROR_SUCCESS) { + unmungestr(otherbuf, buffer, buflen); + free(otherbuf); + return buffer; + } else + return NULL; + +} + +void enum_settings_finish(void *handle) { + struct enumsettings *e = (struct enumsettings *)handle; + RegCloseKey(e->key); + free(e); +} + +static void hostkey_regname(char *buffer, char *hostname, + int port, char *keytype) { + int len; strcpy(buffer, keytype); strcat(buffer, "@"); + len = strlen(buffer); + len += sprintf(buffer+len, "%d:", port); mungestr(hostname, buffer + strlen(buffer)); } -int verify_host_key(char *hostname, char *keytype, char *key) { +int verify_host_key(char *hostname, int port, char *keytype, char *key) { char *otherstr, *regname; int len; HKEY rkey; @@ -78,11 +220,9 @@ int verify_host_key(char *hostname, char *keytype, char *key) { * says. */ otherstr = smalloc(len); - regname = smalloc(3*(strlen(hostname)+strlen(keytype))+5); - if (!otherstr || !regname) - fatalbox("Out of memory"); + regname = smalloc(3*(strlen(hostname)+strlen(keytype))+15); - hostkey_regname(regname, hostname, keytype); + hostkey_regname(regname, hostname, port, keytype); if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys", &rkey) != ERROR_SUCCESS) @@ -98,7 +238,7 @@ int verify_host_key(char *hostname, char *keytype, char *key) { * another trick, which is to look up the _old_ key format * under just the hostname and translate that. */ - char *justhost = regname + 1 + strlen(keytype); + char *justhost = regname + 1 + strcspn(regname, ":"); char *oldstyle = smalloc(len + 10); /* safety margin */ readlen = len; ret = RegQueryValueEx(rkey, justhost, NULL, &type, @@ -168,15 +308,13 @@ int verify_host_key(char *hostname, char *keytype, char *key) { return 0; /* key matched OK in registry */ } -void store_host_key(char *hostname, char *keytype, char *key) { +void store_host_key(char *hostname, int port, char *keytype, char *key) { char *regname; HKEY rkey; - regname = smalloc(3*(strlen(hostname)+strlen(keytype))+5); - if (!regname) - fatalbox("Out of memory"); + regname = smalloc(3*(strlen(hostname)+strlen(keytype))+15); - hostkey_regname(regname, hostname, keytype); + hostkey_regname(regname, hostname, port, keytype); if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys", &rkey) != ERROR_SUCCESS) @@ -243,7 +381,7 @@ void read_random_seed(noise_consumer_t consumer) { } } -void write_random_seed(void *data, size_t len) { +void write_random_seed(void *data, int len) { HANDLE seedf; if (!seedpath[0])