RSA key authentication in ssh1 works; SSH2 is nearly there
[u/mdw/putty] / windlg.c
CommitLineData
374330e2 1#include <windows.h>
2#include <commctrl.h>
3#include <commdlg.h>
4#include <winsock.h>
5#include <stdio.h>
6#include <stdlib.h>
7
374330e2 8#include "ssh.h"
bea1ef5f 9#include "putty.h"
374330e2 10#include "win_res.h"
11
14963b8f 12#define NPANELS 8
13#define MAIN_NPANELS 8
14#define RECONF_NPANELS 5
374330e2 15
16static const char *const puttystr = PUTTY_REG_POS "\\Sessions";
17
c5e9c988 18static char **events = NULL;
19static int nevents = 0, negsize = 0;
20
374330e2 21static HWND logbox = NULL, abtbox = NULL;
22
23static char hex[16] = "0123456789ABCDEF";
24
25static void mungestr(char *in, char *out) {
26 int candot = 0;
27
28 while (*in) {
29 if (*in == ' ' || *in == '\\' || *in == '*' || *in == '?' ||
30 *in == '%' || *in < ' ' || *in > '~' || (*in == '.' && !candot)) {
31 *out++ = '%';
32 *out++ = hex[((unsigned char)*in) >> 4];
33 *out++ = hex[((unsigned char)*in) & 15];
34 } else
35 *out++ = *in;
36 in++;
37 candot = 1;
38 }
39 *out = '\0';
40 return;
41}
42
43static void unmungestr(char *in, char *out) {
374330e2 44 while (*in) {
45 if (*in == '%' && in[1] && in[2]) {
46 int i, j;
47
48 i = in[1] - '0'; i -= (i > 9 ? 7 : 0);
49 j = in[2] - '0'; j -= (j > 9 ? 7 : 0);
50
51 *out++ = (i<<4) + j;
52 in += 3;
53 } else
54 *out++ = *in++;
55 }
56 *out = '\0';
57 return;
58}
59
60static void wpps(HKEY key, LPCTSTR name, LPCTSTR value) {
61 RegSetValueEx(key, name, 0, REG_SZ, value, 1+strlen(value));
62}
63
64static void wppi(HKEY key, LPCTSTR name, int value) {
65 RegSetValueEx(key, name, 0, REG_DWORD,
66 (CONST BYTE *)&value, sizeof(value));
67}
68
69static void gpps(HKEY key, LPCTSTR name, LPCTSTR def,
70 LPTSTR val, int len) {
71 DWORD type, size;
72 size = len;
73
74 if (key == NULL ||
75 RegQueryValueEx(key, name, 0, &type, val, &size) != ERROR_SUCCESS ||
76 type != REG_SZ) {
77 strncpy(val, def, len);
78 val[len-1] = '\0';
79 }
80}
81
82static void gppi(HKEY key, LPCTSTR name, int def, int *i) {
83 DWORD type, val, size;
84 size = sizeof(val);
85
86 if (key == NULL ||
87 RegQueryValueEx(key, name, 0, &type,
88 (BYTE *)&val, &size) != ERROR_SUCCESS ||
89 size != sizeof(val) || type != REG_DWORD)
90 *i = def;
91 else
92 *i = val;
93}
94
374330e2 95static HINSTANCE hinst;
96
1cd246bb 97static int readytogo;
98
374330e2 99static void save_settings (char *section, int do_host) {
100 int i;
101 HKEY subkey1, sesskey;
102 char *p;
103
104 p = malloc(3*strlen(section)+1);
105 mungestr(section, p);
106
107 if (RegCreateKey(HKEY_CURRENT_USER, puttystr, &subkey1)!=ERROR_SUCCESS ||
108 RegCreateKey(subkey1, p, &sesskey) != ERROR_SUCCESS) {
374330e2 109 sesskey = NULL;
110 }
111
112 free(p);
113 RegCloseKey(subkey1);
114
115 wppi (sesskey, "Present", 1);
116 if (do_host) {
117 wpps (sesskey, "HostName", cfg.host);
118 wppi (sesskey, "PortNumber", cfg.port);
89ee5268 119 p = "raw";
a721b9eb 120 for (i = 0; backends[i].name != NULL; i++)
89ee5268 121 if (backends[i].protocol == cfg.protocol) {
122 p = backends[i].name;
123 break;
124 }
125 wpps (sesskey, "Protocol", p);
374330e2 126 }
127 wppi (sesskey, "CloseOnExit", !!cfg.close_on_exit);
9ef49106 128 wppi (sesskey, "WarnOnClose", !!cfg.warn_on_close);
374330e2 129 wpps (sesskey, "TerminalType", cfg.termtype);
130 wpps (sesskey, "TerminalSpeed", cfg.termspeed);
131 {
37508af4 132 char buf[2*sizeof(cfg.environmt)], *p, *q;
374330e2 133 p = buf;
37508af4 134 q = cfg.environmt;
374330e2 135 while (*q) {
136 while (*q) {
137 int c = *q++;
138 if (c == '=' || c == ',' || c == '\\')
139 *p++ = '\\';
140 if (c == '\t')
141 c = '=';
142 *p++ = c;
143 }
144 *p++ = ',';
145 q++;
146 }
147 *p = '\0';
148 wpps (sesskey, "Environment", buf);
149 }
150 wpps (sesskey, "UserName", cfg.username);
fef97f43 151 wppi (sesskey, "NoPTY", cfg.nopty);
bea1ef5f 152 wpps (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" :
9697bfd2 153 cfg.cipher == CIPHER_DES ? "des" : "3des");
ccbfb941 154 wppi (sesskey, "AuthTIS", cfg.try_tis_auth);
7cca0d81 155 wpps (sesskey, "PublicKeyFile", cfg.keyfile);
374330e2 156 wppi (sesskey, "RFCEnviron", cfg.rfc_environ);
157 wppi (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete);
158 wppi (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend);
c9def1b8 159 wppi (sesskey, "LinuxFunctionKeys", cfg.funky_type);
374330e2 160 wppi (sesskey, "ApplicationCursorKeys", cfg.app_cursor);
161 wppi (sesskey, "ApplicationKeypad", cfg.app_keypad);
c5e9c988 162 wppi (sesskey, "NetHackKeypad", cfg.nethack_keypad);
163 wppi (sesskey, "AltF4", cfg.alt_f4);
164 wppi (sesskey, "AltSpace", cfg.alt_space);
5bc238bb 165 wppi (sesskey, "LdiscTerm", cfg.ldisc_term);
217dceef 166 wppi (sesskey, "BlinkCur", cfg.blink_cur);
2a25a1b4 167 wppi (sesskey, "Beep", cfg.beep);
374330e2 168 wppi (sesskey, "ScrollbackLines", cfg.savelines);
169 wppi (sesskey, "DECOriginMode", cfg.dec_om);
170 wppi (sesskey, "AutoWrapMode", cfg.wrap_mode);
fef97f43 171 wppi (sesskey, "LFImpliesCR", cfg.lfhascr);
374330e2 172 wppi (sesskey, "WinNameAlways", cfg.win_name_always);
173 wppi (sesskey, "TermWidth", cfg.width);
174 wppi (sesskey, "TermHeight", cfg.height);
175 wpps (sesskey, "Font", cfg.font);
176 wppi (sesskey, "FontIsBold", cfg.fontisbold);
14963b8f 177 wppi (sesskey, "FontCharSet", cfg.fontcharset);
374330e2 178 wppi (sesskey, "FontHeight", cfg.fontheight);
179 wppi (sesskey, "FontVTMode", cfg.vtmode);
180 wppi (sesskey, "TryPalette", cfg.try_palette);
181 wppi (sesskey, "BoldAsColour", cfg.bold_colour);
182 for (i=0; i<22; i++) {
183 char buf[20], buf2[30];
184 sprintf(buf, "Colour%d", i);
185 sprintf(buf2, "%d,%d,%d", cfg.colours[i][0],
186 cfg.colours[i][1], cfg.colours[i][2]);
187 wpps (sesskey, buf, buf2);
188 }
189 wppi (sesskey, "MouseIsXterm", cfg.mouse_is_xterm);
190 for (i=0; i<256; i+=32) {
191 char buf[20], buf2[256];
192 int j;
193 sprintf(buf, "Wordness%d", i);
194 *buf2 = '\0';
195 for (j=i; j<i+32; j++) {
196 sprintf(buf2+strlen(buf2), "%s%d",
197 (*buf2 ? "," : ""), cfg.wordness[j]);
198 }
199 wpps (sesskey, buf, buf2);
200 }
14963b8f 201 wppi (sesskey, "KoiWinXlat", cfg.xlat_enablekoiwin);
d3d16feb 202 wppi (sesskey, "88592Xlat", cfg.xlat_88592w1250);
14963b8f 203 wppi (sesskey, "CapsLockCyr", cfg.xlat_capslockcyr);
c9def1b8 204 wppi (sesskey, "ScrollBar", cfg.scrollbar);
205 wppi (sesskey, "ScrollOnKey", cfg.scroll_on_key);
206 wppi (sesskey, "LockSize", cfg.locksize);
207 wppi (sesskey, "BCE", cfg.bce);
208 wppi (sesskey, "BlinkText", cfg.blinktext);
374330e2 209
210 RegCloseKey(sesskey);
211}
212
213static void del_session (char *section) {
214 HKEY subkey1;
215 char *p;
216
217 if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS)
218 return;
219
220 p = malloc(3*strlen(section)+1);
221 mungestr(section, p);
222 RegDeleteKey(subkey1, p);
223 free(p);
224
225 RegCloseKey(subkey1);
226}
227
228static void load_settings (char *section, int do_host) {
229 int i;
230 HKEY subkey1, sesskey;
231 char *p;
e277c42d 232 char prot[10];
374330e2 233
234 p = malloc(3*strlen(section)+1);
235 mungestr(section, p);
9816085c 236
237 if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS) {
374330e2 238 sesskey = NULL;
9816085c 239 } else {
240 if (RegOpenKey(subkey1, p, &sesskey) != ERROR_SUCCESS) {
241 sesskey = NULL;
242 }
243 RegCloseKey(subkey1);
374330e2 244 }
245
246 free(p);
374330e2 247
e277c42d 248 gpps (sesskey, "HostName", "", cfg.host, sizeof(cfg.host));
249 gppi (sesskey, "PortNumber", default_port, &cfg.port);
89ee5268 250
e277c42d 251 gpps (sesskey, "Protocol", "default", prot, 10);
89ee5268 252 cfg.protocol = default_protocol;
a721b9eb 253 for (i = 0; backends[i].name != NULL; i++)
89ee5268 254 if (!strcmp(prot, backends[i].name)) {
255 cfg.protocol = backends[i].protocol;
256 break;
257 }
e277c42d 258
374330e2 259 gppi (sesskey, "CloseOnExit", 1, &cfg.close_on_exit);
9ef49106 260 gppi (sesskey, "WarnOnClose", 1, &cfg.warn_on_close);
374330e2 261 gpps (sesskey, "TerminalType", "xterm", cfg.termtype,
262 sizeof(cfg.termtype));
263 gpps (sesskey, "TerminalSpeed", "38400,38400", cfg.termspeed,
264 sizeof(cfg.termspeed));
265 {
37508af4 266 char buf[2*sizeof(cfg.environmt)], *p, *q;
374330e2 267 gpps (sesskey, "Environment", "", buf, sizeof(buf));
268 p = buf;
29b611b7 269 q = cfg.environmt;
374330e2 270 while (*p) {
271 while (*p && *p != ',') {
272 int c = *p++;
273 if (c == '=')
274 c = '\t';
275 if (c == '\\')
276 c = *p++;
29b611b7 277 *q++ = c;
374330e2 278 }
279 if (*p == ',') p++;
280 *q++ = '\0';
281 }
282 *q = '\0';
283 }
284 gpps (sesskey, "UserName", "", cfg.username, sizeof(cfg.username));
fef97f43 285 gppi (sesskey, "NoPTY", 0, &cfg.nopty);
bea1ef5f 286 {
287 char cipher[10];
288 gpps (sesskey, "Cipher", "3des", cipher, 10);
289 if (!strcmp(cipher, "blowfish"))
290 cfg.cipher = CIPHER_BLOWFISH;
9697bfd2 291 else if (!strcmp(cipher, "des"))
292 cfg.cipher = CIPHER_DES;
bea1ef5f 293 else
294 cfg.cipher = CIPHER_3DES;
295 }
ccbfb941 296 gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
7cca0d81 297 gpps (sesskey, "PublicKeyFile", "", cfg.keyfile, sizeof(cfg.keyfile));
374330e2 298 gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
299 gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
300 gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
c9def1b8 301 gppi (sesskey, "LinuxFunctionKeys", 0, &cfg.funky_type);
374330e2 302 gppi (sesskey, "ApplicationCursorKeys", 0, &cfg.app_cursor);
303 gppi (sesskey, "ApplicationKeypad", 0, &cfg.app_keypad);
c5e9c988 304 gppi (sesskey, "NetHackKeypad", 0, &cfg.nethack_keypad);
305 gppi (sesskey, "AltF4", 1, &cfg.alt_f4);
306 gppi (sesskey, "AltSpace", 0, &cfg.alt_space);
5bc238bb 307 gppi (sesskey, "LdiscTerm", 0, &cfg.ldisc_term);
217dceef 308 gppi (sesskey, "BlinkCur", 0, &cfg.blink_cur);
2a25a1b4 309 gppi (sesskey, "Beep", 1, &cfg.beep);
374330e2 310 gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines);
311 gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om);
312 gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode);
fef97f43 313 gppi (sesskey, "LFImpliesCR", 0, &cfg.lfhascr);
374330e2 314 gppi (sesskey, "WinNameAlways", 0, &cfg.win_name_always);
315 gppi (sesskey, "TermWidth", 80, &cfg.width);
316 gppi (sesskey, "TermHeight", 24, &cfg.height);
317 gpps (sesskey, "Font", "Courier", cfg.font, sizeof(cfg.font));
318 gppi (sesskey, "FontIsBold", 0, &cfg.fontisbold);
14963b8f 319 gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg.fontcharset);
374330e2 320 gppi (sesskey, "FontHeight", 10, &cfg.fontheight);
2a7bfc6e 321 gppi (sesskey, "FontVTMode", VT_OEMANSI, (int *)&cfg.vtmode);
374330e2 322 gppi (sesskey, "TryPalette", 0, &cfg.try_palette);
323 gppi (sesskey, "BoldAsColour", 1, &cfg.bold_colour);
324 for (i=0; i<22; i++) {
325 static char *defaults[] = {
326 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
327 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
328 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
329 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
330 "85,255,255", "187,187,187", "255,255,255"
331 };
332 char buf[20], buf2[30];
1d470ad2 333 int c0, c1, c2;
374330e2 334 sprintf(buf, "Colour%d", i);
335 gpps (sesskey, buf, defaults[i], buf2, sizeof(buf2));
1d470ad2 336 if(sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
337 cfg.colours[i][0] = c0;
338 cfg.colours[i][1] = c1;
339 cfg.colours[i][2] = c2;
340 }
374330e2 341 }
342 gppi (sesskey, "MouseIsXterm", 0, &cfg.mouse_is_xterm);
343 for (i=0; i<256; i+=32) {
344 static char *defaults[] = {
345 "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",
346 "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",
347 "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",
348 "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",
349 "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",
350 "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",
351 "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",
352 "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"
353 };
354 char buf[20], buf2[256], *p;
355 int j;
356 sprintf(buf, "Wordness%d", i);
357 gpps (sesskey, buf, defaults[i/32], buf2, sizeof(buf2));
358 p = buf2;
359 for (j=i; j<i+32; j++) {
360 char *q = p;
361 while (*p && *p != ',') p++;
362 if (*p == ',') *p++ = '\0';
363 cfg.wordness[j] = atoi(q);
364 }
365 }
14963b8f 366 gppi (sesskey, "KoiWinXlat", 0, &cfg.xlat_enablekoiwin);
d3d16feb 367 gppi (sesskey, "88592Xlat", 0, &cfg.xlat_88592w1250);
14963b8f 368 gppi (sesskey, "CapsLockCyr", 0, &cfg.xlat_capslockcyr);
c9def1b8 369 gppi (sesskey, "ScrollBar", 1, &cfg.scrollbar);
370 gppi (sesskey, "ScrollOnKey", 0, &cfg.scroll_on_key);
371 gppi (sesskey, "LockSize", 0, &cfg.locksize);
372 gppi (sesskey, "BCE", 0, &cfg.bce);
373 gppi (sesskey, "BlinkText", 0, &cfg.blinktext);
14963b8f 374
374330e2 375 RegCloseKey(sesskey);
376}
377
c9def1b8 378static void force_normal(HWND hwnd)
379{
380static int recurse = 0;
381
382 WINDOWPLACEMENT wp;
383
384 if(recurse) return;
385 recurse = 1;
386
387 wp.length = sizeof(wp);
388 if (GetWindowPlacement(hwnd, &wp))
389 {
390 wp.showCmd = SW_SHOWNORMAL;
391 SetWindowPlacement(hwnd, &wp);
392 }
393 recurse = 0;
394}
395
374330e2 396static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
397 BOOL ok;
398 int n;
399 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
400 if (ok)
401 *result = n;
402}
403
404static int CALLBACK LogProc (HWND hwnd, UINT msg,
405 WPARAM wParam, LPARAM lParam) {
406 int i;
407
408 switch (msg) {
409 case WM_INITDIALOG:
c5e9c988 410 for (i=0; i<nevents; i++)
374330e2 411 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
c5e9c988 412 0, (LPARAM)events[i]);
374330e2 413 return 1;
414/* case WM_CTLCOLORDLG: */
415/* return (int) GetStockObject (LTGRAY_BRUSH); */
416 case WM_COMMAND:
417 switch (LOWORD(wParam)) {
418 case IDOK:
419 logbox = NULL;
420 DestroyWindow (hwnd);
421 return 0;
422 }
423 return 0;
424 case WM_CLOSE:
425 logbox = NULL;
426 DestroyWindow (hwnd);
427 return 0;
428 }
429 return 0;
430}
431
d57835ab 432static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
433 WPARAM wParam, LPARAM lParam) {
434 switch (msg) {
435 case WM_INITDIALOG:
436 return 1;
437 case WM_COMMAND:
438 switch (LOWORD(wParam)) {
439 case IDOK:
440 abtbox = NULL;
441 DestroyWindow (hwnd);
442 return 0;
443 }
444 return 0;
445 case WM_CLOSE:
446 abtbox = NULL;
447 DestroyWindow (hwnd);
448 return 0;
449 }
450 return 0;
451}
452
374330e2 453static int CALLBACK AboutProc (HWND hwnd, UINT msg,
454 WPARAM wParam, LPARAM lParam) {
455 switch (msg) {
456 case WM_INITDIALOG:
067a15ea 457 SetDlgItemText (hwnd, IDA_VERSION, ver);
374330e2 458 return 1;
459/* case WM_CTLCOLORDLG: */
460/* return (int) GetStockObject (LTGRAY_BRUSH); */
461/* case WM_CTLCOLORSTATIC: */
462/* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
463/* return (int) GetStockObject (LTGRAY_BRUSH); */
464 case WM_COMMAND:
465 switch (LOWORD(wParam)) {
466 case IDOK:
467 abtbox = NULL;
468 DestroyWindow (hwnd);
469 return 0;
470 case IDA_LICENCE:
471 EnableWindow(hwnd, 0);
472 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
d57835ab 473 NULL, LicenceProc);
374330e2 474 EnableWindow(hwnd, 1);
475 return 0;
476 }
477 return 0;
478 case WM_CLOSE:
479 abtbox = NULL;
480 DestroyWindow (hwnd);
481 return 0;
482 }
483 return 0;
484}
485
486static int GeneralPanelProc (HWND hwnd, UINT msg,
487 WPARAM wParam, LPARAM lParam) {
488 switch (msg) {
489 case WM_INITDIALOG:
490 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
491 return 1;
492/* case WM_CTLCOLORDLG: */
493/* return (int) GetStockObject (LTGRAY_BRUSH); */
494/* case WM_CTLCOLORSTATIC: */
495/* case WM_CTLCOLORBTN: */
496/* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
497/* return (int) GetStockObject (LTGRAY_BRUSH); */
498 case WM_CLOSE:
499 DestroyWindow (hwnd);
500 return 1;
501 }
502 return 0;
503}
504
505static int CALLBACK ConnectionProc (HWND hwnd, UINT msg,
506 WPARAM wParam, LPARAM lParam) {
507 int i;
508
509 switch (msg) {
510 case WM_INITDIALOG:
511 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
512 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
513 for (i = 0; i < nsessions; i++)
514 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
515 0, (LPARAM) (sessions[i]));
5e1a8e27 516 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
517 cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
518 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW );
374330e2 519 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
9ef49106 520 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
374330e2 521 break;
1cd246bb 522 case WM_LBUTTONUP:
523 /*
524 * Button release should trigger WM_OK if there was a
525 * previous double click on the session list.
526 */
527 ReleaseCapture();
528 if (readytogo)
529 SendMessage (GetParent(hwnd), WM_COMMAND, IDOK, 0);
530 break;
374330e2 531 case WM_COMMAND:
532 switch (LOWORD(wParam)) {
533 case IDC0_PROTTELNET:
534 case IDC0_PROTSSH:
5e1a8e27 535 case IDC0_PROTRAW:
374330e2 536 if (HIWORD(wParam) == BN_CLICKED ||
537 HIWORD(wParam) == BN_DOUBLECLICKED) {
538 int i = IsDlgButtonChecked (hwnd, IDC0_PROTSSH);
5e1a8e27 539 int j = IsDlgButtonChecked (hwnd, IDC0_PROTTELNET);
540 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
374330e2 541 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
542 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
543 cfg.port = i ? 22 : 23;
544 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
545 }
546 }
547 break;
548 case IDC0_HOST:
549 if (HIWORD(wParam) == EN_CHANGE)
550 GetDlgItemText (hwnd, IDC0_HOST, cfg.host,
551 sizeof(cfg.host)-1);
552 break;
553 case IDC0_PORT:
554 if (HIWORD(wParam) == EN_CHANGE)
555 MyGetDlgItemInt (hwnd, IDC0_PORT, &cfg.port);
556 break;
557 case IDC0_CLOSEEXIT:
558 if (HIWORD(wParam) == BN_CLICKED ||
559 HIWORD(wParam) == BN_DOUBLECLICKED)
560 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC0_CLOSEEXIT);
561 break;
9ef49106 562 case IDC0_CLOSEWARN:
563 if (HIWORD(wParam) == BN_CLICKED ||
564 HIWORD(wParam) == BN_DOUBLECLICKED)
565 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC0_CLOSEWARN);
566 break;
374330e2 567 case IDC0_SESSEDIT:
568 if (HIWORD(wParam) == EN_CHANGE)
569 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
570 (WPARAM) -1, 0);
571 break;
572 case IDC0_SESSSAVE:
573 if (HIWORD(wParam) == BN_CLICKED ||
574 HIWORD(wParam) == BN_DOUBLECLICKED) {
575 /*
576 * Save a session
577 */
578 char str[2048];
579 GetDlgItemText (hwnd, IDC0_SESSEDIT, str, sizeof(str)-1);
580 if (!*str) {
581 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
582 LB_GETCURSEL, 0, 0);
583 if (n == LB_ERR) {
584 MessageBeep(0);
585 break;
586 }
587 strcpy (str, sessions[n]);
588 }
589 save_settings (str, !!strcmp(str, "Default Settings"));
590 get_sesslist (FALSE);
591 get_sesslist (TRUE);
592 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
593 0, 0);
594 for (i = 0; i < nsessions; i++)
595 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
596 0, (LPARAM) (sessions[i]));
597 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
598 (WPARAM) -1, 0);
599 }
600 break;
601 case IDC0_SESSLIST:
602 case IDC0_SESSLOAD:
603 if (LOWORD(wParam) == IDC0_SESSLOAD &&
604 HIWORD(wParam) != BN_CLICKED &&
605 HIWORD(wParam) != BN_DOUBLECLICKED)
606 break;
607 if (LOWORD(wParam) == IDC0_SESSLIST &&
608 HIWORD(wParam) != LBN_DBLCLK)
609 break;
610 {
611 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
612 LB_GETCURSEL, 0, 0);
613 if (n == LB_ERR) {
614 MessageBeep(0);
615 break;
616 }
617 load_settings (sessions[n],
618 !!strcmp(sessions[n], "Default Settings"));
619 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
620 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
5e1a8e27 621 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
374330e2 622 (cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
5e1a8e27 623 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW));
374330e2 624 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
9ef49106 625 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
374330e2 626 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
627 (WPARAM) -1, 0);
628 }
629 if (LOWORD(wParam) == IDC0_SESSLIST) {
630 /*
631 * A double-click on a saved session should
632 * actually start the session, not just load it.
633 * Unless it's Default Settings or some other
634 * host-less set of saved settings.
635 */
1cd246bb 636 if (*cfg.host) {
637 readytogo = TRUE;
638 SetCapture(hwnd);
639 }
374330e2 640 }
641 break;
642 case IDC0_SESSDEL:
643 if (HIWORD(wParam) == BN_CLICKED ||
644 HIWORD(wParam) == BN_DOUBLECLICKED) {
645 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
646 LB_GETCURSEL, 0, 0);
647 if (n == LB_ERR || n == 0) {
648 MessageBeep(0);
649 break;
650 }
651 del_session(sessions[n]);
652 get_sesslist (FALSE);
653 get_sesslist (TRUE);
654 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
655 0, 0);
656 for (i = 0; i < nsessions; i++)
657 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
658 0, (LPARAM) (sessions[i]));
659 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
660 (WPARAM) -1, 0);
661 }
662 }
663 }
664 return GeneralPanelProc (hwnd, msg, wParam, lParam);
665}
666
667static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
668 WPARAM wParam, LPARAM lParam) {
669 switch (msg) {
670 case WM_INITDIALOG:
671 CheckRadioButton (hwnd, IDC1_DEL008, IDC1_DEL127,
672 cfg.bksp_is_delete ? IDC1_DEL127 : IDC1_DEL008);
673 CheckRadioButton (hwnd, IDC1_HOMETILDE, IDC1_HOMERXVT,
674 cfg.rxvt_homeend ? IDC1_HOMERXVT : IDC1_HOMETILDE);
c9def1b8 675 CheckRadioButton (hwnd, IDC1_FUNCTILDE, IDC1_FUNCXTERM,
676 cfg.funky_type ?
677 (cfg.funky_type==2 ? IDC1_FUNCXTERM
678 : IDC1_FUNCLINUX )
679 : IDC1_FUNCTILDE);
374330e2 680 CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC,
681 cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL);
c5e9c988 682 CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPNH,
683 cfg.nethack_keypad ? IDC1_KPNH :
374330e2 684 cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
c5e9c988 685 CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
686 CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
5bc238bb 687 CheckDlgButton (hwnd, IDC1_LDISCTERM, cfg.ldisc_term);
c9def1b8 688 CheckDlgButton (hwnd, IDC1_SCROLLKEY, cfg.scroll_on_key);
374330e2 689 break;
690 case WM_COMMAND:
691 if (HIWORD(wParam) == BN_CLICKED ||
692 HIWORD(wParam) == BN_DOUBLECLICKED)
693 switch (LOWORD(wParam)) {
694 case IDC1_DEL008:
695 case IDC1_DEL127:
696 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC1_DEL127);
697 break;
698 case IDC1_HOMETILDE:
699 case IDC1_HOMERXVT:
700 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC1_HOMERXVT);
701 break;
c9def1b8 702 case IDC1_FUNCXTERM:
703 cfg.funky_type = 2;
704 break;
374330e2 705 case IDC1_FUNCTILDE:
706 case IDC1_FUNCLINUX:
c9def1b8 707 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC1_FUNCLINUX);
374330e2 708 break;
709 case IDC1_KPNORMAL:
710 case IDC1_KPAPPLIC:
711 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC);
c5e9c988 712 cfg.nethack_keypad = FALSE;
713 break;
714 case IDC1_KPNH:
715 cfg.app_keypad = FALSE;
716 cfg.nethack_keypad = TRUE;
374330e2 717 break;
718 case IDC1_CURNORMAL:
719 case IDC1_CURAPPLIC:
720 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC);
721 break;
c5e9c988 722 case IDC1_ALTF4:
723 if (HIWORD(wParam) == BN_CLICKED ||
724 HIWORD(wParam) == BN_DOUBLECLICKED)
725 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC1_ALTF4);
726 break;
727 case IDC1_ALTSPACE:
728 if (HIWORD(wParam) == BN_CLICKED ||
729 HIWORD(wParam) == BN_DOUBLECLICKED)
730 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
731 break;
5bc238bb 732 case IDC1_LDISCTERM:
733 if (HIWORD(wParam) == BN_CLICKED ||
734 HIWORD(wParam) == BN_DOUBLECLICKED)
735 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC1_LDISCTERM);
736 break;
c9def1b8 737 case IDC1_SCROLLKEY:
217dceef 738 if (HIWORD(wParam) == BN_CLICKED ||
739 HIWORD(wParam) == BN_DOUBLECLICKED)
c9def1b8 740 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC1_SCROLLKEY);
217dceef 741 break;
374330e2 742 }
743 }
744 return GeneralPanelProc (hwnd, msg, wParam, lParam);
745}
746
747static void fmtfont (char *buf) {
748 sprintf (buf, "Font: %s, ", cfg.font);
749 if (cfg.fontisbold)
750 strcat(buf, "bold, ");
751 if (cfg.fontheight == 0)
752 strcat (buf, "default height");
753 else
754 sprintf (buf+strlen(buf), "%d-%s",
755 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
756 (cfg.fontheight < 0 ? "pixel" : "point"));
757}
758
759static int CALLBACK TerminalProc (HWND hwnd, UINT msg,
760 WPARAM wParam, LPARAM lParam) {
761 CHOOSEFONT cf;
762 LOGFONT lf;
763 char fontstatic[256];
764
765 switch (msg) {
766 case WM_INITDIALOG:
767 CheckDlgButton (hwnd, IDC2_WRAPMODE, cfg.wrap_mode);
768 CheckDlgButton (hwnd, IDC2_WINNAME, cfg.win_name_always);
769 CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om);
fef97f43 770 CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr);
374330e2 771 SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE);
772 SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE);
773 SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE);
774 fmtfont (fontstatic);
775 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
c9def1b8 776 CheckDlgButton (hwnd, IDC1_BLINKCUR, cfg.blink_cur);
777 CheckDlgButton (hwnd, IDC1_BEEP, cfg.beep);
778 CheckDlgButton (hwnd, IDC2_SCROLLBAR, cfg.scrollbar);
779 CheckDlgButton (hwnd, IDC2_LOCKSIZE, cfg.locksize);
780 CheckDlgButton (hwnd, IDC2_BCE, cfg.bce);
781 CheckDlgButton (hwnd, IDC2_BLINKTEXT, cfg.blinktext);
374330e2 782 break;
783 case WM_COMMAND:
784 switch (LOWORD(wParam)) {
785 case IDC2_WRAPMODE:
786 if (HIWORD(wParam) == BN_CLICKED ||
787 HIWORD(wParam) == BN_DOUBLECLICKED)
788 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC2_WRAPMODE);
789 break;
790 case IDC2_WINNAME:
791 if (HIWORD(wParam) == BN_CLICKED ||
792 HIWORD(wParam) == BN_DOUBLECLICKED)
793 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC2_WINNAME);
794 break;
795 case IDC2_DECOM:
796 if (HIWORD(wParam) == BN_CLICKED ||
797 HIWORD(wParam) == BN_DOUBLECLICKED)
798 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM);
799 break;
fef97f43 800 case IDC2_LFHASCR:
801 if (HIWORD(wParam) == BN_CLICKED ||
802 HIWORD(wParam) == BN_DOUBLECLICKED)
803 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR);
804 break;
374330e2 805 case IDC2_ROWSEDIT:
806 if (HIWORD(wParam) == EN_CHANGE)
807 MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height);
808 break;
809 case IDC2_COLSEDIT:
810 if (HIWORD(wParam) == EN_CHANGE)
811 MyGetDlgItemInt (hwnd, IDC2_COLSEDIT, &cfg.width);
812 break;
813 case IDC2_SAVEEDIT:
814 if (HIWORD(wParam) == EN_CHANGE)
815 MyGetDlgItemInt (hwnd, IDC2_SAVEEDIT, &cfg.savelines);
816 break;
817 case IDC2_CHOOSEFONT:
818 lf.lfHeight = cfg.fontheight;
819 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
820 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
821 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
14963b8f 822 lf.lfCharSet = cfg.fontcharset;
374330e2 823 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
824 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
825 lf.lfQuality = DEFAULT_QUALITY;
826 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
827 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
828 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
829
830 cf.lStructSize = sizeof(cf);
831 cf.hwndOwner = hwnd;
832 cf.lpLogFont = &lf;
833 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
834 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
835
836 if (ChooseFont (&cf)) {
837 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
838 cfg.font[sizeof(cfg.font)-1] = '\0';
839 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
14963b8f 840 cfg.fontcharset = lf.lfCharSet;
374330e2 841 cfg.fontheight = lf.lfHeight;
842 fmtfont (fontstatic);
843 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
844 }
845 break;
c9def1b8 846 case IDC1_BLINKCUR:
847 if (HIWORD(wParam) == BN_CLICKED ||
848 HIWORD(wParam) == BN_DOUBLECLICKED)
849 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC1_BLINKCUR);
850 break;
851 case IDC1_BEEP:
852 if (HIWORD(wParam) == BN_CLICKED ||
853 HIWORD(wParam) == BN_DOUBLECLICKED)
854 cfg.beep = IsDlgButtonChecked (hwnd, IDC1_BEEP);
855 break;
856 case IDC2_SCROLLBAR:
857 if (HIWORD(wParam) == BN_CLICKED ||
858 HIWORD(wParam) == BN_DOUBLECLICKED)
859 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC2_SCROLLBAR);
860 break;
861 case IDC2_LOCKSIZE:
862 if (HIWORD(wParam) == BN_CLICKED ||
863 HIWORD(wParam) == BN_DOUBLECLICKED)
864 cfg.locksize = IsDlgButtonChecked (hwnd, IDC2_LOCKSIZE);
865 break;
866 case IDC2_BLINKTEXT:
867 if (HIWORD(wParam) == BN_CLICKED ||
868 HIWORD(wParam) == BN_DOUBLECLICKED)
869 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC2_BLINKTEXT);
870 break;
871 case IDC2_BCE:
872 if (HIWORD(wParam) == BN_CLICKED ||
873 HIWORD(wParam) == BN_DOUBLECLICKED)
874 cfg.bce = IsDlgButtonChecked (hwnd, IDC2_BCE);
875 break;
374330e2 876 }
877 break;
878 }
879 return GeneralPanelProc (hwnd, msg, wParam, lParam);
880}
881
882static int CALLBACK TelnetProc (HWND hwnd, UINT msg,
883 WPARAM wParam, LPARAM lParam) {
884 int i;
885
886 switch (msg) {
887 case WM_INITDIALOG:
888 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
889 SetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed);
890 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
891 {
37508af4 892 char *p = cfg.environmt;
374330e2 893 while (*p) {
894 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, 0,
895 (LPARAM) p);
896 p += strlen(p)+1;
897 }
898 }
899 CheckRadioButton (hwnd, IDC3_EMBSD, IDC3_EMRFC,
900 cfg.rfc_environ ? IDC3_EMRFC : IDC3_EMBSD);
901 break;
902 case WM_COMMAND:
903 switch (LOWORD(wParam)) {
904 case IDC3_TTEDIT:
905 if (HIWORD(wParam) == EN_CHANGE)
906 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
907 sizeof(cfg.termtype)-1);
908 break;
909 case IDC3_TSEDIT:
910 if (HIWORD(wParam) == EN_CHANGE)
911 GetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed,
912 sizeof(cfg.termspeed)-1);
913 break;
914 case IDC3_LOGEDIT:
915 if (HIWORD(wParam) == EN_CHANGE)
916 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
917 sizeof(cfg.username)-1);
918 break;
919 case IDC3_EMBSD:
920 case IDC3_EMRFC:
921 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC3_EMRFC);
922 break;
923 case IDC3_ENVADD:
924 if (HIWORD(wParam) == BN_CLICKED ||
925 HIWORD(wParam) == BN_DOUBLECLICKED) {
37508af4 926 char str[sizeof(cfg.environmt)];
374330e2 927 char *p;
928 GetDlgItemText (hwnd, IDC3_VAREDIT, str, sizeof(str)-1);
929 if (!*str) {
930 MessageBeep(0);
931 break;
932 }
933 p = str + strlen(str);
934 *p++ = '\t';
935 GetDlgItemText (hwnd, IDC3_VALEDIT, p, sizeof(str)-1-(p-str));
936 if (!*p) {
937 MessageBeep(0);
938 break;
939 }
37508af4 940 p = cfg.environmt;
374330e2 941 while (*p) {
942 while (*p) p++;
943 p++;
944 }
37508af4 945 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
374330e2 946 strcpy (p, str);
947 p[strlen(str)+1] = '\0';
948 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING,
949 0, (LPARAM)str);
950 SetDlgItemText (hwnd, IDC3_VAREDIT, "");
951 SetDlgItemText (hwnd, IDC3_VALEDIT, "");
952 } else {
953 MessageBox(hwnd, "Environment too big", "PuTTY Error",
954 MB_OK | MB_ICONERROR);
955 }
956 }
957 break;
958 case IDC3_ENVREMOVE:
959 if (HIWORD(wParam) != BN_CLICKED &&
960 HIWORD(wParam) != BN_DOUBLECLICKED)
961 break;
962 i = SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_GETCURSEL, 0, 0);
963 if (i == LB_ERR)
964 MessageBeep (0);
965 else {
966 char *p, *q;
967
968 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_DELETESTRING,
969 i, 0);
37508af4 970 p = cfg.environmt;
374330e2 971 while (i > 0) {
972 if (!*p)
973 goto disaster;
974 while (*p) p++;
975 p++;
976 i--;
977 }
978 q = p;
979 if (!*p)
980 goto disaster;
981 while (*p) p++;
982 p++;
983 while (*p) {
984 while (*p)
985 *q++ = *p++;
986 *q++ = *p++;
987 }
988 *q = '\0';
989 disaster:;
990 }
991 break;
992 }
993 break;
994 }
995 return GeneralPanelProc (hwnd, msg, wParam, lParam);
996}
997
998static int CALLBACK SshProc (HWND hwnd, UINT msg,
999 WPARAM wParam, LPARAM lParam) {
7cca0d81 1000 OPENFILENAME of;
1001 char filename[sizeof(cfg.keyfile)];
1002
374330e2 1003 switch (msg) {
1004 case WM_INITDIALOG:
1005 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
1006 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
fef97f43 1007 CheckDlgButton (hwnd, IDC3_NOPTY, cfg.nopty);
9697bfd2 1008 CheckRadioButton (hwnd, IDC3_CIPHER3DES, IDC3_CIPHERDES,
bea1ef5f 1009 cfg.cipher == CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF :
9697bfd2 1010 cfg.cipher == CIPHER_DES ? IDC3_CIPHERDES :
1011
bea1ef5f 1012 IDC3_CIPHER3DES);
ccbfb941 1013 CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
7cca0d81 1014 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
374330e2 1015 break;
1016 case WM_COMMAND:
1017 switch (LOWORD(wParam)) {
1018 case IDC3_TTEDIT:
1019 if (HIWORD(wParam) == EN_CHANGE)
1020 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
1021 sizeof(cfg.termtype)-1);
1022 break;
1023 case IDC3_LOGEDIT:
1024 if (HIWORD(wParam) == EN_CHANGE)
1025 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
1026 sizeof(cfg.username)-1);
1027 break;
fef97f43 1028 case IDC3_NOPTY:
1029 if (HIWORD(wParam) == BN_CLICKED ||
1030 HIWORD(wParam) == BN_DOUBLECLICKED)
1031 cfg.nopty = IsDlgButtonChecked (hwnd, IDC3_NOPTY);
1032 break;
bea1ef5f 1033 case IDC3_CIPHER3DES:
1034 case IDC3_CIPHERBLOWF:
9697bfd2 1035 case IDC3_CIPHERDES:
bea1ef5f 1036 if (HIWORD(wParam) == BN_CLICKED ||
1037 HIWORD(wParam) == BN_DOUBLECLICKED) {
1038 if (IsDlgButtonChecked (hwnd, IDC3_CIPHER3DES))
1039 cfg.cipher = CIPHER_3DES;
1040 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERBLOWF))
1041 cfg.cipher = CIPHER_BLOWFISH;
9697bfd2 1042 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERDES))
1043 cfg.cipher = CIPHER_DES;
bea1ef5f 1044 }
1045 break;
ccbfb941 1046 case IDC3_AUTHTIS:
1047 if (HIWORD(wParam) == BN_CLICKED ||
1048 HIWORD(wParam) == BN_DOUBLECLICKED)
1049 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
1050 break;
7cca0d81 1051 case IDC3_PKEDIT:
1052 if (HIWORD(wParam) == EN_CHANGE)
1053 GetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile,
1054 sizeof(cfg.keyfile)-1);
1055 break;
1056 case IDC3_PKBUTTON:
1057 /*
1058 * FIXME: this crashes. Find out why.
1059 */
1060 memset(&of, 0, sizeof(of));
1061#ifdef OPENFILENAME_SIZE_VERSION_400
1062 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1063#else
1064 of.lStructSize = sizeof(of);
1065#endif
1066 of.hwndOwner = hwnd;
1067 of.lpstrFilter = "All Files\0*\0\0\0";
1068 of.lpstrCustomFilter = NULL;
1069 of.nFilterIndex = 1;
1070 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1071 of.nMaxFile = sizeof(filename);
1072 of.lpstrFileTitle = NULL;
1073 of.lpstrInitialDir = NULL;
1074 of.lpstrTitle = "Select Public Key File";
1075 of.Flags = 0;
1076 if (GetOpenFileName(&of)) {
1077 strcpy(cfg.keyfile, filename);
1078 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
1079 }
1080 break;
374330e2 1081 }
1082 break;
1083 }
1084 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1085}
1086
1087static int CALLBACK SelectionProc (HWND hwnd, UINT msg,
1088 WPARAM wParam, LPARAM lParam) {
1089 int i;
1090
1091 switch (msg) {
1092 case WM_INITDIALOG:
1093 CheckRadioButton (hwnd, IDC4_MBWINDOWS, IDC4_MBXTERM,
1094 cfg.mouse_is_xterm ? IDC4_MBXTERM : IDC4_MBWINDOWS);
1095 {
1096 static int tabs[4] = {25, 61, 96, 128};
1097 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_SETTABSTOPS, 4,
1098 (LPARAM) tabs);
1099 }
1100 for (i=0; i<256; i++) {
1101 char str[100];
1102 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1103 (i>=0x21 && i != 0x7F) ? i : ' ',
1104 cfg.wordness[i]);
1105 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_ADDSTRING, 0,
1106 (LPARAM) str);
1107 }
1108 break;
1109 case WM_COMMAND:
1110 switch (LOWORD(wParam)) {
1111 case IDC4_MBWINDOWS:
1112 case IDC4_MBXTERM:
1113 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC4_MBXTERM);
1114 break;
1115 case IDC4_CCSET:
1116 {
1117 BOOL ok;
1118 int i;
1119 int n = GetDlgItemInt (hwnd, IDC4_CCEDIT, &ok, FALSE);
1120
1121 if (!ok)
1122 MessageBeep (0);
1123 else {
1124 for (i=0; i<256; i++)
1125 if (SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_GETSEL,
1126 i, 0)) {
1127 char str[100];
1128 cfg.wordness[i] = n;
1129 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1130 LB_DELETESTRING, i, 0);
1131 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1132 (i>=0x21 && i != 0x7F) ? i : ' ',
1133 cfg.wordness[i]);
1134 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1135 LB_INSERTSTRING, i,
1136 (LPARAM)str);
1137 }
1138 }
1139 }
1140 break;
1141 }
1142 break;
1143 }
1144 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1145}
1146
1147static int CALLBACK ColourProc (HWND hwnd, UINT msg,
1148 WPARAM wParam, LPARAM lParam) {
1149 static const char *const colours[] = {
1150 "Default Foreground", "Default Bold Foreground",
1151 "Default Background", "Default Bold Background",
1152 "Cursor Text", "Cursor Colour",
1153 "ANSI Black", "ANSI Black Bold",
1154 "ANSI Red", "ANSI Red Bold",
1155 "ANSI Green", "ANSI Green Bold",
1156 "ANSI Yellow", "ANSI Yellow Bold",
1157 "ANSI Blue", "ANSI Blue Bold",
1158 "ANSI Magenta", "ANSI Magenta Bold",
1159 "ANSI Cyan", "ANSI Cyan Bold",
1160 "ANSI White", "ANSI White Bold"
1161 };
1162 static const int permanent[] = {
1163 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
1164 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
1165 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
1166 };
1167 switch (msg) {
1168 case WM_INITDIALOG:
1169 CheckDlgButton (hwnd, IDC5_BOLDCOLOUR, cfg.bold_colour);
1170 CheckDlgButton (hwnd, IDC5_PALETTE, cfg.try_palette);
1171 {
1172 int i;
1173 for (i=0; i<22; i++)
1174 if (cfg.bold_colour || permanent[i])
1175 SendDlgItemMessage (hwnd, IDC5_LIST, LB_ADDSTRING, 0,
1176 (LPARAM) colours[i]);
1177 }
1178 SendDlgItemMessage (hwnd, IDC5_LIST, LB_SETCURSEL, 0, 0);
1179 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[0][0], FALSE);
1180 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[0][1], FALSE);
1181 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[0][2], FALSE);
1182 break;
1183 case WM_COMMAND:
1184 switch (LOWORD(wParam)) {
1185 case IDC5_BOLDCOLOUR:
1186 if (HIWORD(wParam) == BN_CLICKED ||
1187 HIWORD(wParam) == BN_DOUBLECLICKED) {
1188 int n, i;
1189 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC5_BOLDCOLOUR);
1190 n = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCOUNT, 0, 0);
1191 if (cfg.bold_colour && n!=22) {
1192 for (i=0; i<22; i++)
1193 if (!permanent[i])
1194 SendDlgItemMessage (hwnd, IDC5_LIST,
1195 LB_INSERTSTRING, i,
1196 (LPARAM) colours[i]);
1197 } else if (!cfg.bold_colour && n!=12) {
1198 for (i=22; i-- ;)
1199 if (!permanent[i])
1200 SendDlgItemMessage (hwnd, IDC5_LIST,
1201 LB_DELETESTRING, i, 0);
1202 }
1203 }
1204 break;
1205 case IDC5_PALETTE:
1206 if (HIWORD(wParam) == BN_CLICKED ||
1207 HIWORD(wParam) == BN_DOUBLECLICKED)
1208 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC5_PALETTE);
1209 break;
1210 case IDC5_LIST:
1211 if (HIWORD(wParam) == LBN_DBLCLK ||
1212 HIWORD(wParam) == LBN_SELCHANGE) {
1213 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1214 0, 0);
1215 if (!cfg.bold_colour)
1216 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1217 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0], FALSE);
1218 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1], FALSE);
1219 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2], FALSE);
1220 }
1221 break;
1222 case IDC5_CHANGE:
1223 if (HIWORD(wParam) == BN_CLICKED ||
1224 HIWORD(wParam) == BN_DOUBLECLICKED) {
1225 static CHOOSECOLOR cc;
1226 static DWORD custom[16] = {0}; /* zero initialisers */
1227 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1228 0, 0);
1229 if (!cfg.bold_colour)
1230 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1231 cc.lStructSize = sizeof(cc);
1232 cc.hwndOwner = hwnd;
1d470ad2 1233 cc.hInstance = (HWND)hinst;
374330e2 1234 cc.lpCustColors = custom;
1235 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1236 cfg.colours[i][2]);
1237 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1238 if (ChooseColor(&cc)) {
1239 cfg.colours[i][0] =
1240 (unsigned char) (cc.rgbResult & 0xFF);
1241 cfg.colours[i][1] =
1242 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1243 cfg.colours[i][2] =
1244 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1245 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0],
1246 FALSE);
1247 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1],
1248 FALSE);
1249 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2],
1250 FALSE);
1251 }
1252 }
1253 break;
1254 }
1255 break;
1256 }
1257 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1258}
1259
c9def1b8 1260static int CALLBACK TranslationProc (HWND hwnd, UINT msg,
14963b8f 1261 WPARAM wParam, LPARAM lParam) {
1262 switch (msg) {
1263 case WM_INITDIALOG:
d3d16feb 1264 CheckRadioButton (hwnd, IDC6_NOXLAT, IDC6_88592WIN1250,
1265 cfg.xlat_88592w1250 ? IDC6_88592WIN1250 :
1266 cfg.xlat_enablekoiwin ? IDC6_KOI8WIN1251 :
1267 IDC6_NOXLAT);
14963b8f 1268 CheckDlgButton (hwnd, IDC6_CAPSLOCKCYR, cfg.xlat_capslockcyr);
c9def1b8 1269 CheckRadioButton (hwnd, IDC2_VTXWINDOWS, IDC2_VTPOORMAN,
1270 cfg.vtmode == VT_XWINDOWS ? IDC2_VTXWINDOWS :
1271 cfg.vtmode == VT_OEMANSI ? IDC2_VTOEMANSI :
1272 cfg.vtmode == VT_OEMONLY ? IDC2_VTOEMONLY :
1273 IDC2_VTPOORMAN);
14963b8f 1274 case WM_COMMAND:
1275 switch (LOWORD(wParam)) {
d3d16feb 1276 case IDC6_NOXLAT:
1277 case IDC6_KOI8WIN1251:
1278 case IDC6_88592WIN1250:
1279 cfg.xlat_enablekoiwin =
1280 IsDlgButtonChecked (hwnd, IDC6_KOI8WIN1251);
1281 cfg.xlat_88592w1250 =
1282 IsDlgButtonChecked (hwnd, IDC6_88592WIN1250);
14963b8f 1283 break;
1284 case IDC6_CAPSLOCKCYR:
1285 if (HIWORD(wParam) == BN_CLICKED ||
1286 HIWORD(wParam) == BN_DOUBLECLICKED) {
1287 cfg.xlat_capslockcyr =
1288 IsDlgButtonChecked (hwnd, IDC6_CAPSLOCKCYR);
1289 }
1290 break;
c9def1b8 1291 case IDC2_VTXWINDOWS:
1292 case IDC2_VTOEMANSI:
1293 case IDC2_VTOEMONLY:
1294 case IDC2_VTPOORMAN:
1295 cfg.vtmode =
1296 (IsDlgButtonChecked (hwnd, IDC2_VTXWINDOWS) ? VT_XWINDOWS :
1297 IsDlgButtonChecked (hwnd, IDC2_VTOEMANSI) ? VT_OEMANSI :
1298 IsDlgButtonChecked (hwnd, IDC2_VTOEMONLY) ? VT_OEMONLY :
1299 VT_POORMAN);
1300 break;
14963b8f 1301 }
1302 }
1303 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1304}
1305
374330e2 1306static DLGPROC panelproc[NPANELS] = {
1307 ConnectionProc, KeyboardProc, TerminalProc,
c9def1b8 1308 TelnetProc, SshProc, SelectionProc, ColourProc, TranslationProc
374330e2 1309};
1310static char *panelids[NPANELS] = {
1311 MAKEINTRESOURCE(IDD_PANEL0),
1312 MAKEINTRESOURCE(IDD_PANEL1),
1313 MAKEINTRESOURCE(IDD_PANEL2),
1314 MAKEINTRESOURCE(IDD_PANEL3),
1315 MAKEINTRESOURCE(IDD_PANEL35),
1316 MAKEINTRESOURCE(IDD_PANEL4),
14963b8f 1317 MAKEINTRESOURCE(IDD_PANEL5),
1318 MAKEINTRESOURCE(IDD_PANEL6)
374330e2 1319};
14963b8f 1320
374330e2 1321static char *names[NPANELS] = {
14963b8f 1322 "Connection", "Keyboard", "Terminal", "Telnet",
c9def1b8 1323 "SSH", "Selection", "Colours", "Translation"
374330e2 1324};
1325
14963b8f 1326static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6, 7};
1327static int reconfp[RECONF_NPANELS] = { 1, 2, 5, 6, 7};
374330e2 1328
1329static int GenericMainDlgProc (HWND hwnd, UINT msg,
1330 WPARAM wParam, LPARAM lParam,
1331 int npanels, int *panelnums, HWND *page) {
1332 HWND hw;
1333
1334 switch (msg) {
1335 case WM_INITDIALOG:
1336 { /* centre the window */
1337 RECT rs, rd;
1338
1339 hw = GetDesktopWindow();
1340 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1341 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1342 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1343 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1344 }
1345 *page = NULL;
1346 { /* initialise the tab control */
1347 TC_ITEMHEADER tab;
1348 int i;
1349
1350 hw = GetDlgItem (hwnd, IDC_TAB);
1351 for (i=0; i<npanels; i++) {
1352 tab.mask = TCIF_TEXT;
1353 tab.pszText = names[panelnums[i]];
1354 TabCtrl_InsertItem (hw, i, &tab);
1355 }
1356/* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1357 hwnd, panelproc[panelnums[0]]);*/
1358 *page = CreateDialog (hinst, panelids[panelnums[0]],
1359 hwnd, panelproc[panelnums[0]]);
1360 SetWindowLong (*page, GWL_EXSTYLE,
1361 GetWindowLong (*page, GWL_EXSTYLE) |
1362 WS_EX_CONTROLPARENT);
1363 }
1364 SetFocus (*page);
1365 return 0;
1366 case WM_NOTIFY:
1367 if (LOWORD(wParam) == IDC_TAB &&
1368 ((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
1369 int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
1370 if (*page)
1371 DestroyWindow (*page);
1372/* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1373 hwnd, panelproc[panelnums[i]]);*/
1374 *page = CreateDialog (hinst, panelids[panelnums[i]],
1375 hwnd, panelproc[panelnums[i]]);
1376 SetWindowLong (*page, GWL_EXSTYLE,
1377 GetWindowLong (*page, GWL_EXSTYLE) |
1378 WS_EX_CONTROLPARENT);
1379 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1380 return 0;
1381 }
1382 break;
1383/* case WM_CTLCOLORDLG: */
1384/* return (int) GetStockObject (LTGRAY_BRUSH); */
1385 case WM_COMMAND:
1386 switch (LOWORD(wParam)) {
1387 case IDOK:
1388 if (*cfg.host)
1389 EndDialog (hwnd, 1);
1390 else
1391 MessageBeep (0);
1392 return 0;
1393 case IDCANCEL:
1394 EndDialog (hwnd, 0);
1395 return 0;
1396 }
1397 return 0;
1398 case WM_CLOSE:
1399 EndDialog (hwnd, 0);
1400 return 0;
c9def1b8 1401
1402 /* Grrr Explorer will maximize Dialogs! */
1403 case WM_SIZE:
1404 if (wParam == SIZE_MAXIMIZED)
1405 force_normal(hwnd);
1406 return 0;
374330e2 1407 }
1408 return 0;
1409}
1410
1411static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1412 WPARAM wParam, LPARAM lParam) {
1413#if 0
1414 HWND hw;
1415 int i;
1416#endif
1417 static HWND page = NULL;
1418
1419 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1420#if 0
1421 /*
1422 * If the Connection panel is active and the Session List
1423 * box is selected, we treat a press of Open to have an
1424 * implicit press of Load preceding it.
1425 */
1426 hw = GetDlgItem (hwnd, IDC_TAB);
1427 i = TabCtrl_GetCurSel(hw);
1428 if (panelproc[mainp[i]] == ConnectionProc &&
1429 page && implicit_load_ok) {
1430 SendMessage (page, WM_COMMAND,
1431 MAKELONG(IDC0_SESSLOAD, BN_CLICKED), 0);
1432 }
1433#endif
1434 }
1435 if (msg == WM_COMMAND && LOWORD(wParam) == IDC_ABOUT) {
1436 EnableWindow(hwnd, 0);
1437 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1438 GetParent(hwnd), AboutProc);
1439 EnableWindow(hwnd, 1);
1440 }
1441 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1442 MAIN_NPANELS, mainp, &page);
1443}
1444
1445static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1446 WPARAM wParam, LPARAM lParam) {
1447 static HWND page;
1448 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1449 RECONF_NPANELS, reconfp, &page);
1450}
1451
0a4aa984 1452void get_sesslist(int allocate) {
374330e2 1453 static char *buffer;
1454 int buflen, bufsize, i, ret;
1455 char otherbuf[2048];
1456 char *p;
1457 HKEY subkey1;
1458
1459 if (allocate) {
1460 if (RegCreateKey(HKEY_CURRENT_USER,
1461 puttystr, &subkey1) != ERROR_SUCCESS)
1462 return;
1463
1464 buflen = bufsize = 0;
1465 buffer = NULL;
1466 i = 0;
1467 do {
1468 ret = RegEnumKey(subkey1, i++, otherbuf, sizeof(otherbuf));
1469 if (ret == ERROR_SUCCESS) {
1470 bufsize = buflen + 2048;
1471 buffer = srealloc(buffer, bufsize);
1472 unmungestr(otherbuf, buffer+buflen);
1473 buflen += strlen(buffer+buflen)+1;
1474 }
1475 } while (ret == ERROR_SUCCESS);
1476 buffer = srealloc(buffer, buflen+1);
1477 buffer[buflen] = '\0';
1478
1479 p = buffer;
1480 nsessions = 1; /* "Default Settings" counts as one */
1481 while (*p) {
1482 if (strcmp(p, "Default Settings"))
1483 nsessions++;
1484 while (*p) p++;
1485 p++;
1486 }
1487
1488 sessions = smalloc(nsessions * sizeof(char *));
1489 sessions[0] = "Default Settings";
1490 p = buffer;
1491 i = 1;
1492 while (*p) {
1493 if (strcmp(p, "Default Settings"))
1494 sessions[i++] = p;
1495 while (*p) p++;
1496 p++;
1497 }
1498 } else {
1499 sfree (buffer);
1500 sfree (sessions);
1501 }
1502}
1503
1504int do_config (void) {
1505 int ret;
1506
1507 get_sesslist(TRUE);
1508 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1509 get_sesslist(FALSE);
1510
1511 return ret;
1512}
1513
1514int do_reconfig (HWND hwnd) {
1515 Config backup_cfg;
1516 int ret;
1517
1518 backup_cfg = cfg; /* structure copy */
1519 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1520 if (!ret)
1521 cfg = backup_cfg; /* structure copy */
c9def1b8 1522 else
1523 force_normal(hwnd);
1524
374330e2 1525 return ret;
1526}
1527
1528void do_defaults (char *session) {
1529 if (session)
1530 load_settings (session, TRUE);
1531 else
1532 load_settings ("Default Settings", FALSE);
1533}
1534
c5e9c988 1535void logevent (char *string) {
1536 if (nevents >= negsize) {
374330e2 1537 negsize += 64;
c5e9c988 1538 events = srealloc (events, negsize * sizeof(*events));
374330e2 1539 }
c5e9c988 1540 events[nevents] = smalloc(1+strlen(string));
1541 strcpy (events[nevents], string);
1542 nevents++;
374330e2 1543 if (logbox)
1544 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1545 0, (LPARAM)string);
1546}
1547
c5e9c988 1548void showeventlog (HWND hwnd) {
374330e2 1549 if (!logbox) {
1550 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1551 hwnd, LogProc);
1552 ShowWindow (logbox, SW_SHOWNORMAL);
1553 }
1554}
1555
1556void showabout (HWND hwnd) {
1557 if (!abtbox) {
1558 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1559 hwnd, AboutProc);
1560 ShowWindow (abtbox, SW_SHOWNORMAL);
1561 }
1562}
1563
89ee5268 1564void verify_ssh_host_key(char *host, char *keystr) {
1565 char *otherstr, *mungedhost;
374330e2 1566 int len;
1567 HKEY rkey;
1568
89ee5268 1569 len = 1 + strlen(keystr);
374330e2 1570
1571 /*
1572 * Now read a saved key in from the registry and see what it
1573 * says.
1574 */
c9def1b8 1575 otherstr = smalloc(len);
1576 mungedhost = smalloc(3*strlen(host)+1);
374330e2 1577 if (!otherstr || !mungedhost)
1578 fatalbox("Out of memory");
1579
1580 mungestr(host, mungedhost);
1581
1582 if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",
1583 &rkey) != ERROR_SUCCESS) {
1584 if (MessageBox(NULL, "PuTTY was unable to open the host key cache\n"
1585 "in the registry. There is thus no way to tell\n"
1586 "if the remote host is what you think it is.\n"
1587 "Connect anyway?", "PuTTY Problem",
1588 MB_ICONWARNING | MB_YESNO) == IDNO)
1589 exit(0);
1590 } else {
1591 DWORD readlen = len;
1592 DWORD type;
1593 int ret;
1594
1595 ret = RegQueryValueEx(rkey, mungedhost, NULL,
1596 &type, otherstr, &readlen);
1597
1598 if (ret == ERROR_MORE_DATA ||
1599 (ret == ERROR_SUCCESS && type == REG_SZ &&
1600 strcmp(otherstr, keystr))) {
1601 if (MessageBox(NULL,
1602 "This host's host key is different from the\n"
1603 "one cached in the registry! Someone may be\n"
1604 "impersonating this host for malicious reasons;\n"
1605 "alternatively, the host key may have changed\n"
1606 "due to sloppy system administration.\n"
1607 "Replace key in registry and connect?",
1608 "PuTTY: Security Warning",
1609 MB_ICONWARNING | MB_YESNO) == IDNO)
1610 exit(0);
1611 RegSetValueEx(rkey, mungedhost, 0, REG_SZ, keystr,
1612 strlen(keystr)+1);
1613 } else if (ret != ERROR_SUCCESS || type != REG_SZ) {
1614 if (MessageBox(NULL,
1615 "This host's host key is not cached in the\n"
1616 "registry. Do you want to add it to the cache\n"
1617 "and carry on connecting?",
1618 "PuTTY: New Host",
1619 MB_ICONWARNING | MB_YESNO) == IDNO)
1620 exit(0);
1621 RegSetValueEx(rkey, mungedhost, 0, REG_SZ, keystr,
1622 strlen(keystr)+1);
1623 }
1624
1625 RegCloseKey(rkey);
1626 }
1627}