2 * settings.c: read and write saved sessions. (platform-independent)
\r
11 #include "ssh/gssc.h"
\r
12 #include "ssh/gss.h"
\r
16 /* The cipher order given here is the default order. */
\r
17 static const struct keyvalwhere ciphernames[] = {
\r
18 { "aes", CIPHER_AES, -1, -1 },
\r
19 { "chacha20", CIPHER_CHACHA20, CIPHER_AES, +1 },
\r
20 { "aesgcm", CIPHER_AESGCM, CIPHER_CHACHA20, +1 },
\r
21 { "3des", CIPHER_3DES, -1, -1 },
\r
22 { "WARN", CIPHER_WARN, -1, -1 },
\r
23 { "des", CIPHER_DES, -1, -1 },
\r
24 { "blowfish", CIPHER_BLOWFISH, -1, -1 },
\r
25 { "arcfour", CIPHER_ARCFOUR, -1, -1 },
\r
28 /* The default order here is sometimes overridden by the backward-
\r
29 * compatibility warts in load_open_settings(), and should be kept
\r
30 * in sync with those. */
\r
31 static const struct keyvalwhere kexnames[] = {
\r
32 { "ntru-curve25519", KEX_NTRU_HYBRID, -1, +1 },
\r
33 { "ecdh", KEX_ECDH, -1, +1 },
\r
34 /* This name is misleading: it covers both SHA-256 and SHA-1 variants */
\r
35 { "dh-gex-sha1", KEX_DHGEX, -1, -1 },
\r
36 /* Again, this covers both SHA-256 and SHA-1, despite the name: */
\r
37 { "dh-group14-sha1", KEX_DHGROUP14, -1, -1 },
\r
38 /* This one really is only SHA-1, though: */
\r
39 { "dh-group1-sha1", KEX_DHGROUP1, KEX_WARN, +1 },
\r
40 { "rsa", KEX_RSA, KEX_WARN, -1 },
\r
41 /* Larger fixed DH groups: prefer the larger 15 and 16 over 14,
\r
42 * but by default the even larger 17 and 18 go below 16.
\r
43 * Rationale: diminishing returns of improving the DH strength are
\r
44 * outweighed by increased CPU cost. Group 18 is painful on a slow
\r
45 * machine. Users can override if they need to. */
\r
46 { "dh-group15-sha512", KEX_DHGROUP15, KEX_DHGROUP14, -1 },
\r
47 { "dh-group16-sha512", KEX_DHGROUP16, KEX_DHGROUP15, -1 },
\r
48 { "dh-group17-sha512", KEX_DHGROUP17, KEX_DHGROUP16, +1 },
\r
49 { "dh-group18-sha512", KEX_DHGROUP18, KEX_DHGROUP17, +1 },
\r
50 { "WARN", KEX_WARN, -1, -1 }
\r
53 static const struct keyvalwhere hknames[] = {
\r
54 { "ed25519", HK_ED25519, -1, +1 },
\r
55 { "ed448", HK_ED448, -1, +1 },
\r
56 { "ecdsa", HK_ECDSA, -1, -1 },
\r
57 { "dsa", HK_DSA, -1, -1 },
\r
58 { "rsa", HK_RSA, -1, -1 },
\r
59 { "WARN", HK_WARN, -1, -1 },
\r
63 * All the terminal modes that we know about for the "TerminalModes"
\r
64 * setting. (Also used by config.c for the drop-down list.)
\r
65 * This is currently precisely the same as the set in
\r
66 * ssh/ttymode-list.h, but could in principle differ if other backends
\r
67 * started to support tty modes (e.g., the pty backend).
\r
68 * The set of modes in in this array is currently significant for
\r
69 * settings migration from old versions; if they change, review the
\r
70 * gppmap() invocation for "TerminalModes".
\r
72 const char *const ttymodes[] = {
\r
73 "INTR", "QUIT", "ERASE", "KILL", "EOF",
\r
74 "EOL", "EOL2", "START", "STOP", "SUSP",
\r
75 "DSUSP", "REPRINT", "WERASE", "LNEXT", "FLUSH",
\r
76 "SWTCH", "STATUS", "DISCARD", "IGNPAR", "PARMRK",
\r
77 "INPCK", "ISTRIP", "INLCR", "IGNCR", "ICRNL",
\r
78 "IUCLC", "IXON", "IXANY", "IXOFF", "IMAXBEL",
\r
79 "IUTF8", "ISIG", "ICANON", "XCASE", "ECHO",
\r
80 "ECHOE", "ECHOK", "ECHONL", "NOFLSH", "TOSTOP",
\r
81 "IEXTEN", "ECHOCTL", "ECHOKE", "PENDIN", "OPOST",
\r
82 "OLCUC", "ONLCR", "OCRNL", "ONOCR", "ONLRET",
\r
83 "CS7", "CS8", "PARENB", "PARODD", NULL
\r
86 static int default_protocol, default_port;
\r
87 void settings_set_default_protocol(int newval) { default_protocol = newval; }
\r
88 void settings_set_default_port(int newval) { default_port = newval; }
\r
91 * Convenience functions to access the backends[] array
\r
92 * (which is only present in tools that manage settings).
\r
95 const struct BackendVtable *backend_vt_from_name(const char *name)
\r
97 const struct BackendVtable *const *p;
\r
98 for (p = backends; *p != NULL; p++)
\r
99 if (!strcmp((*p)->id, name))
\r
104 const struct BackendVtable *backend_vt_from_proto(int proto)
\r
106 const struct BackendVtable *const *p;
\r
107 for (p = backends; *p != NULL; p++)
\r
108 if ((*p)->protocol == proto)
\r
113 char *get_remote_username(Conf *conf)
\r
115 char *username = conf_get_str(conf, CONF_username);
\r
117 return dupstr(username);
\r
118 } else if (conf_get_bool(conf, CONF_username_from_env)) {
\r
119 /* Use local username. */
\r
120 return get_username(); /* might still be NULL */
\r
126 static char *gpps_raw(settings_r *sesskey, const char *name, const char *def)
\r
128 char *ret = read_setting_s(sesskey, name);
\r
130 ret = platform_default_s(name);
\r
132 ret = def ? dupstr(def) : NULL; /* permit NULL as final fallback */
\r
136 static void gpps(settings_r *sesskey, const char *name, const char *def,
\r
137 Conf *conf, int primary)
\r
139 char *val = gpps_raw(sesskey, name, def);
\r
140 conf_set_str(conf, primary, val);
\r
145 * gppfont and gppfile cannot have local defaults, since the very
\r
146 * format of a Filename or FontSpec is platform-dependent. So the
\r
147 * platform-dependent functions MUST return some sort of value.
\r
149 static void gppfont(settings_r *sesskey, const char *name,
\r
150 Conf *conf, int primary)
\r
152 FontSpec *result = read_setting_fontspec(sesskey, name);
\r
154 result = platform_default_fontspec(name);
\r
155 conf_set_fontspec(conf, primary, result);
\r
156 fontspec_free(result);
\r
158 static void gppfile(settings_r *sesskey, const char *name,
\r
159 Conf *conf, int primary)
\r
161 Filename *result = read_setting_filename(sesskey, name);
\r
163 result = platform_default_filename(name);
\r
164 conf_set_filename(conf, primary, result);
\r
165 filename_free(result);
\r
168 static bool gppb_raw(settings_r *sesskey, const char *name, bool def)
\r
170 def = platform_default_b(name, def);
\r
171 return sesskey ? read_setting_i(sesskey, name, def) != 0 : def;
\r
174 static void gppb(settings_r *sesskey, const char *name, bool def,
\r
175 Conf *conf, int primary)
\r
177 conf_set_bool(conf, primary, gppb_raw(sesskey, name, def));
\r
180 static int gppi_raw(settings_r *sesskey, const char *name, int def)
\r
182 def = platform_default_i(name, def);
\r
183 return read_setting_i(sesskey, name, def);
\r
186 static void gppi(settings_r *sesskey, const char *name, int def,
\r
187 Conf *conf, int primary)
\r
189 conf_set_int(conf, primary, gppi_raw(sesskey, name, def));
\r
193 * Read a set of name-value pairs in the format we occasionally use:
\r
194 * NAME\tVALUE\0NAME\tVALUE\0\0 in memory
\r
195 * NAME=VALUE,NAME=VALUE, in storage
\r
196 * If there's no "=VALUE" (e.g. just NAME,NAME,NAME) then those keys
\r
197 * are mapped to the empty string.
\r
199 static bool gppmap(settings_r *sesskey, const char *name,
\r
200 Conf *conf, int primary)
\r
202 char *buf, *p, *q, *key, *val;
\r
205 * Start by clearing any existing subkeys of this key from conf.
\r
207 while ((key = conf_get_str_nthstrkey(conf, primary, 0)) != NULL)
\r
208 conf_del_str_str(conf, primary, key);
\r
211 * Now read a serialised list from the settings and unmarshal it
\r
212 * into its components.
\r
214 buf = gpps_raw(sesskey, name, NULL);
\r
222 while (*p && *p != ',') {
\r
238 if (primary == CONF_portfwd && strchr(buf, 'D') != NULL) {
\r
240 * Backwards-compatibility hack: dynamic forwardings are
\r
241 * indexed in the data store as a third type letter in the
\r
242 * key, 'D' alongside 'L' and 'R' - but really, they
\r
243 * should be filed under 'L' with a special _value_,
\r
244 * because local and dynamic forwardings both involve
\r
245 * _listening_ on a local port, and are hence mutually
\r
246 * exclusive on the same port number. So here we translate
\r
247 * the legacy storage format into the sensible internal
\r
248 * form, by finding the D and turning it into a L.
\r
250 char *newkey = dupstr(buf);
\r
251 *strchr(newkey, 'D') = 'L';
\r
252 conf_set_str_str(conf, primary, newkey, "D");
\r
255 conf_set_str_str(conf, primary, buf, val);
\r
264 * Write a set of name/value pairs in the above format, or just the
\r
265 * names if include_values is false.
\r
267 static void wmap(settings_w *sesskey, char const *outkey, Conf *conf,
\r
268 int primary, bool include_values)
\r
270 char *buf, *p, *key, *realkey;
\r
271 const char *val, *q;
\r
274 len = 1; /* allow for NUL */
\r
276 for (val = conf_get_str_strs(conf, primary, NULL, &key);
\r
278 val = conf_get_str_strs(conf, primary, key, &key))
\r
279 len += 2 + 2 * (strlen(key) + strlen(val)); /* allow for escaping */
\r
281 buf = snewn(len, char);
\r
284 for (val = conf_get_str_strs(conf, primary, NULL, &key);
\r
286 val = conf_get_str_strs(conf, primary, key, &key)) {
\r
288 if (primary == CONF_portfwd && !strcmp(val, "D")) {
\r
290 * Backwards-compatibility hack, as above: translate from
\r
291 * the sensible internal representation of dynamic
\r
292 * forwardings (key "L<port>", value "D") to the
\r
293 * conceptually incoherent legacy storage format (key
\r
294 * "D<port>", value empty).
\r
298 realkey = key; /* restore it at end of loop */
\r
301 L = strchr(key, 'L');
\r
309 for (q = key; *q; q++) {
\r
310 if (*q == '=' || *q == ',' || *q == '\\')
\r
314 if (include_values) {
\r
316 for (q = val; *q; q++) {
\r
317 if (*q == '=' || *q == ',' || *q == '\\')
\r
329 write_setting_s(sesskey, outkey, buf);
\r
333 static int key2val(const struct keyvalwhere *mapping,
\r
334 int nmaps, char *key)
\r
337 for (i = 0; i < nmaps; i++)
\r
338 if (!strcmp(mapping[i].s, key)) return mapping[i].v;
\r
342 static const char *val2key(const struct keyvalwhere *mapping,
\r
343 int nmaps, int val)
\r
346 for (i = 0; i < nmaps; i++)
\r
347 if (mapping[i].v == val) return mapping[i].s;
\r
352 * Helper function to parse a comma-separated list of strings into
\r
353 * a preference list array of values. Any missing values are added
\r
354 * to the end and duplicates are weeded.
\r
355 * XXX: assumes vals in 'mapping' are small +ve integers
\r
357 static void gprefs_from_str(const char *str,
\r
358 const struct keyvalwhere *mapping, int nvals,
\r
359 Conf *conf, int primary)
\r
361 char *commalist = dupstr(str);
\r
363 int i, j, n, v, pos;
\r
364 unsigned long seen = 0; /* bitmap for weeding dups etc */
\r
367 * Go through that list and convert it into values.
\r
372 while (*p && *p == ',') p++;
\r
374 break; /* no more words */
\r
377 while (*p && *p != ',') p++;
\r
378 if (*p) *p++ = '\0';
\r
380 v = key2val(mapping, nvals, q);
\r
381 if (v != -1 && !(seen & (1 << v))) {
\r
383 conf_set_int_int(conf, primary, n, v);
\r
391 * Now go through 'mapping' and add values that weren't mentioned
\r
392 * in the list we fetched. We may have to loop over it multiple
\r
393 * times so that we add values before other values whose default
\r
394 * positions depend on them.
\r
396 while (n < nvals) {
\r
397 for (i = 0; i < nvals; i++) {
\r
398 assert(mapping[i].v >= 0);
\r
399 assert(mapping[i].v < 32);
\r
401 if (!(seen & (1 << mapping[i].v))) {
\r
403 * This element needs adding. But can we add it yet?
\r
405 if (mapping[i].vrel != -1 && !(seen & (1 << mapping[i].vrel)))
\r
406 continue; /* nope */
\r
409 * OK, we can work out where to add this element, so
\r
412 if (mapping[i].vrel == -1) {
\r
413 pos = (mapping[i].where < 0 ? n : 0);
\r
415 for (j = 0; j < n; j++)
\r
416 if (conf_get_int_int(conf, primary, j) ==
\r
419 assert(j < n); /* implied by (seen & (1<<vrel)) */
\r
420 pos = (mapping[i].where < 0 ? j : j+1);
\r
426 for (j = n-1; j >= pos; j--)
\r
427 conf_set_int_int(conf, primary, j+1,
\r
428 conf_get_int_int(conf, primary, j));
\r
429 conf_set_int_int(conf, primary, pos, mapping[i].v);
\r
430 seen |= (1 << mapping[i].v);
\r
438 * Read a preference list.
\r
440 static void gprefs(settings_r *sesskey, const char *name, const char *def,
\r
441 const struct keyvalwhere *mapping, int nvals,
\r
442 Conf *conf, int primary)
\r
445 * Fetch the string which we'll parse as a comma-separated list.
\r
447 char *value = gpps_raw(sesskey, name, def);
\r
448 gprefs_from_str(value, mapping, nvals, conf, primary);
\r
453 * Write out a preference list.
\r
455 static void wprefs(settings_w *sesskey, const char *name,
\r
456 const struct keyvalwhere *mapping, int nvals,
\r
457 Conf *conf, int primary)
\r
462 for (maxlen = i = 0; i < nvals; i++) {
\r
463 const char *s = val2key(mapping, nvals,
\r
464 conf_get_int_int(conf, primary, i));
\r
466 maxlen += (maxlen > 0 ? 1 : 0) + strlen(s);
\r
470 buf = snewn(maxlen + 1, char);
\r
473 for (i = 0; i < nvals; i++) {
\r
474 const char *s = val2key(mapping, nvals,
\r
475 conf_get_int_int(conf, primary, i));
\r
477 p += sprintf(p, "%s%s", (p > buf ? "," : ""), s);
\r
481 assert(p - buf == maxlen);
\r
484 write_setting_s(sesskey, name, buf);
\r
489 static void write_setting_b(settings_w *handle, const char *key, bool value)
\r
491 write_setting_i(handle, key, value ? 1 : 0);
\r
494 static void write_clip_setting(settings_w *sesskey, const char *savekey,
\r
495 Conf *conf, int confkey, int strconfkey)
\r
497 int val = conf_get_int(conf, confkey);
\r
501 write_setting_s(sesskey, savekey, "none");
\r
503 case CLIPUI_IMPLICIT:
\r
504 write_setting_s(sesskey, savekey, "implicit");
\r
506 case CLIPUI_EXPLICIT:
\r
507 write_setting_s(sesskey, savekey, "explicit");
\r
509 case CLIPUI_CUSTOM: {
\r
510 char *sval = dupcat("custom:", conf_get_str(conf, strconfkey));
\r
511 write_setting_s(sesskey, savekey, sval);
\r
518 static void read_clip_setting(settings_r *sesskey, char *savekey,
\r
519 int def, Conf *conf, int confkey, int strconfkey)
\r
521 char *setting = read_setting_s(sesskey, savekey);
\r
524 conf_set_str(conf, strconfkey, "");
\r
527 } else if (!strcmp(setting, "implicit")) {
\r
528 val = CLIPUI_IMPLICIT;
\r
529 } else if (!strcmp(setting, "explicit")) {
\r
530 val = CLIPUI_EXPLICIT;
\r
531 } else if (!strncmp(setting, "custom:", 7)) {
\r
532 val = CLIPUI_CUSTOM;
\r
533 conf_set_str(conf, strconfkey, setting + 7);
\r
537 conf_set_int(conf, confkey, val);
\r
541 char *save_settings(const char *section, Conf *conf)
\r
543 struct settings_w *sesskey;
\r
546 sesskey = open_settings_w(section, &errmsg);
\r
549 save_open_settings(sesskey, conf);
\r
550 close_settings_w(sesskey);
\r
554 void save_open_settings(settings_w *sesskey, Conf *conf)
\r
559 write_setting_i(sesskey, "Present", 1);
\r
560 write_setting_s(sesskey, "HostName", conf_get_str(conf, CONF_host));
\r
561 write_setting_filename(sesskey, "LogFileName", conf_get_filename(conf, CONF_logfilename));
\r
562 write_setting_i(sesskey, "LogType", conf_get_int(conf, CONF_logtype));
\r
563 write_setting_i(sesskey, "LogFileClash", conf_get_int(conf, CONF_logxfovr));
\r
564 write_setting_b(sesskey, "LogFlush", conf_get_bool(conf, CONF_logflush));
\r
565 write_setting_b(sesskey, "LogHeader", conf_get_bool(conf, CONF_logheader));
\r
566 write_setting_b(sesskey, "SSHLogOmitPasswords", conf_get_bool(conf, CONF_logomitpass));
\r
567 write_setting_b(sesskey, "SSHLogOmitData", conf_get_bool(conf, CONF_logomitdata));
\r
570 const struct BackendVtable *vt =
\r
571 backend_vt_from_proto(conf_get_int(conf, CONF_protocol));
\r
575 write_setting_s(sesskey, "Protocol", p);
\r
576 write_setting_i(sesskey, "PortNumber", conf_get_int(conf, CONF_port));
\r
577 /* The CloseOnExit numbers are arranged in a different order from
\r
578 * the standard FORCE_ON / FORCE_OFF / AUTO. */
\r
579 write_setting_i(sesskey, "CloseOnExit", (conf_get_int(conf, CONF_close_on_exit)+2)%3);
\r
580 write_setting_b(sesskey, "WarnOnClose", !!conf_get_bool(conf, CONF_warn_on_close));
\r
581 write_setting_i(sesskey, "PingInterval", conf_get_int(conf, CONF_ping_interval) / 60); /* minutes */
\r
582 write_setting_i(sesskey, "PingIntervalSecs", conf_get_int(conf, CONF_ping_interval) % 60); /* seconds */
\r
583 write_setting_b(sesskey, "TCPNoDelay", conf_get_bool(conf, CONF_tcp_nodelay));
\r
584 write_setting_b(sesskey, "TCPKeepalives", conf_get_bool(conf, CONF_tcp_keepalives));
\r
585 write_setting_s(sesskey, "TerminalType", conf_get_str(conf, CONF_termtype));
\r
586 write_setting_s(sesskey, "TerminalSpeed", conf_get_str(conf, CONF_termspeed));
\r
587 wmap(sesskey, "TerminalModes", conf, CONF_ttymodes, true);
\r
589 /* Address family selection */
\r
590 write_setting_i(sesskey, "AddressFamily", conf_get_int(conf, CONF_addressfamily));
\r
592 /* proxy settings */
\r
593 write_setting_s(sesskey, "ProxyExcludeList", conf_get_str(conf, CONF_proxy_exclude_list));
\r
594 write_setting_i(sesskey, "ProxyDNS", (conf_get_int(conf, CONF_proxy_dns)+2)%3);
\r
595 write_setting_b(sesskey, "ProxyLocalhost", conf_get_bool(conf, CONF_even_proxy_localhost));
\r
596 write_setting_i(sesskey, "ProxyMethod", conf_get_int(conf, CONF_proxy_type));
\r
597 write_setting_s(sesskey, "ProxyHost", conf_get_str(conf, CONF_proxy_host));
\r
598 write_setting_i(sesskey, "ProxyPort", conf_get_int(conf, CONF_proxy_port));
\r
599 write_setting_s(sesskey, "ProxyUsername", conf_get_str(conf, CONF_proxy_username));
\r
600 write_setting_s(sesskey, "ProxyPassword", conf_get_str(conf, CONF_proxy_password));
\r
601 write_setting_s(sesskey, "ProxyTelnetCommand", conf_get_str(conf, CONF_proxy_telnet_command));
\r
602 write_setting_i(sesskey, "ProxyLogToTerm", conf_get_int(conf, CONF_proxy_log_to_term));
\r
603 wmap(sesskey, "Environment", conf, CONF_environmt, true);
\r
604 write_setting_s(sesskey, "UserName", conf_get_str(conf, CONF_username));
\r
605 write_setting_b(sesskey, "UserNameFromEnvironment", conf_get_bool(conf, CONF_username_from_env));
\r
606 write_setting_s(sesskey, "LocalUserName", conf_get_str(conf, CONF_localusername));
\r
607 write_setting_b(sesskey, "NoPTY", conf_get_bool(conf, CONF_nopty));
\r
608 write_setting_b(sesskey, "Compression", conf_get_bool(conf, CONF_compression));
\r
609 write_setting_b(sesskey, "TryAgent", conf_get_bool(conf, CONF_tryagent));
\r
610 write_setting_b(sesskey, "AgentFwd", conf_get_bool(conf, CONF_agentfwd));
\r
612 write_setting_b(sesskey, "GssapiFwd", conf_get_bool(conf, CONF_gssapifwd));
\r
614 write_setting_b(sesskey, "ChangeUsername", conf_get_bool(conf, CONF_change_username));
\r
615 wprefs(sesskey, "Cipher", ciphernames, CIPHER_MAX, conf, CONF_ssh_cipherlist);
\r
616 wprefs(sesskey, "KEX", kexnames, KEX_MAX, conf, CONF_ssh_kexlist);
\r
617 wprefs(sesskey, "HostKey", hknames, HK_MAX, conf, CONF_ssh_hklist);
\r
618 write_setting_b(sesskey, "PreferKnownHostKeys", conf_get_bool(conf, CONF_ssh_prefer_known_hostkeys));
\r
619 write_setting_i(sesskey, "RekeyTime", conf_get_int(conf, CONF_ssh_rekey_time));
\r
621 write_setting_i(sesskey, "GssapiRekey", conf_get_int(conf, CONF_gssapirekey));
\r
623 write_setting_s(sesskey, "RekeyBytes", conf_get_str(conf, CONF_ssh_rekey_data));
\r
624 write_setting_b(sesskey, "SshNoAuth", conf_get_bool(conf, CONF_ssh_no_userauth));
\r
625 write_setting_b(sesskey, "SshNoTrivialAuth", conf_get_bool(conf, CONF_ssh_no_trivial_userauth));
\r
626 write_setting_b(sesskey, "SshBanner", conf_get_bool(conf, CONF_ssh_show_banner));
\r
627 write_setting_b(sesskey, "AuthTIS", conf_get_bool(conf, CONF_try_tis_auth));
\r
628 write_setting_b(sesskey, "AuthKI", conf_get_bool(conf, CONF_try_ki_auth));
\r
630 write_setting_b(sesskey, "AuthGSSAPI", conf_get_bool(conf, CONF_try_gssapi_auth));
\r
631 write_setting_b(sesskey, "AuthGSSAPIKEX", conf_get_bool(conf, CONF_try_gssapi_kex));
\r
632 wprefs(sesskey, "GSSLibs", gsslibkeywords, ngsslibs, conf, CONF_ssh_gsslist);
\r
633 write_setting_filename(sesskey, "GSSCustom", conf_get_filename(conf, CONF_ssh_gss_custom));
\r
635 write_setting_b(sesskey, "SshNoShell", conf_get_bool(conf, CONF_ssh_no_shell));
\r
636 write_setting_i(sesskey, "SshProt", conf_get_int(conf, CONF_sshprot));
\r
637 write_setting_s(sesskey, "LogHost", conf_get_str(conf, CONF_loghost));
\r
638 write_setting_b(sesskey, "SSH2DES", conf_get_bool(conf, CONF_ssh2_des_cbc));
\r
639 write_setting_filename(sesskey, "PublicKeyFile", conf_get_filename(conf, CONF_keyfile));
\r
640 write_setting_filename(sesskey, "DetachedCertificate", conf_get_filename(conf, CONF_detached_cert));
\r
641 write_setting_s(sesskey, "AuthPlugin", conf_get_str(conf, CONF_auth_plugin));
\r
642 write_setting_s(sesskey, "RemoteCommand", conf_get_str(conf, CONF_remote_cmd));
\r
643 write_setting_b(sesskey, "RFCEnviron", conf_get_bool(conf, CONF_rfc_environ));
\r
644 write_setting_b(sesskey, "PassiveTelnet", conf_get_bool(conf, CONF_passive_telnet));
\r
645 write_setting_b(sesskey, "BackspaceIsDelete", conf_get_bool(conf, CONF_bksp_is_delete));
\r
646 write_setting_b(sesskey, "RXVTHomeEnd", conf_get_bool(conf, CONF_rxvt_homeend));
\r
647 write_setting_i(sesskey, "LinuxFunctionKeys", conf_get_int(conf, CONF_funky_type));
\r
648 write_setting_i(sesskey, "ShiftedArrowKeys", conf_get_int(conf, CONF_sharrow_type));
\r
649 write_setting_b(sesskey, "NoApplicationKeys", conf_get_bool(conf, CONF_no_applic_k));
\r
650 write_setting_b(sesskey, "NoApplicationCursors", conf_get_bool(conf, CONF_no_applic_c));
\r
651 write_setting_b(sesskey, "NoMouseReporting", conf_get_bool(conf, CONF_no_mouse_rep));
\r
652 write_setting_b(sesskey, "NoRemoteResize", conf_get_bool(conf, CONF_no_remote_resize));
\r
653 write_setting_b(sesskey, "NoAltScreen", conf_get_bool(conf, CONF_no_alt_screen));
\r
654 write_setting_b(sesskey, "NoRemoteWinTitle", conf_get_bool(conf, CONF_no_remote_wintitle));
\r
655 write_setting_b(sesskey, "NoRemoteClearScroll", conf_get_bool(conf, CONF_no_remote_clearscroll));
\r
656 write_setting_i(sesskey, "RemoteQTitleAction", conf_get_int(conf, CONF_remote_qtitle_action));
\r
657 write_setting_b(sesskey, "NoDBackspace", conf_get_bool(conf, CONF_no_dbackspace));
\r
658 write_setting_b(sesskey, "NoRemoteCharset", conf_get_bool(conf, CONF_no_remote_charset));
\r
659 write_setting_b(sesskey, "ApplicationCursorKeys", conf_get_bool(conf, CONF_app_cursor));
\r
660 write_setting_b(sesskey, "ApplicationKeypad", conf_get_bool(conf, CONF_app_keypad));
\r
661 write_setting_b(sesskey, "NetHackKeypad", conf_get_bool(conf, CONF_nethack_keypad));
\r
662 write_setting_b(sesskey, "AltF4", conf_get_bool(conf, CONF_alt_f4));
\r
663 write_setting_b(sesskey, "AltSpace", conf_get_bool(conf, CONF_alt_space));
\r
664 write_setting_b(sesskey, "AltOnly", conf_get_bool(conf, CONF_alt_only));
\r
665 write_setting_b(sesskey, "ComposeKey", conf_get_bool(conf, CONF_compose_key));
\r
666 write_setting_b(sesskey, "CtrlAltKeys", conf_get_bool(conf, CONF_ctrlaltkeys));
\r
667 #ifdef OSX_META_KEY_CONFIG
\r
668 write_setting_b(sesskey, "OSXOptionMeta", conf_get_bool(conf, CONF_osx_option_meta));
\r
669 write_setting_b(sesskey, "OSXCommandMeta", conf_get_bool(conf, CONF_osx_command_meta));
\r
671 write_setting_b(sesskey, "TelnetKey", conf_get_bool(conf, CONF_telnet_keyboard));
\r
672 write_setting_b(sesskey, "TelnetRet", conf_get_bool(conf, CONF_telnet_newline));
\r
673 write_setting_i(sesskey, "LocalEcho", conf_get_int(conf, CONF_localecho));
\r
674 write_setting_i(sesskey, "LocalEdit", conf_get_int(conf, CONF_localedit));
\r
675 write_setting_s(sesskey, "Answerback", conf_get_str(conf, CONF_answerback));
\r
676 write_setting_b(sesskey, "AlwaysOnTop", conf_get_bool(conf, CONF_alwaysontop));
\r
677 write_setting_b(sesskey, "FullScreenOnAltEnter", conf_get_bool(conf, CONF_fullscreenonaltenter));
\r
678 write_setting_b(sesskey, "HideMousePtr", conf_get_bool(conf, CONF_hide_mouseptr));
\r
679 write_setting_b(sesskey, "SunkenEdge", conf_get_bool(conf, CONF_sunken_edge));
\r
680 write_setting_i(sesskey, "WindowBorder", conf_get_int(conf, CONF_window_border));
\r
681 write_setting_i(sesskey, "CurType", conf_get_int(conf, CONF_cursor_type));
\r
682 write_setting_b(sesskey, "BlinkCur", conf_get_bool(conf, CONF_blink_cur));
\r
683 write_setting_i(sesskey, "Beep", conf_get_int(conf, CONF_beep));
\r
684 write_setting_i(sesskey, "BeepInd", conf_get_int(conf, CONF_beep_ind));
\r
685 write_setting_filename(sesskey, "BellWaveFile", conf_get_filename(conf, CONF_bell_wavefile));
\r
686 write_setting_b(sesskey, "BellOverload", conf_get_bool(conf, CONF_bellovl));
\r
687 write_setting_i(sesskey, "BellOverloadN", conf_get_int(conf, CONF_bellovl_n));
\r
688 write_setting_i(sesskey, "BellOverloadT", conf_get_int(conf, CONF_bellovl_t)
\r
689 #ifdef PUTTY_UNIX_PLATFORM_H
\r
693 write_setting_i(sesskey, "BellOverloadS", conf_get_int(conf, CONF_bellovl_s)
\r
694 #ifdef PUTTY_UNIX_PLATFORM_H
\r
698 write_setting_i(sesskey, "ScrollbackLines", conf_get_int(conf, CONF_savelines));
\r
699 write_setting_b(sesskey, "DECOriginMode", conf_get_bool(conf, CONF_dec_om));
\r
700 write_setting_b(sesskey, "AutoWrapMode", conf_get_bool(conf, CONF_wrap_mode));
\r
701 write_setting_b(sesskey, "LFImpliesCR", conf_get_bool(conf, CONF_lfhascr));
\r
702 write_setting_b(sesskey, "CRImpliesLF", conf_get_bool(conf, CONF_crhaslf));
\r
703 write_setting_b(sesskey, "DisableArabicShaping", conf_get_bool(conf, CONF_no_arabicshaping));
\r
704 write_setting_b(sesskey, "DisableBidi", conf_get_bool(conf, CONF_no_bidi));
\r
705 write_setting_b(sesskey, "WinNameAlways", conf_get_bool(conf, CONF_win_name_always));
\r
706 write_setting_s(sesskey, "WinTitle", conf_get_str(conf, CONF_wintitle));
\r
707 write_setting_i(sesskey, "TermWidth", conf_get_int(conf, CONF_width));
\r
708 write_setting_i(sesskey, "TermHeight", conf_get_int(conf, CONF_height));
\r
709 write_setting_fontspec(sesskey, "Font", conf_get_fontspec(conf, CONF_font));
\r
710 write_setting_i(sesskey, "FontQuality", conf_get_int(conf, CONF_font_quality));
\r
711 write_setting_i(sesskey, "FontVTMode", conf_get_int(conf, CONF_vtmode));
\r
712 write_setting_b(sesskey, "UseSystemColours", conf_get_bool(conf, CONF_system_colour));
\r
713 write_setting_b(sesskey, "TryPalette", conf_get_bool(conf, CONF_try_palette));
\r
714 write_setting_b(sesskey, "ANSIColour", conf_get_bool(conf, CONF_ansi_colour));
\r
715 write_setting_b(sesskey, "Xterm256Colour", conf_get_bool(conf, CONF_xterm_256_colour));
\r
716 write_setting_b(sesskey, "TrueColour", conf_get_bool(conf, CONF_true_colour));
\r
717 write_setting_i(sesskey, "BoldAsColour", conf_get_int(conf, CONF_bold_style)-1);
\r
719 for (i = 0; i < 22; i++) {
\r
720 char buf[20], buf2[30];
\r
721 sprintf(buf, "Colour%d", i);
\r
722 sprintf(buf2, "%d,%d,%d",
\r
723 conf_get_int_int(conf, CONF_colours, i*3+0),
\r
724 conf_get_int_int(conf, CONF_colours, i*3+1),
\r
725 conf_get_int_int(conf, CONF_colours, i*3+2));
\r
726 write_setting_s(sesskey, buf, buf2);
\r
728 write_setting_b(sesskey, "RawCNP", conf_get_bool(conf, CONF_rawcnp));
\r
729 write_setting_b(sesskey, "UTF8linedraw", conf_get_bool(conf, CONF_utf8linedraw));
\r
730 write_setting_b(sesskey, "PasteRTF", conf_get_bool(conf, CONF_rtf_paste));
\r
731 write_setting_i(sesskey, "MouseIsXterm", conf_get_int(conf, CONF_mouse_is_xterm));
\r
732 write_setting_b(sesskey, "RectSelect", conf_get_bool(conf, CONF_rect_select));
\r
733 write_setting_b(sesskey, "PasteControls", conf_get_bool(conf, CONF_paste_controls));
\r
734 write_setting_b(sesskey, "MouseOverride", conf_get_bool(conf, CONF_mouse_override));
\r
735 for (i = 0; i < 256; i += 32) {
\r
736 char buf[20], buf2[256];
\r
738 sprintf(buf, "Wordness%d", i);
\r
740 for (j = i; j < i + 32; j++) {
\r
741 sprintf(buf2 + strlen(buf2), "%s%d",
\r
742 (*buf2 ? "," : ""),
\r
743 conf_get_int_int(conf, CONF_wordness, j));
\r
745 write_setting_s(sesskey, buf, buf2);
\r
747 write_setting_b(sesskey, "MouseAutocopy",
\r
748 conf_get_bool(conf, CONF_mouseautocopy));
\r
749 write_clip_setting(sesskey, "MousePaste", conf,
\r
750 CONF_mousepaste, CONF_mousepaste_custom);
\r
751 write_clip_setting(sesskey, "CtrlShiftIns", conf,
\r
752 CONF_ctrlshiftins, CONF_ctrlshiftins_custom);
\r
753 write_clip_setting(sesskey, "CtrlShiftCV", conf,
\r
754 CONF_ctrlshiftcv, CONF_ctrlshiftcv_custom);
\r
755 write_setting_s(sesskey, "LineCodePage", conf_get_str(conf, CONF_line_codepage));
\r
756 write_setting_b(sesskey, "CJKAmbigWide", conf_get_bool(conf, CONF_cjk_ambig_wide));
\r
757 write_setting_b(sesskey, "UTF8Override", conf_get_bool(conf, CONF_utf8_override));
\r
758 write_setting_s(sesskey, "Printer", conf_get_str(conf, CONF_printer));
\r
759 write_setting_b(sesskey, "CapsLockCyr", conf_get_bool(conf, CONF_xlat_capslockcyr));
\r
760 write_setting_b(sesskey, "ScrollBar", conf_get_bool(conf, CONF_scrollbar));
\r
761 write_setting_b(sesskey, "ScrollBarFullScreen", conf_get_bool(conf, CONF_scrollbar_in_fullscreen));
\r
762 write_setting_b(sesskey, "ScrollOnKey", conf_get_bool(conf, CONF_scroll_on_key));
\r
763 write_setting_b(sesskey, "ScrollOnDisp", conf_get_bool(conf, CONF_scroll_on_disp));
\r
764 write_setting_b(sesskey, "EraseToScrollback", conf_get_bool(conf, CONF_erase_to_scrollback));
\r
765 write_setting_i(sesskey, "LockSize", conf_get_int(conf, CONF_resize_action));
\r
766 write_setting_b(sesskey, "BCE", conf_get_bool(conf, CONF_bce));
\r
767 write_setting_b(sesskey, "BlinkText", conf_get_bool(conf, CONF_blinktext));
\r
768 write_setting_b(sesskey, "X11Forward", conf_get_bool(conf, CONF_x11_forward));
\r
769 write_setting_s(sesskey, "X11Display", conf_get_str(conf, CONF_x11_display));
\r
770 write_setting_i(sesskey, "X11AuthType", conf_get_int(conf, CONF_x11_auth));
\r
771 write_setting_filename(sesskey, "X11AuthFile", conf_get_filename(conf, CONF_xauthfile));
\r
772 write_setting_b(sesskey, "LocalPortAcceptAll", conf_get_bool(conf, CONF_lport_acceptall));
\r
773 write_setting_b(sesskey, "RemotePortAcceptAll", conf_get_bool(conf, CONF_rport_acceptall));
\r
774 wmap(sesskey, "PortForwardings", conf, CONF_portfwd, true);
\r
775 write_setting_i(sesskey, "BugIgnore1", 2-conf_get_int(conf, CONF_sshbug_ignore1));
\r
776 write_setting_i(sesskey, "BugPlainPW1", 2-conf_get_int(conf, CONF_sshbug_plainpw1));
\r
777 write_setting_i(sesskey, "BugRSA1", 2-conf_get_int(conf, CONF_sshbug_rsa1));
\r
778 write_setting_i(sesskey, "BugIgnore2", 2-conf_get_int(conf, CONF_sshbug_ignore2));
\r
779 write_setting_i(sesskey, "BugHMAC2", 2-conf_get_int(conf, CONF_sshbug_hmac2));
\r
780 write_setting_i(sesskey, "BugDeriveKey2", 2-conf_get_int(conf, CONF_sshbug_derivekey2));
\r
781 write_setting_i(sesskey, "BugRSAPad2", 2-conf_get_int(conf, CONF_sshbug_rsapad2));
\r
782 write_setting_i(sesskey, "BugPKSessID2", 2-conf_get_int(conf, CONF_sshbug_pksessid2));
\r
783 write_setting_i(sesskey, "BugRekey2", 2-conf_get_int(conf, CONF_sshbug_rekey2));
\r
784 write_setting_i(sesskey, "BugMaxPkt2", 2-conf_get_int(conf, CONF_sshbug_maxpkt2));
\r
785 write_setting_i(sesskey, "BugOldGex2", 2-conf_get_int(conf, CONF_sshbug_oldgex2));
\r
786 write_setting_i(sesskey, "BugWinadj", 2-conf_get_int(conf, CONF_sshbug_winadj));
\r
787 write_setting_i(sesskey, "BugChanReq", 2-conf_get_int(conf, CONF_sshbug_chanreq));
\r
788 write_setting_i(sesskey, "BugRSASHA2CertUserauth", 2-conf_get_int(conf, CONF_sshbug_rsa_sha2_cert_userauth));
\r
789 write_setting_i(sesskey, "BugDropStart", 2-conf_get_int(conf, CONF_sshbug_dropstart));
\r
790 write_setting_i(sesskey, "BugFilterKexinit", 2-conf_get_int(conf, CONF_sshbug_filter_kexinit));
\r
791 write_setting_b(sesskey, "StampUtmp", conf_get_bool(conf, CONF_stamp_utmp));
\r
792 write_setting_b(sesskey, "LoginShell", conf_get_bool(conf, CONF_login_shell));
\r
793 write_setting_b(sesskey, "ScrollbarOnLeft", conf_get_bool(conf, CONF_scrollbar_on_left));
\r
794 write_setting_fontspec(sesskey, "BoldFont", conf_get_fontspec(conf, CONF_boldfont));
\r
795 write_setting_fontspec(sesskey, "WideFont", conf_get_fontspec(conf, CONF_widefont));
\r
796 write_setting_fontspec(sesskey, "WideBoldFont", conf_get_fontspec(conf, CONF_wideboldfont));
\r
797 write_setting_b(sesskey, "ShadowBold", conf_get_bool(conf, CONF_shadowbold));
\r
798 write_setting_i(sesskey, "ShadowBoldOffset", conf_get_int(conf, CONF_shadowboldoffset));
\r
799 write_setting_s(sesskey, "SerialLine", conf_get_str(conf, CONF_serline));
\r
800 write_setting_i(sesskey, "SerialSpeed", conf_get_int(conf, CONF_serspeed));
\r
801 write_setting_i(sesskey, "SerialDataBits", conf_get_int(conf, CONF_serdatabits));
\r
802 write_setting_i(sesskey, "SerialStopHalfbits", conf_get_int(conf, CONF_serstopbits));
\r
803 write_setting_i(sesskey, "SerialParity", conf_get_int(conf, CONF_serparity));
\r
804 write_setting_i(sesskey, "SerialFlowControl", conf_get_int(conf, CONF_serflow));
\r
805 write_setting_s(sesskey, "WindowClass", conf_get_str(conf, CONF_winclass));
\r
806 write_setting_b(sesskey, "ConnectionSharing", conf_get_bool(conf, CONF_ssh_connection_sharing));
\r
807 write_setting_b(sesskey, "ConnectionSharingUpstream", conf_get_bool(conf, CONF_ssh_connection_sharing_upstream));
\r
808 write_setting_b(sesskey, "ConnectionSharingDownstream", conf_get_bool(conf, CONF_ssh_connection_sharing_downstream));
\r
809 wmap(sesskey, "SSHManualHostKeys", conf, CONF_ssh_manual_hostkeys, false);
\r
814 write_setting_s(sesskey, "SUPDUPLocation", conf_get_str(conf, CONF_supdup_location));
\r
815 write_setting_i(sesskey, "SUPDUPCharset", conf_get_int(conf, CONF_supdup_ascii_set));
\r
816 write_setting_b(sesskey, "SUPDUPMoreProcessing", conf_get_bool(conf, CONF_supdup_more));
\r
817 write_setting_b(sesskey, "SUPDUPScrolling", conf_get_bool(conf, CONF_supdup_scroll));
\r
820 bool load_settings(const char *section, Conf *conf)
\r
822 settings_r *sesskey;
\r
824 sesskey = open_settings_r(section);
\r
825 bool exists = (sesskey != NULL);
\r
826 load_open_settings(sesskey, conf);
\r
827 close_settings_r(sesskey);
\r
829 if (exists && conf_launchable(conf))
\r
830 add_session_to_jumplist(section);
\r
835 void load_open_settings(settings_r *sesskey, Conf *conf)
\r
840 conf_set_bool(conf, CONF_ssh_subsys, false); /* FIXME: load this properly */
\r
841 conf_set_str(conf, CONF_remote_cmd, "");
\r
842 conf_set_str(conf, CONF_remote_cmd2, "");
\r
843 conf_set_str(conf, CONF_ssh_nc_host, "");
\r
845 gpps(sesskey, "HostName", "", conf, CONF_host);
\r
846 gppfile(sesskey, "LogFileName", conf, CONF_logfilename);
\r
847 gppi(sesskey, "LogType", 0, conf, CONF_logtype);
\r
848 gppi(sesskey, "LogFileClash", LGXF_ASK, conf, CONF_logxfovr);
\r
849 gppb(sesskey, "LogFlush", true, conf, CONF_logflush);
\r
850 gppb(sesskey, "LogHeader", true, conf, CONF_logheader);
\r
851 gppb(sesskey, "SSHLogOmitPasswords", true, conf, CONF_logomitpass);
\r
852 gppb(sesskey, "SSHLogOmitData", false, conf, CONF_logomitdata);
\r
854 prot = gpps_raw(sesskey, "Protocol", "default");
\r
855 conf_set_int(conf, CONF_protocol, default_protocol);
\r
856 conf_set_int(conf, CONF_port, default_port);
\r
858 const struct BackendVtable *vt = backend_vt_from_name(prot);
\r
860 conf_set_int(conf, CONF_protocol, vt->protocol);
\r
861 gppi(sesskey, "PortNumber", default_port, conf, CONF_port);
\r
866 /* Address family selection */
\r
867 gppi(sesskey, "AddressFamily", ADDRTYPE_UNSPEC, conf, CONF_addressfamily);
\r
869 /* The CloseOnExit numbers are arranged in a different order from
\r
870 * the standard FORCE_ON / FORCE_OFF / AUTO. */
\r
871 i = gppi_raw(sesskey, "CloseOnExit", 1); conf_set_int(conf, CONF_close_on_exit, (i+1)%3);
\r
872 gppb(sesskey, "WarnOnClose", true, conf, CONF_warn_on_close);
\r
874 /* This is two values for backward compatibility with 0.50/0.51 */
\r
875 int pingmin, pingsec;
\r
876 pingmin = gppi_raw(sesskey, "PingInterval", 0);
\r
877 pingsec = gppi_raw(sesskey, "PingIntervalSecs", 0);
\r
878 conf_set_int(conf, CONF_ping_interval, pingmin * 60 + pingsec);
\r
880 gppb(sesskey, "TCPNoDelay", true, conf, CONF_tcp_nodelay);
\r
881 gppb(sesskey, "TCPKeepalives", false, conf, CONF_tcp_keepalives);
\r
882 gpps(sesskey, "TerminalType", "xterm", conf, CONF_termtype);
\r
883 gpps(sesskey, "TerminalSpeed", "38400,38400", conf, CONF_termspeed);
\r
884 if (gppmap(sesskey, "TerminalModes", conf, CONF_ttymodes)) {
\r
886 * Backwards compatibility with old saved settings.
\r
888 * From the invention of this setting through 0.67, the set of
\r
889 * terminal modes was fixed, and absence of a mode from this
\r
890 * setting meant the user had explicitly removed it from the
\r
891 * UI and we shouldn't send it.
\r
893 * In 0.68, the IUTF8 mode was added, and in handling old
\r
894 * settings we inadvertently removed the ability to not send
\r
895 * a mode. Any mode not mentioned was treated as if it was
\r
896 * set to 'auto' (A).
\r
898 * After 0.68, we added explicit notation to the setting format
\r
899 * when the user removes a known terminal mode from the list.
\r
901 * So: if any of the modes from the original set is missing, we
\r
902 * assume this was an intentional removal by the user and add
\r
903 * an explicit removal ('N'); but if IUTF8 (or any other mode
\r
904 * added after 0.67) is missing, we assume that its absence is
\r
905 * due to the setting being old rather than intentional, and
\r
906 * add it with its default setting.
\r
908 * (This does mean that if a 0.68 user explicitly removed IUTF8,
\r
909 * we add it back; but removing IUTF8 had no effect in 0.68, so
\r
910 * we're preserving behaviour, which is the best we can do.)
\r
912 for (i = 0; ttymodes[i]; i++) {
\r
913 if (!conf_get_str_str_opt(conf, CONF_ttymodes, ttymodes[i])) {
\r
914 /* Mode not mentioned in setting. */
\r
916 if (!strcmp(ttymodes[i], "IUTF8")) {
\r
917 /* Any new modes we add in future should be treated
\r
919 def = "A"; /* same as new-setting default below */
\r
921 /* One of the original modes. Absence is probably
\r
923 def = "N"; /* don't send */
\r
925 conf_set_str_str(conf, CONF_ttymodes, ttymodes[i], def);
\r
929 /* This hardcodes a big set of defaults in any new saved
\r
930 * sessions. Let's hope we don't change our mind. */
\r
931 for (i = 0; ttymodes[i]; i++)
\r
932 conf_set_str_str(conf, CONF_ttymodes, ttymodes[i], "A");
\r
935 /* proxy settings */
\r
936 gpps(sesskey, "ProxyExcludeList", "", conf, CONF_proxy_exclude_list);
\r
937 i = gppi_raw(sesskey, "ProxyDNS", 1); conf_set_int(conf, CONF_proxy_dns, (i+1)%3);
\r
938 gppb(sesskey, "ProxyLocalhost", false, conf, CONF_even_proxy_localhost);
\r
939 gppi(sesskey, "ProxyMethod", -1, conf, CONF_proxy_type);
\r
940 if (conf_get_int(conf, CONF_proxy_type) == -1) {
\r
942 i = gppi_raw(sesskey, "ProxyType", 0);
\r
944 conf_set_int(conf, CONF_proxy_type, PROXY_NONE);
\r
946 conf_set_int(conf, CONF_proxy_type, PROXY_HTTP);
\r
948 conf_set_int(conf, CONF_proxy_type, PROXY_TELNET);
\r
950 conf_set_int(conf, CONF_proxy_type, PROXY_CMD);
\r
952 i = gppi_raw(sesskey, "ProxySOCKSVersion", 5);
\r
954 conf_set_int(conf, CONF_proxy_type, PROXY_SOCKS5);
\r
956 conf_set_int(conf, CONF_proxy_type, PROXY_SOCKS4);
\r
959 gpps(sesskey, "ProxyHost", "proxy", conf, CONF_proxy_host);
\r
960 gppi(sesskey, "ProxyPort", 80, conf, CONF_proxy_port);
\r
961 gpps(sesskey, "ProxyUsername", "", conf, CONF_proxy_username);
\r
962 gpps(sesskey, "ProxyPassword", "", conf, CONF_proxy_password);
\r
963 gpps(sesskey, "ProxyTelnetCommand", "connect %host %port\\n",
\r
964 conf, CONF_proxy_telnet_command);
\r
965 gppi(sesskey, "ProxyLogToTerm", FORCE_OFF, conf, CONF_proxy_log_to_term);
\r
966 gppmap(sesskey, "Environment", conf, CONF_environmt);
\r
967 gpps(sesskey, "UserName", "", conf, CONF_username);
\r
968 gppb(sesskey, "UserNameFromEnvironment", false,
\r
969 conf, CONF_username_from_env);
\r
970 gpps(sesskey, "LocalUserName", "", conf, CONF_localusername);
\r
971 gppb(sesskey, "NoPTY", false, conf, CONF_nopty);
\r
972 gppb(sesskey, "Compression", false, conf, CONF_compression);
\r
973 gppb(sesskey, "TryAgent", true, conf, CONF_tryagent);
\r
974 gppb(sesskey, "AgentFwd", false, conf, CONF_agentfwd);
\r
975 gppb(sesskey, "ChangeUsername", false, conf, CONF_change_username);
\r
977 gppb(sesskey, "GssapiFwd", false, conf, CONF_gssapifwd);
\r
979 gprefs(sesskey, "Cipher", "\0",
\r
980 ciphernames, CIPHER_MAX, conf, CONF_ssh_cipherlist);
\r
982 /* Backward-compatibility: before 0.58 (when the "KEX"
\r
983 * preference was first added), we had an option to
\r
984 * disable gex under the "bugs" panel after one report of
\r
985 * a server which offered it then choked, but we never got
\r
986 * a server version string or any other reports. */
\r
987 const char *default_kexes,
\r
988 *normal_default = "ecdh,dh-gex-sha1,dh-group18-sha512,dh-group17-sha512,dh-group16-sha512,dh-group15-sha512,dh-group14-sha1,rsa,"
\r
989 "WARN,dh-group1-sha1",
\r
990 *bugdhgex2_default = "ecdh,dh-group18-sha512,dh-group17-sha512,dh-group16-sha512,dh-group15-sha512,dh-group14-sha1,rsa,"
\r
991 "WARN,dh-group1-sha1,dh-gex-sha1";
\r
993 i = 2 - gppi_raw(sesskey, "BugDHGEx2", 0);
\r
995 default_kexes = bugdhgex2_default;
\r
997 default_kexes = normal_default;
\r
998 /* Migration: after 0.67 we decided we didn't like
\r
999 * dh-group1-sha1. If it looks like the user never changed
\r
1000 * the defaults, quietly upgrade their settings to demote it.
\r
1001 * (If they did, they're on their own.) */
\r
1002 raw = gpps_raw(sesskey, "KEX", default_kexes);
\r
1003 assert(raw != NULL);
\r
1004 /* Lack of 'ecdh' tells us this was saved by 0.58-0.67
\r
1005 * inclusive. If it was saved by a later version, we need
\r
1006 * to leave it alone. */
\r
1007 if (strcmp(raw, "dh-group14-sha1,dh-group1-sha1,rsa,"
\r
1008 "WARN,dh-gex-sha1") == 0) {
\r
1009 /* Previously migrated from BugDHGEx2. */
\r
1011 raw = dupstr(bugdhgex2_default);
\r
1012 } else if (strcmp(raw, "dh-gex-sha1,dh-group14-sha1,"
\r
1013 "dh-group1-sha1,rsa,WARN") == 0) {
\r
1014 /* Untouched old default setting. */
\r
1016 raw = dupstr(normal_default);
\r
1018 /* (For the record: after 0.70, the default algorithm list
\r
1019 * very briefly contained the string 'gss-sha1-krb5'; this was
\r
1020 * never used in any committed version of code, but was left
\r
1021 * over from a pre-commit version of GSS key exchange.
\r
1022 * Mentioned here as it is remotely possible that it will turn
\r
1023 * up in someone's saved settings in future.) */
\r
1025 gprefs_from_str(raw, kexnames, KEX_MAX, conf, CONF_ssh_kexlist);
\r
1028 gprefs(sesskey, "HostKey", "ed25519,ecdsa,rsa,dsa,WARN",
\r
1029 hknames, HK_MAX, conf, CONF_ssh_hklist);
\r
1030 gppb(sesskey, "PreferKnownHostKeys", true, conf, CONF_ssh_prefer_known_hostkeys);
\r
1031 gppi(sesskey, "RekeyTime", 60, conf, CONF_ssh_rekey_time);
\r
1033 gppi(sesskey, "GssapiRekey", GSS_DEF_REKEY_MINS, conf, CONF_gssapirekey);
\r
1035 gpps(sesskey, "RekeyBytes", "1G", conf, CONF_ssh_rekey_data);
\r
1037 /* SSH-2 only by default */
\r
1038 int sshprot = gppi_raw(sesskey, "SshProt", 3);
\r
1039 /* Old sessions may contain the values corresponding to the fallbacks
\r
1040 * we used to allow; migrate them */
\r
1041 if (sshprot == 1) sshprot = 0; /* => "SSH-1 only" */
\r
1042 else if (sshprot == 2) sshprot = 3; /* => "SSH-2 only" */
\r
1043 conf_set_int(conf, CONF_sshprot, sshprot);
\r
1045 gpps(sesskey, "LogHost", "", conf, CONF_loghost);
\r
1046 gppb(sesskey, "SSH2DES", false, conf, CONF_ssh2_des_cbc);
\r
1047 gppb(sesskey, "SshNoAuth", false, conf, CONF_ssh_no_userauth);
\r
1048 gppb(sesskey, "SshNoTrivialAuth", false, conf, CONF_ssh_no_trivial_userauth);
\r
1049 gppb(sesskey, "SshBanner", true, conf, CONF_ssh_show_banner);
\r
1050 gppb(sesskey, "AuthTIS", false, conf, CONF_try_tis_auth);
\r
1051 gppb(sesskey, "AuthKI", true, conf, CONF_try_ki_auth);
\r
1053 gppb(sesskey, "AuthGSSAPI", true, conf, CONF_try_gssapi_auth);
\r
1054 gppb(sesskey, "AuthGSSAPIKEX", true, conf, CONF_try_gssapi_kex);
\r
1055 gprefs(sesskey, "GSSLibs", "\0",
\r
1056 gsslibkeywords, ngsslibs, conf, CONF_ssh_gsslist);
\r
1057 gppfile(sesskey, "GSSCustom", conf, CONF_ssh_gss_custom);
\r
1059 gppb(sesskey, "SshNoShell", false, conf, CONF_ssh_no_shell);
\r
1060 gppfile(sesskey, "PublicKeyFile", conf, CONF_keyfile);
\r
1061 gppfile(sesskey, "DetachedCertificate", conf, CONF_detached_cert);
\r
1062 gpps(sesskey, "AuthPlugin", "", conf, CONF_auth_plugin);
\r
1063 gpps(sesskey, "RemoteCommand", "", conf, CONF_remote_cmd);
\r
1064 gppb(sesskey, "RFCEnviron", false, conf, CONF_rfc_environ);
\r
1065 gppb(sesskey, "PassiveTelnet", false, conf, CONF_passive_telnet);
\r
1066 gppb(sesskey, "BackspaceIsDelete", true, conf, CONF_bksp_is_delete);
\r
1067 gppb(sesskey, "RXVTHomeEnd", false, conf, CONF_rxvt_homeend);
\r
1068 gppi(sesskey, "LinuxFunctionKeys", 0, conf, CONF_funky_type);
\r
1069 gppi(sesskey, "ShiftedArrowKeys", SHARROW_APPLICATION, conf,
\r
1070 CONF_sharrow_type);
\r
1071 gppb(sesskey, "NoApplicationKeys", false, conf, CONF_no_applic_k);
\r
1072 gppb(sesskey, "NoApplicationCursors", false, conf, CONF_no_applic_c);
\r
1073 gppb(sesskey, "NoMouseReporting", false, conf, CONF_no_mouse_rep);
\r
1074 gppb(sesskey, "NoRemoteResize", false, conf, CONF_no_remote_resize);
\r
1075 gppb(sesskey, "NoAltScreen", false, conf, CONF_no_alt_screen);
\r
1076 gppb(sesskey, "NoRemoteWinTitle", false, conf, CONF_no_remote_wintitle);
\r
1077 gppb(sesskey, "NoRemoteClearScroll", false,
\r
1078 conf, CONF_no_remote_clearscroll);
\r
1080 /* Backward compatibility */
\r
1081 int no_remote_qtitle = gppi_raw(sesskey, "NoRemoteQTitle", 1);
\r
1082 /* We deliberately interpret the old setting of "no response" as
\r
1083 * "empty string". This changes the behaviour, but hopefully for
\r
1084 * the better; the user can always recover the old behaviour. */
\r
1085 gppi(sesskey, "RemoteQTitleAction",
\r
1086 no_remote_qtitle ? TITLE_EMPTY : TITLE_REAL,
\r
1087 conf, CONF_remote_qtitle_action);
\r
1089 gppb(sesskey, "NoDBackspace", false, conf, CONF_no_dbackspace);
\r
1090 gppb(sesskey, "NoRemoteCharset", false, conf, CONF_no_remote_charset);
\r
1091 gppb(sesskey, "ApplicationCursorKeys", false, conf, CONF_app_cursor);
\r
1092 gppb(sesskey, "ApplicationKeypad", false, conf, CONF_app_keypad);
\r
1093 gppb(sesskey, "NetHackKeypad", false, conf, CONF_nethack_keypad);
\r
1094 gppb(sesskey, "AltF4", true, conf, CONF_alt_f4);
\r
1095 gppb(sesskey, "AltSpace", false, conf, CONF_alt_space);
\r
1096 gppb(sesskey, "AltOnly", false, conf, CONF_alt_only);
\r
1097 gppb(sesskey, "ComposeKey", false, conf, CONF_compose_key);
\r
1098 gppb(sesskey, "CtrlAltKeys", true, conf, CONF_ctrlaltkeys);
\r
1099 #ifdef OSX_META_KEY_CONFIG
\r
1100 gppb(sesskey, "OSXOptionMeta", true, conf, CONF_osx_option_meta);
\r
1101 gppb(sesskey, "OSXCommandMeta", false, conf, CONF_osx_command_meta);
\r
1103 gppb(sesskey, "TelnetKey", false, conf, CONF_telnet_keyboard);
\r
1104 gppb(sesskey, "TelnetRet", true, conf, CONF_telnet_newline);
\r
1105 gppi(sesskey, "LocalEcho", AUTO, conf, CONF_localecho);
\r
1106 gppi(sesskey, "LocalEdit", AUTO, conf, CONF_localedit);
\r
1107 gpps(sesskey, "Answerback", "PuTTY", conf, CONF_answerback);
\r
1108 gppb(sesskey, "AlwaysOnTop", false, conf, CONF_alwaysontop);
\r
1109 gppb(sesskey, "FullScreenOnAltEnter", false,
\r
1110 conf, CONF_fullscreenonaltenter);
\r
1111 gppb(sesskey, "HideMousePtr", false, conf, CONF_hide_mouseptr);
\r
1112 gppb(sesskey, "SunkenEdge", false, conf, CONF_sunken_edge);
\r
1113 gppi(sesskey, "WindowBorder", 1, conf, CONF_window_border);
\r
1114 gppi(sesskey, "CurType", 0, conf, CONF_cursor_type);
\r
1115 gppb(sesskey, "BlinkCur", false, conf, CONF_blink_cur);
\r
1116 /* pedantic compiler tells me I can't use conf, CONF_beep as an int * :-) */
\r
1117 gppi(sesskey, "Beep", 1, conf, CONF_beep);
\r
1118 gppi(sesskey, "BeepInd", 0, conf, CONF_beep_ind);
\r
1119 gppfile(sesskey, "BellWaveFile", conf, CONF_bell_wavefile);
\r
1120 gppb(sesskey, "BellOverload", true, conf, CONF_bellovl);
\r
1121 gppi(sesskey, "BellOverloadN", 5, conf, CONF_bellovl_n);
\r
1122 i = gppi_raw(sesskey, "BellOverloadT", 2*TICKSPERSEC
\r
1123 #ifdef PUTTY_UNIX_PLATFORM_H
\r
1127 conf_set_int(conf, CONF_bellovl_t, i
\r
1128 #ifdef PUTTY_UNIX_PLATFORM_H
\r
1132 i = gppi_raw(sesskey, "BellOverloadS", 5*TICKSPERSEC
\r
1133 #ifdef PUTTY_UNIX_PLATFORM_H
\r
1137 conf_set_int(conf, CONF_bellovl_s, i
\r
1138 #ifdef PUTTY_UNIX_PLATFORM_H
\r
1142 gppi(sesskey, "ScrollbackLines", 2000, conf, CONF_savelines);
\r
1143 gppb(sesskey, "DECOriginMode", false, conf, CONF_dec_om);
\r
1144 gppb(sesskey, "AutoWrapMode", true, conf, CONF_wrap_mode);
\r
1145 gppb(sesskey, "LFImpliesCR", false, conf, CONF_lfhascr);
\r
1146 gppb(sesskey, "CRImpliesLF", false, conf, CONF_crhaslf);
\r
1147 gppb(sesskey, "DisableArabicShaping", false, conf, CONF_no_arabicshaping);
\r
1148 gppb(sesskey, "DisableBidi", false, conf, CONF_no_bidi);
\r
1149 gppb(sesskey, "WinNameAlways", true, conf, CONF_win_name_always);
\r
1150 gpps(sesskey, "WinTitle", "", conf, CONF_wintitle);
\r
1151 gppi(sesskey, "TermWidth", 80, conf, CONF_width);
\r
1152 gppi(sesskey, "TermHeight", 24, conf, CONF_height);
\r
1153 gppfont(sesskey, "Font", conf, CONF_font);
\r
1154 gppi(sesskey, "FontQuality", FQ_DEFAULT, conf, CONF_font_quality);
\r
1155 gppi(sesskey, "FontVTMode", VT_UNICODE, conf, CONF_vtmode);
\r
1156 gppb(sesskey, "UseSystemColours", false, conf, CONF_system_colour);
\r
1157 gppb(sesskey, "TryPalette", false, conf, CONF_try_palette);
\r
1158 gppb(sesskey, "ANSIColour", true, conf, CONF_ansi_colour);
\r
1159 gppb(sesskey, "Xterm256Colour", true, conf, CONF_xterm_256_colour);
\r
1160 gppb(sesskey, "TrueColour", true, conf, CONF_true_colour);
\r
1161 i = gppi_raw(sesskey, "BoldAsColour", 1); conf_set_int(conf, CONF_bold_style, i+1);
\r
1163 for (i = 0; i < 22; i++) {
\r
1164 static const char *const defaults[] = {
\r
1165 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
\r
1166 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
\r
1167 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
\r
1168 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
\r
1169 "85,255,255", "187,187,187", "255,255,255"
\r
1171 char buf[20], *buf2;
\r
1173 sprintf(buf, "Colour%d", i);
\r
1174 buf2 = gpps_raw(sesskey, buf, defaults[i]);
\r
1175 if (sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
\r
1176 conf_set_int_int(conf, CONF_colours, i*3+0, c0);
\r
1177 conf_set_int_int(conf, CONF_colours, i*3+1, c1);
\r
1178 conf_set_int_int(conf, CONF_colours, i*3+2, c2);
\r
1182 gppb(sesskey, "RawCNP", false, conf, CONF_rawcnp);
\r
1183 gppb(sesskey, "UTF8linedraw", false, conf, CONF_utf8linedraw);
\r
1184 gppb(sesskey, "PasteRTF", false, conf, CONF_rtf_paste);
\r
1185 gppi(sesskey, "MouseIsXterm", 0, conf, CONF_mouse_is_xterm);
\r
1186 gppb(sesskey, "RectSelect", false, conf, CONF_rect_select);
\r
1187 gppb(sesskey, "PasteControls", false, conf, CONF_paste_controls);
\r
1188 gppb(sesskey, "MouseOverride", true, conf, CONF_mouse_override);
\r
1189 for (i = 0; i < 256; i += 32) {
\r
1190 static const char *const defaults[] = {
\r
1191 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
\r
1192 "0,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1",
\r
1193 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2",
\r
1194 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1",
\r
1195 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
\r
1196 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
\r
1197 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2",
\r
1198 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2"
\r
1200 char buf[20], *buf2, *p;
\r
1202 sprintf(buf, "Wordness%d", i);
\r
1203 buf2 = gpps_raw(sesskey, buf, defaults[i / 32]);
\r
1205 for (j = i; j < i + 32; j++) {
\r
1207 while (*p && *p != ',')
\r
1211 conf_set_int_int(conf, CONF_wordness, j, atoi(q));
\r
1215 gppb(sesskey, "MouseAutocopy", CLIPUI_DEFAULT_AUTOCOPY,
\r
1216 conf, CONF_mouseautocopy);
\r
1217 read_clip_setting(sesskey, "MousePaste", CLIPUI_DEFAULT_MOUSE,
\r
1218 conf, CONF_mousepaste, CONF_mousepaste_custom);
\r
1219 read_clip_setting(sesskey, "CtrlShiftIns", CLIPUI_DEFAULT_INS,
\r
1220 conf, CONF_ctrlshiftins, CONF_ctrlshiftins_custom);
\r
1221 read_clip_setting(sesskey, "CtrlShiftCV", CLIPUI_NONE,
\r
1222 conf, CONF_ctrlshiftcv, CONF_ctrlshiftcv_custom);
\r
1224 * The empty default for LineCodePage will be converted later
\r
1225 * into a plausible default for the locale.
\r
1227 gpps(sesskey, "LineCodePage", "", conf, CONF_line_codepage);
\r
1228 gppb(sesskey, "CJKAmbigWide", false, conf, CONF_cjk_ambig_wide);
\r
1229 gppb(sesskey, "UTF8Override", true, conf, CONF_utf8_override);
\r
1230 gpps(sesskey, "Printer", "", conf, CONF_printer);
\r
1231 gppb(sesskey, "CapsLockCyr", false, conf, CONF_xlat_capslockcyr);
\r
1232 gppb(sesskey, "ScrollBar", true, conf, CONF_scrollbar);
\r
1233 gppb(sesskey, "ScrollBarFullScreen", false,
\r
1234 conf, CONF_scrollbar_in_fullscreen);
\r
1235 gppb(sesskey, "ScrollOnKey", false, conf, CONF_scroll_on_key);
\r
1236 gppb(sesskey, "ScrollOnDisp", true, conf, CONF_scroll_on_disp);
\r
1237 gppb(sesskey, "EraseToScrollback", true, conf, CONF_erase_to_scrollback);
\r
1238 gppi(sesskey, "LockSize", 0, conf, CONF_resize_action);
\r
1239 gppb(sesskey, "BCE", true, conf, CONF_bce);
\r
1240 gppb(sesskey, "BlinkText", false, conf, CONF_blinktext);
\r
1241 gppb(sesskey, "X11Forward", false, conf, CONF_x11_forward);
\r
1242 gpps(sesskey, "X11Display", "", conf, CONF_x11_display);
\r
1243 gppi(sesskey, "X11AuthType", X11_MIT, conf, CONF_x11_auth);
\r
1244 gppfile(sesskey, "X11AuthFile", conf, CONF_xauthfile);
\r
1246 gppb(sesskey, "LocalPortAcceptAll", false, conf, CONF_lport_acceptall);
\r
1247 gppb(sesskey, "RemotePortAcceptAll", false, conf, CONF_rport_acceptall);
\r
1248 gppmap(sesskey, "PortForwardings", conf, CONF_portfwd);
\r
1249 i = gppi_raw(sesskey, "BugIgnore1", 0); conf_set_int(conf, CONF_sshbug_ignore1, 2-i);
\r
1250 i = gppi_raw(sesskey, "BugPlainPW1", 0); conf_set_int(conf, CONF_sshbug_plainpw1, 2-i);
\r
1251 i = gppi_raw(sesskey, "BugRSA1", 0); conf_set_int(conf, CONF_sshbug_rsa1, 2-i);
\r
1252 i = gppi_raw(sesskey, "BugIgnore2", 0); conf_set_int(conf, CONF_sshbug_ignore2, 2-i);
\r
1255 i = gppi_raw(sesskey, "BugHMAC2", 0); conf_set_int(conf, CONF_sshbug_hmac2, 2-i);
\r
1256 if (2-i == AUTO) {
\r
1257 i = gppi_raw(sesskey, "BuggyMAC", 0);
\r
1259 conf_set_int(conf, CONF_sshbug_hmac2, FORCE_ON);
\r
1262 i = gppi_raw(sesskey, "BugDeriveKey2", 0); conf_set_int(conf, CONF_sshbug_derivekey2, 2-i);
\r
1263 i = gppi_raw(sesskey, "BugRSAPad2", 0); conf_set_int(conf, CONF_sshbug_rsapad2, 2-i);
\r
1264 i = gppi_raw(sesskey, "BugPKSessID2", 0); conf_set_int(conf, CONF_sshbug_pksessid2, 2-i);
\r
1265 i = gppi_raw(sesskey, "BugRekey2", 0); conf_set_int(conf, CONF_sshbug_rekey2, 2-i);
\r
1266 i = gppi_raw(sesskey, "BugMaxPkt2", 0); conf_set_int(conf, CONF_sshbug_maxpkt2, 2-i);
\r
1267 i = gppi_raw(sesskey, "BugOldGex2", 0); conf_set_int(conf, CONF_sshbug_oldgex2, 2-i);
\r
1268 i = gppi_raw(sesskey, "BugWinadj", 0); conf_set_int(conf, CONF_sshbug_winadj, 2-i);
\r
1269 i = gppi_raw(sesskey, "BugChanReq", 0); conf_set_int(conf, CONF_sshbug_chanreq, 2-i);
\r
1270 i = gppi_raw(sesskey, "BugRSASHA2CertUserauth", 0); conf_set_int(conf, CONF_sshbug_rsa_sha2_cert_userauth, 2-i);
\r
1271 i = gppi_raw(sesskey, "BugDropStart", 1); conf_set_int(conf, CONF_sshbug_dropstart, 2-i);
\r
1272 i = gppi_raw(sesskey, "BugFilterKexinit", 1); conf_set_int(conf, CONF_sshbug_filter_kexinit, 2-i);
\r
1273 conf_set_bool(conf, CONF_ssh_simple, false);
\r
1274 gppb(sesskey, "StampUtmp", true, conf, CONF_stamp_utmp);
\r
1275 gppb(sesskey, "LoginShell", true, conf, CONF_login_shell);
\r
1276 gppb(sesskey, "ScrollbarOnLeft", false, conf, CONF_scrollbar_on_left);
\r
1277 gppb(sesskey, "ShadowBold", false, conf, CONF_shadowbold);
\r
1278 gppfont(sesskey, "BoldFont", conf, CONF_boldfont);
\r
1279 gppfont(sesskey, "WideFont", conf, CONF_widefont);
\r
1280 gppfont(sesskey, "WideBoldFont", conf, CONF_wideboldfont);
\r
1281 gppi(sesskey, "ShadowBoldOffset", 1, conf, CONF_shadowboldoffset);
\r
1282 gpps(sesskey, "SerialLine", "", conf, CONF_serline);
\r
1283 gppi(sesskey, "SerialSpeed", 9600, conf, CONF_serspeed);
\r
1284 gppi(sesskey, "SerialDataBits", 8, conf, CONF_serdatabits);
\r
1285 gppi(sesskey, "SerialStopHalfbits", 2, conf, CONF_serstopbits);
\r
1286 gppi(sesskey, "SerialParity", SER_PAR_NONE, conf, CONF_serparity);
\r
1287 gppi(sesskey, "SerialFlowControl", SER_FLOW_XONXOFF, conf, CONF_serflow);
\r
1288 gpps(sesskey, "WindowClass", "", conf, CONF_winclass);
\r
1289 gppb(sesskey, "ConnectionSharing", false,
\r
1290 conf, CONF_ssh_connection_sharing);
\r
1291 gppb(sesskey, "ConnectionSharingUpstream", true,
\r
1292 conf, CONF_ssh_connection_sharing_upstream);
\r
1293 gppb(sesskey, "ConnectionSharingDownstream", true,
\r
1294 conf, CONF_ssh_connection_sharing_downstream);
\r
1295 gppmap(sesskey, "SSHManualHostKeys", conf, CONF_ssh_manual_hostkeys);
\r
1300 gpps(sesskey, "SUPDUPLocation", "The Internet", conf, CONF_supdup_location);
\r
1301 gppi(sesskey, "SUPDUPCharset", false, conf, CONF_supdup_ascii_set);
\r
1302 gppb(sesskey, "SUPDUPMoreProcessing", false, conf, CONF_supdup_more);
\r
1303 gppb(sesskey, "SUPDUPScrolling", false, conf, CONF_supdup_scroll);
\r
1306 bool do_defaults(const char *session, Conf *conf)
\r
1308 return load_settings(session, conf);
\r
1311 static int sessioncmp(const void *av, const void *bv)
\r
1313 const char *a = *(const char *const *) av;
\r
1314 const char *b = *(const char *const *) bv;
\r
1317 * Alphabetical order, except that "Default Settings" is a
\r
1318 * special case and comes first.
\r
1320 if (!strcmp(a, "Default Settings"))
\r
1321 return -1; /* a comes first */
\r
1322 if (!strcmp(b, "Default Settings"))
\r
1323 return +1; /* b comes first */
\r
1325 * FIXME: perhaps we should ignore the first & in determining
\r
1328 return strcmp(a, b); /* otherwise, compare normally */
\r
1331 bool sesslist_demo_mode = false;
\r
1333 void get_sesslist(struct sesslist *list, bool allocate)
\r
1337 settings_e *handle;
\r
1340 strbuf *sb = strbuf_new();
\r
1342 if (sesslist_demo_mode) {
\r
1343 put_asciz(sb, "demo-server");
\r
1344 put_asciz(sb, "demo-server-2");
\r
1346 if ((handle = enum_settings_start()) != NULL) {
\r
1347 while (enum_settings_next(handle, sb))
\r
1348 put_byte(sb, '\0');
\r
1349 enum_settings_finish(handle);
\r
1351 put_byte(sb, '\0');
\r
1354 list->buffer = strbuf_to_str(sb);
\r
1357 * Now set up the list of sessions. Note that "Default
\r
1358 * Settings" must always be claimed to exist, even if it
\r
1363 list->nsessions = 1; /* "Default Settings" counts as one */
\r
1365 if (strcmp(p, "Default Settings"))
\r
1366 list->nsessions++;
\r
1372 list->sessions = snewn(list->nsessions + 1, const char *);
\r
1373 list->sessions[0] = "Default Settings";
\r
1377 if (strcmp(p, "Default Settings"))
\r
1378 list->sessions[i++] = p;
\r
1384 qsort(list->sessions, i, sizeof(const char *), sessioncmp);
\r
1386 sfree(list->buffer);
\r
1387 sfree(list->sessions);
\r
1388 list->buffer = NULL;
\r
1389 list->sessions = NULL;
\r