X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/5471d09ad63fc6216fb9c2a3b52ca9c93821a054..ca20bfcf9f32391ac683100cd3f1bfeb48083236:/settings.c diff --git a/settings.c b/settings.c index 6f7ea9cb..53e89591 100644 --- a/settings.c +++ b/settings.c @@ -8,6 +8,19 @@ #include "putty.h" #include "storage.h" +/* + * Tables of string <-> enum value mappings + */ +struct keyval { char *s; int v; }; + +static const struct keyval ciphernames[] = { + { "WARN", CIPHER_WARN }, + { "3des", CIPHER_3DES }, + { "blowfish", CIPHER_BLOWFISH }, + { "aes", CIPHER_AES }, + { "des", CIPHER_DES } +}; + static void gpps(void *handle, char *name, char *def, char *val, int len) { if (!read_setting_s(handle, name, val, len)) { @@ -21,6 +34,88 @@ static void gppi(void *handle, char *name, int def, int *i) *i = read_setting_i(handle, name, def); } +static int key2val(const struct keyval *mapping, int nmaps, char *key) +{ + int i; + for (i = 0; i < nmaps; i++) + if (!strcmp(mapping[i].s, key)) return mapping[i].v; + return -1; +} + +static const char *val2key(const struct keyval *mapping, int nmaps, int val) +{ + int i; + for (i = 0; i < nmaps; i++) + if (mapping[i].v == val) return mapping[i].s; + return NULL; +} + +/* + * Helper function to parse a comma-separated list of strings into + * a preference list array of values. Any missing values are added + * to the end and duplicates are weeded. + * XXX: assumes vals in 'mapping' are small +ve integers + */ +static void gprefs(void *sesskey, char *name, char *def, + const struct keyval *mapping, int nvals, + int *array) +{ + char commalist[80]; + int n; + unsigned long seen = 0; /* bitmap for weeding dups etc */ + gpps(sesskey, name, def, commalist, sizeof(commalist)); + + /* Grotty parsing of commalist. */ + n = 0; + do { + int v; + char *key; + key = strtok(n==0 ? commalist : NULL, ","); /* sorry */ + if (!key) break; + if (((v = key2val(mapping, nvals, key)) != -1) && + !(seen & 1< 0 && i < nvals; i++) { + const char *s = val2key(mapping, nvals, array[i]); + if (s) { + int sl = strlen(s); + if (i > 0) { + strncat(buf, ",", l); + l--; + } + strncat(buf, s, l); + l -= sl; + } + } + write_setting_s(sesskey, name, buf); +} + void save_settings(char *section, int do_host, Config * cfg) { int i; @@ -76,10 +171,8 @@ void save_settings(char *section, int do_host, Config * cfg) write_setting_i(sesskey, "NoPTY", cfg->nopty); write_setting_i(sesskey, "Compression", cfg->compression); write_setting_i(sesskey, "AgentFwd", cfg->agentfwd); - write_setting_s(sesskey, "Cipher", - cfg->cipher == CIPHER_BLOWFISH ? "blowfish" : - cfg->cipher == CIPHER_DES ? "des" : - cfg->cipher == CIPHER_AES ? "aes" : "3des"); + wprefs(sesskey, "SSHCipherList", ciphernames, CIPHER_MAX, + cfg->ssh_cipherlist); write_setting_i(sesskey, "AuthTIS", cfg->try_tis_auth); write_setting_i(sesskey, "SshProt", cfg->sshprot); write_setting_i(sesskey, "BuggyMAC", cfg->buggymac); @@ -250,16 +343,17 @@ void load_settings(char *section, int do_host, Config * cfg) gppi(sesskey, "Compression", 0, &cfg->compression); gppi(sesskey, "AgentFwd", 0, &cfg->agentfwd); { - char cipher[10]; - gpps(sesskey, "Cipher", "3des", cipher, 10); - if (!strcmp(cipher, "blowfish")) - cfg->cipher = CIPHER_BLOWFISH; - else if (!strcmp(cipher, "des")) - cfg->cipher = CIPHER_DES; - else if (!strcmp(cipher, "aes")) - cfg->cipher = CIPHER_AES; - else - cfg->cipher = CIPHER_3DES; + /* Backwards compatibility: recreate old cipher policy. */ + char defcipherlist[80]; + gpps(sesskey, "Cipher", "3des", defcipherlist, 80); + if (strcmp(defcipherlist, "3des") != 0) { + int l = strlen(defcipherlist); + strncpy(defcipherlist + l, ",3des", 80 - l); + defcipherlist[79] = '\0'; + } + /* Use it as default if no new-style policy. */ + gprefs(sesskey, "SSHCipherList", defcipherlist, + ciphernames, CIPHER_MAX, cfg->ssh_cipherlist); } gppi(sesskey, "SshProt", 1, &cfg->sshprot); gppi(sesskey, "BuggyMAC", 0, &cfg->buggymac);