X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/dc35b97d4e2902b7d4f501a53aad265448b4e3a2..2184a5d91ffbcf2de2f730c83dda2d9443035f50:/windlg.c diff --git a/windlg.c b/windlg.c index 641dd650..f3084ce2 100644 --- a/windlg.c +++ b/windlg.c @@ -18,6 +18,8 @@ static int nevents = 0, negsize = 0; static int readytogo; static int sesslist_has_focus; +static struct prefslist cipherlist; + void force_normal(HWND hwnd) { static int recurse = 0; @@ -257,6 +259,7 @@ enum { IDCX_ABOUT = IDC_LGFSTATIC, IDC_LGFEDIT, IDC_LGFBUTTON, + IDC_LGFEXPLAIN, IDC_LSTATXIST, IDC_LSTATXOVR, IDC_LSTATXAPN, @@ -328,6 +331,10 @@ enum { IDCX_ABOUT = IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT, IDC_BELL_WAVEBROWSE, + IDC_B_IND_STATIC, + IDC_B_IND_DISABLED, + IDC_B_IND_FLASH, + IDC_B_IND_STEADY, IDC_BELLOVL, IDC_BELLOVLNSTATIC, IDC_BELLOVLN, @@ -347,18 +354,29 @@ enum { IDCX_ABOUT = IDC_ROWSEDIT, IDC_COLSSTATIC, IDC_COLSEDIT, - IDC_LOCKSIZE, + IDC_RESIZESTATIC, + IDC_RESIZETERM, + IDC_RESIZEFONT, + IDC_RESIZENONE, + IDC_RESIZEEITHER, IDC_SCROLLBAR, - IDC_CLOSEWARN, + IDC_SCROLLBARFULLSCREEN, IDC_SAVESTATIC, IDC_SAVEEDIT, + IDC_SCROLLKEY, + IDC_SCROLLDISP, + windowpanelend, + + behaviourpanelstart, + IDC_TITLE_BEHAVIOUR, + IDC_BOX_BEHAVIOUR1, + IDC_CLOSEWARN, IDC_ALTF4, IDC_ALTSPACE, IDC_ALTONLY, - IDC_SCROLLKEY, - IDC_SCROLLDISP, IDC_ALWAYSONTOP, - windowpanelend, + IDC_FULLSCREENONALTENTER, + behaviourpanelend, appearancepanelstart, IDC_TITLE_APPEARANCE, @@ -379,18 +397,22 @@ enum { IDCX_ABOUT = IDC_WINNAME, IDC_HIDEMOUSE, IDC_SUNKENEDGE, + IDC_WINBSTATIC, + IDC_WINBEDIT, appearancepanelend, connectionpanelstart, IDC_TITLE_CONNECTION, IDC_BOX_CONNECTION1, IDC_BOX_CONNECTION2, + IDC_BOX_CONNECTION3, IDC_TTSTATIC, IDC_TTEDIT, IDC_LOGSTATIC, IDC_LOGEDIT, IDC_PINGSTATIC, IDC_PINGEDIT, + IDC_NODELAY, connectionpanelend, telnetpanelstart, @@ -431,25 +453,32 @@ enum { IDCX_ABOUT = IDC_BOX_SSH2, IDC_BOX_SSH3, IDC_NOPTY, - IDC_CIPHERSTATIC, - IDC_CIPHER3DES, - IDC_CIPHERBLOWF, - IDC_CIPHERDES, - IDC_CIPHERAES, + IDC_BOX_SSHCIPHER, + IDC_CIPHERSTATIC2, + IDC_CIPHERLIST, + IDC_CIPHERUP, + IDC_CIPHERDN, IDC_BUGGYMAC, - IDC_AUTHTIS, - IDC_PKSTATIC, - IDC_PKEDIT, - IDC_PKBUTTON, IDC_SSHPROTSTATIC, IDC_SSHPROT1, IDC_SSHPROT2, - IDC_AGENTFWD, IDC_CMDSTATIC, IDC_CMDEDIT, IDC_COMPRESS, sshpanelend, + sshauthpanelstart, + IDC_TITLE_SSHAUTH, + IDC_BOX_SSHAUTH1, + IDC_BOX_SSHAUTH2, + IDC_PKSTATIC, + IDC_PKEDIT, + IDC_PKBUTTON, + IDC_AGENTFWD, + IDC_AUTHTIS, + IDC_AUTHKI, + sshauthpanelend, + selectionpanelstart, IDC_TITLE_SELECTION, IDC_BOX_SELECTION1, @@ -458,12 +487,17 @@ enum { IDCX_ABOUT = IDC_MBSTATIC, IDC_MBWINDOWS, IDC_MBXTERM, + IDC_MOUSEOVERRIDE, + IDC_SELTYPESTATIC, + IDC_SELTYPELEX, + IDC_SELTYPERECT, IDC_CCSTATIC, IDC_CCLIST, IDC_CCSET, IDC_CCSTATIC2, IDC_CCEDIT, IDC_RAWCNP, + IDC_RTFPASTE, selectionpanelend, colourspanelstart, @@ -487,8 +521,10 @@ enum { IDCX_ABOUT = IDC_TITLE_TRANSLATION, IDC_BOX_TRANSLATION1, IDC_BOX_TRANSLATION2, + IDC_BOX_TRANSLATION3, IDC_CODEPAGESTATIC, IDC_CODEPAGE, + IDC_CAPSLOCKCYR, IDC_VTSTATIC, IDC_VTXWINDOWS, IDC_VTOEMANSI, @@ -499,10 +535,24 @@ enum { IDCX_ABOUT = tunnelspanelstart, IDC_TITLE_TUNNELS, - IDC_BOX_TUNNELS, + IDC_BOX_TUNNELS1, + IDC_BOX_TUNNELS2, IDC_X11_FORWARD, IDC_X11_DISPSTATIC, IDC_X11_DISPLAY, + IDC_LPORT_ALL, + IDC_PFWDSTATIC, + IDC_PFWDSTATIC2, + IDC_PFWDREMOVE, + IDC_PFWDLIST, + IDC_PFWDADD, + IDC_SPORTSTATIC, + IDC_SPORTEDIT, + IDC_DPORTSTATIC, + IDC_DPORTEDIT, + IDC_PFWDLOCAL, + IDC_PFWDREMOTE, + tunnelspanelend, controlendvalue @@ -564,6 +614,7 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) cfg.protocol == PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW); SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE); + CheckDlgButton(hwnd, IDC_NODELAY, cfg.tcp_nodelay); CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127, cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008); @@ -597,6 +648,7 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO); SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback); CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop); + CheckDlgButton(hwnd, IDC_FULLSCREENONALTENTER, cfg.fullscreenonaltenter); CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key); CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp); @@ -614,6 +666,11 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE : cfg.beep == BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT); + CheckRadioButton(hwnd, IDC_B_IND_DISABLED, IDC_B_IND_STEADY, + cfg.beep_ind == + B_IND_DISABLED ? IDC_B_IND_DISABLED : cfg.beep_ind == + B_IND_FLASH ? IDC_B_IND_FLASH : cfg.beep_ind == + B_IND_STEADY ? IDC_B_IND_STEADY : IDC_B_IND_DISABLED); SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile); CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl); SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE); @@ -627,12 +684,18 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) CheckDlgButton(hwnd, IDC_WINNAME, cfg.win_name_always); CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr); CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge); + SetDlgItemInt(hwnd, IDC_WINBEDIT, cfg.window_border, FALSE); CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT, cfg.cursor_type == 0 ? IDC_CURBLOCK : cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT); CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur); CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar); - CheckDlgButton(hwnd, IDC_LOCKSIZE, cfg.locksize); + CheckDlgButton(hwnd, IDC_SCROLLBARFULLSCREEN, cfg.scrollbar_in_fullscreen); + CheckRadioButton(hwnd, IDC_RESIZETERM, IDC_RESIZEEITHER, + cfg.resize_action == RESIZE_TERM ? IDC_RESIZETERM : + cfg.resize_action == RESIZE_FONT ? IDC_RESIZEFONT : + cfg.resize_action == RESIZE_EITHER ? IDC_RESIZEEITHER : + IDC_RESIZENONE); CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL, cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL : cfg.close_on_exit == @@ -654,11 +717,18 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) IDC_LSTATXAPN); { char *p = cfg.environmt; + SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_RESETCONTENT, 0, 0); while (*p) { SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0, (LPARAM) p); p += strlen(p) + 1; } + p = cfg.portfwd; + while (*p) { + SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING, 0, + (LPARAM) p); + p += strlen(p) + 1; + } } CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC, cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD); @@ -671,20 +741,51 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression); CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac); CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd); - CheckRadioButton(hwnd, IDC_CIPHER3DES, IDC_CIPHERAES, - cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF : - cfg.cipher == CIPHER_DES ? IDC_CIPHERDES : - cfg.cipher == CIPHER_AES ? IDC_CIPHERAES : - IDC_CIPHER3DES); CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2, cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2); CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth); + CheckDlgButton(hwnd, IDC_AUTHKI, cfg.try_ki_auth); SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile); SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd); + { + int i; + static const struct { char *s; int c; } ciphers[] = { + { "3DES", CIPHER_3DES }, + { "Blowfish", CIPHER_BLOWFISH }, + { "DES", CIPHER_DES }, + { "AES (SSH 2 only)", CIPHER_AES }, + { "-- warn below here --", CIPHER_WARN } + }; + + /* Set up the "selected ciphers" box. */ + /* (cipherlist assumed to contain all ciphers) */ + SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_RESETCONTENT, 0, 0); + for (i = 0; i < CIPHER_MAX; i++) { + int c = cfg.ssh_cipherlist[i]; + int j, pos; + char *cstr = NULL; + for (j = 0; j < (sizeof ciphers) / (sizeof ciphers[0]); j++) { + if (ciphers[j].c == c) { + cstr = ciphers[j].s; + break; + } + } + pos = SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_ADDSTRING, + 0, (LPARAM) cstr); + SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_SETITEMDATA, + pos, (LPARAM) c); + } + + } + CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM, cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS); + CheckRadioButton(hwnd, IDC_SELTYPELEX, IDC_SELTYPERECT, + cfg.rect_select == 0 ? IDC_SELTYPELEX : IDC_SELTYPERECT); + CheckDlgButton(hwnd, IDC_MOUSEOVERRIDE, cfg.mouse_override); CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp); + CheckDlgButton(hwnd, IDC_RTFPASTE, cfg.rtf_paste); { static int tabs[4] = { 25, 61, 96, 128 }; SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4, @@ -716,7 +817,19 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE); SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE); - SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage); + { + int i; + char *cp; + strcpy(cfg.line_codepage, cp_name(decode_codepage(cfg.line_codepage))); + SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_RESETCONTENT, 0, 0); + CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr); + for (i = 0; (cp = cp_enumerate(i)) != NULL; i++) { + SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_ADDSTRING, + 0, (LPARAM) cp); + } + SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage); + } + CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE, cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS : cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI : @@ -726,6 +839,9 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward); SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display); + + CheckDlgButton(hwnd, IDC_LPORT_ALL, cfg.lport_acceptall); + CheckRadioButton(hwnd, IDC_PFWDLOCAL, IDC_PFWDREMOTE, IDC_PFWDLOCAL); } struct treeview_faff { @@ -770,10 +886,11 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) bartitle(&cp, "Basic options for your PuTTY session", IDC_TITLE_SESSION); if (dlgtype == 0) { - beginbox(&cp, "Specify your connection by host name", + beginbox(&cp, "Specify your connection by host name or IP address", IDC_BOX_SESSION1); multiedit(&cp, - "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75, + "Host &Name (or IP address)", + IDC_HOSTSTATIC, IDC_HOST, 75, "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL); if (backends[3].backend == NULL) { /* this is PuTTYtel, so only three protocols available */ @@ -825,6 +942,8 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) editbutton(&cp, "Log &file name:", IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...", IDC_LGFBUTTON); + statictext(&cp, "(Log file name can contain &&Y, &&M, &&D for date," + " &&T for time, and &&H for host name)", 2, IDC_LGFEXPLAIN); radiobig(&cp, "What to do if the log file already &exists:", IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR, @@ -861,7 +980,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) } if (panel == bellpanelstart) { - /* The Bell panel. Accelerators used: [acgo] bdsm wt */ + /* The Bell panel. Accelerators used: [acgo] bdsm wit */ struct ctlpos cp; ctlposinit(&cp, hwnd, 80, 3, 13); bartitle(&cp, "Options controlling the terminal bell", @@ -876,6 +995,10 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) editbutton(&cp, "Custom sound file to play as a bell:", IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT, "Bro&wse...", IDC_BELL_WAVEBROWSE); + radioline(&cp, "Taskbar/caption &indication on bell:", + IDC_B_IND_STATIC, 3, "Disabled", IDC_B_IND_DISABLED, + "Flashing", IDC_B_IND_FLASH, "Steady", IDC_B_IND_STEADY, + NULL); endbox(&cp); beginbox(&cp, "Control the bell overload behaviour", IDC_BOX_BELL2); @@ -887,7 +1010,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20); statictext(&cp, "The bell is re-enabled after a few seconds of silence.", - IDC_BELLOVLEXPLAIN); + 1, IDC_BELLOVLEXPLAIN); staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC, IDC_BELLOVLS, 20); endbox(&cp); @@ -897,10 +1020,8 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */ struct ctlpos cp; ctlposinit(&cp, hwnd, 80, 3, 13); - /* - bartitle(&cp, "Options controlling the effects of keys", - IDC_TITLE_KEYBOARD); - */ + bartitle(&cp, "Options controlling the effects of keys", + IDC_TITLE_KEYBOARD); beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1); radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2, "Control-H", IDC_DEL008, @@ -937,7 +1058,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) } if (panel == windowpanelstart) { - /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */ + /* The Window panel. Accelerators used: [acgo] rmz sdikp */ struct ctlpos cp; ctlposinit(&cp, hwnd, 80, 3, 13); bartitle(&cp, "Options controlling PuTTY's window", @@ -946,31 +1067,29 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) multiedit(&cp, "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50, "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL); - checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE); + radiobig(&cp, "When window is resi&zed:", IDC_RESIZESTATIC, + "Change the number of rows and columns", IDC_RESIZETERM, + "Change the size of the font", IDC_RESIZEFONT, + "Change font size only when maximised", IDC_RESIZEEITHER, + "Forbid resizing completely", IDC_RESIZENONE, NULL); endbox(&cp); beginbox(&cp, "Control the scrollback in the window", IDC_BOX_WINDOW2); staticedit(&cp, "Lines of &scrollback", IDC_SAVESTATIC, IDC_SAVEEDIT, 50); checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR); + checkbox(&cp, "D&isplay scrollbar in full screen mode", IDC_SCROLLBARFULLSCREEN); checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY); checkbox(&cp, "Reset scrollback on dis&play activity", IDC_SCROLLDISP); endbox(&cp); - beginbox(&cp, NULL, IDC_BOX_WINDOW3); - checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN); - checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4); - checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE); - checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY); - checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP); - endbox(&cp); } if (panel == appearancepanelstart) { /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */ struct ctlpos cp; ctlposinit(&cp, hwnd, 80, 3, 13); - bartitle(&cp, "Options controlling PuTTY's appearance", + bartitle(&cp, "Configure the appearance of PuTTY's window", IDC_TITLE_APPEARANCE); beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1); radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3, @@ -997,17 +1116,45 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5); checkbox(&cp, "&Sunken-edge border (slightly thicker)", IDC_SUNKENEDGE); + staticedit(&cp, "Gap between text and window edge", + IDC_WINBSTATIC, IDC_WINBEDIT, 20); + endbox(&cp); + } + + if (panel == behaviourpanelstart) { + /* The Behaviour panel. Accelerators used: [acgo] w4yltf */ + struct ctlpos cp; + ctlposinit(&cp, hwnd, 80, 3, 13); + bartitle(&cp, "Configure the behaviour of PuTTY's window", + IDC_TITLE_WINDOW); + beginbox(&cp, NULL, IDC_BOX_BEHAVIOUR1); + checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN); + checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4); + checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE); + checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY); + checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP); + checkbox(&cp, "&Full screen on Alt-Enter", IDC_FULLSCREENONALTENTER); endbox(&cp); } if (panel == translationpanelstart) { - /* The Translation panel. Accelerators used: [acgo] xbep t s */ + /* The Translation panel. Accelerators used: [acgo] rxbepus */ struct ctlpos cp; ctlposinit(&cp, hwnd, 80, 3, 13); bartitle(&cp, "Options controlling character set translation", IDC_TITLE_TRANSLATION); - beginbox(&cp, "Adjust how PuTTY displays line drawing characters", + beginbox(&cp, "Character set translation on received data", IDC_BOX_TRANSLATION1); + combobox(&cp, "&Received data assumed to be in which character set:", + IDC_CODEPAGESTATIC, IDC_CODEPAGE); + endbox(&cp); + beginbox(&cp, "Enable character set translation on input data", + IDC_BOX_TRANSLATION2); + checkbox(&cp, "Cap&s Lock acts as Cyrillic switch", + IDC_CAPSLOCKCYR); + endbox(&cp); + beginbox(&cp, "Adjust how PuTTY displays line drawing characters", + IDC_BOX_TRANSLATION3); radiobig(&cp, "Handling of line drawing characters:", IDC_VTSTATIC, "Font has &XWindows encoding", IDC_VTXWINDOWS, @@ -1016,15 +1163,10 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")", IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL); endbox(&cp); - beginbox(&cp, "Enable character set translation on received data", - IDC_BOX_TRANSLATION2); - multiedit(&cp, "Line codepage:", IDC_CODEPAGESTATIC, - IDC_CODEPAGE, 100, NULL); - endbox(&cp); } if (panel == selectionpanelstart) { - /* The Selection panel. Accelerators used: [acgo] d wx hst */ + /* The Selection panel. Accelerators used: [acgo] df wxp hst nr */ struct ctlpos cp; ctlposinit(&cp, hwnd, 80, 3, 13); bartitle(&cp, "Options controlling copy and paste", @@ -1034,6 +1176,9 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) checkbox(&cp, "&Don't translate line drawing chars into +, - and |", IDC_RAWCNP); + checkbox(&cp, + "Paste to clipboard in RT&F as well as plain text", + IDC_RTFPASTE); endbox(&cp); beginbox(&cp, "Control which mouse button does which thing", IDC_BOX_SELECTION2); @@ -1041,6 +1186,14 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS, "&xterm (Right extends, Middle pastes)", IDC_MBXTERM, NULL); + checkbox(&cp, + "Shift overrides a&pplication's use of mouse", + IDC_MOUSEOVERRIDE); + radioline(&cp, + "Default selection mode (Alt+drag does the other one):", + IDC_SELTYPESTATIC, 2, + "&Normal", IDC_SELTYPELEX, + "&Rectangular block", IDC_SELTYPERECT, NULL); endbox(&cp); beginbox(&cp, "Control the select-one-word-at-a-time mode", IDC_BOX_SELECTION3); @@ -1074,7 +1227,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) } if (panel == connectionpanelstart) { - /* The Connection panel. Accelerators used: [acgo] tuk */ + /* The Connection panel. Accelerators used: [acgo] tukn */ struct ctlpos cp; ctlposinit(&cp, hwnd, 80, 3, 13); bartitle(&cp, "Options controlling the connection", @@ -1098,6 +1251,13 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) staticedit(&cp, "Seconds between &keepalives (0 to turn off)", IDC_PINGSTATIC, IDC_PINGEDIT, 20); endbox(&cp); + if (dlgtype == 0) { + beginbox(&cp, "Low-level TCP connection options", + IDC_BOX_CONNECTION3); + checkbox(&cp, "Disable &Nagle's algorithm (TCP_NODELAY option)", + IDC_NODELAY); + endbox(&cp); + } } if (panel == telnetpanelstart) { @@ -1145,7 +1305,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) } if (panel == sshpanelstart) { - /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */ + /* The SSH panel. Accelerators used: [acgo] r pe12i s */ struct ctlpos cp; ctlposinit(&cp, hwnd, 80, 3, 13); if (dlgtype == 0) { @@ -1156,42 +1316,72 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100, NULL); endbox(&cp); - beginbox(&cp, "Authentication options", IDC_BOX_SSH2); - checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication", - IDC_AUTHTIS); - checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD); - editbutton(&cp, "Private &key file for authentication:", - IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", - IDC_PKBUTTON); - endbox(&cp); - beginbox(&cp, "Protocol options", IDC_BOX_SSH3); + beginbox(&cp, "Protocol options", IDC_BOX_SSH2); checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY); checkbox(&cp, "Enable compr&ession", IDC_COMPRESS); radioline(&cp, "Preferred SSH protocol version:", IDC_SSHPROTSTATIC, 2, "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL); - radioline(&cp, "Preferred encryption algorithm:", - IDC_CIPHERSTATIC, 4, "&3DES", IDC_CIPHER3DES, - "&Blowfish", IDC_CIPHERBLOWF, "&DES", IDC_CIPHERDES, - "AE&S", IDC_CIPHERAES, NULL); checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x", IDC_BUGGYMAC); endbox(&cp); + beginbox(&cp, "Encryption options", IDC_BOX_SSH3); + prefslist(&cipherlist, &cp, "Encryption cipher &selection policy:", + IDC_CIPHERSTATIC2, IDC_CIPHERLIST, IDC_CIPHERUP, + IDC_CIPHERDN); + endbox(&cp); + } + } + + if (panel == sshauthpanelstart) { + /* The SSH authentication panel. Accelerators used: [acgo] m fkiw */ + struct ctlpos cp; + ctlposinit(&cp, hwnd, 80, 3, 13); + if (dlgtype == 0) { + bartitle(&cp, "Options controlling SSH authentication", + IDC_TITLE_SSHAUTH); + beginbox(&cp, "Authentication methods", + IDC_BOX_SSHAUTH1); + checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication (SSH1)", + IDC_AUTHTIS); + checkbox(&cp, "Attempt \"keyboard-&interactive\" authentication" + " (SSH2)", IDC_AUTHKI); + endbox(&cp); + beginbox(&cp, "Authentication parameters", + IDC_BOX_SSHAUTH2); + checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD); + editbutton(&cp, "Private &key file for authentication:", + IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", + IDC_PKBUTTON); + endbox(&cp); } } if (panel == tunnelspanelstart) { - /* The Tunnels panel. Accelerators used: [acgo] ex */ + /* The Tunnels panel. Accelerators used: [acgo] deilmrstx */ struct ctlpos cp; ctlposinit(&cp, hwnd, 80, 3, 13); if (dlgtype == 0) { bartitle(&cp, "Options controlling SSH tunnelling", IDC_TITLE_TUNNELS); - beginbox(&cp, "X11 forwarding options", IDC_BOX_TUNNELS); + beginbox(&cp, "X11 forwarding", IDC_BOX_TUNNELS1); checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD); multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC, IDC_X11_DISPLAY, 50, NULL); endbox(&cp); + beginbox(&cp, "Port forwarding", IDC_BOX_TUNNELS2); + checkbox(&cp, "Local ports accept connections from o&ther hosts", IDC_LPORT_ALL); + staticbtn(&cp, "Forwarded ports:", IDC_PFWDSTATIC, + "&Remove", IDC_PFWDREMOVE); + fwdsetter(&cp, IDC_PFWDLIST, + "Add new forwarded port:", IDC_PFWDSTATIC2, + "&Source port", IDC_SPORTSTATIC, IDC_SPORTEDIT, + "Dest&ination", IDC_DPORTSTATIC, IDC_DPORTEDIT, + "A&dd", IDC_PFWDADD); + bareradioline(&cp, 2, + "&Local", IDC_PFWDLOCAL, "Re&mote", IDC_PFWDREMOTE, NULL); + endbox(&cp); + } } } @@ -1240,6 +1430,7 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, char portname[32]; struct servent *service; int i; + static UINT draglistmsg = WM_NULL; switch (msg) { case WM_INITDIALOG: @@ -1286,7 +1477,7 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, r.left = 3; r.right = r.left + 75; r.top = 13; - r.bottom = r.top + 206; + r.bottom = r.top + 219; MapDialogRect(hwnd, &r); treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "", WS_CHILD | WS_VISIBLE | @@ -1313,6 +1504,7 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, treeview_insert(&tvfaff, 1, "Bell"); treeview_insert(&tvfaff, 0, "Window"); treeview_insert(&tvfaff, 1, "Appearance"); + treeview_insert(&tvfaff, 1, "Behaviour"); treeview_insert(&tvfaff, 1, "Translation"); treeview_insert(&tvfaff, 1, "Selection"); treeview_insert(&tvfaff, 1, "Colours"); @@ -1322,6 +1514,9 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, treeview_insert(&tvfaff, 1, "Rlogin"); if (backends[3].backend != NULL) { treeview_insert(&tvfaff, 1, "SSH"); + /* XXX long name is ugly */ + /* XXX make it closed by default? */ + treeview_insert(&tvfaff, 2, "Auth"); treeview_insert(&tvfaff, 2, "Tunnels"); } } @@ -1363,6 +1558,9 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, TVITEM item; int j; char buffer[64]; + + SendMessage (hwnd, WM_SETREDRAW, FALSE, 0); + item.hItem = i; item.pszText = buffer; item.cchTextMax = sizeof(buffer); @@ -1387,6 +1585,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, create_controls(hwnd, dlgtype, windowpanelstart); if (!strcmp(buffer, "Appearance")) create_controls(hwnd, dlgtype, appearancepanelstart); + if (!strcmp(buffer, "Behaviour")) + create_controls(hwnd, dlgtype, behaviourpanelstart); if (!strcmp(buffer, "Tunnels")) create_controls(hwnd, dlgtype, tunnelspanelstart); if (!strcmp(buffer, "Connection")) @@ -1397,6 +1597,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, create_controls(hwnd, dlgtype, rloginpanelstart); if (!strcmp(buffer, "SSH")) create_controls(hwnd, dlgtype, sshpanelstart); + if (!strcmp(buffer, "Auth")) + create_controls(hwnd, dlgtype, sshauthpanelstart); if (!strcmp(buffer, "Selection")) create_controls(hwnd, dlgtype, selectionpanelstart); if (!strcmp(buffer, "Colours")) @@ -1405,6 +1607,9 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, create_controls(hwnd, dlgtype, translationpanelstart); init_dlg_ctrls(hwnd, FALSE); + + SendMessage (hwnd, WM_SETREDRAW, TRUE, 0); + InvalidateRect (hwnd, NULL, TRUE); SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */ return 0; @@ -1582,6 +1787,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, MyGetDlgItemInt(hwnd, IDC_PINGEDIT, &cfg.ping_interval); break; + case IDC_NODELAY: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.tcp_nodelay = + IsDlgButtonChecked(hwnd, IDC_NODELAY); + break; case IDC_DEL008: case IDC_DEL127: if (HIWORD(wParam) == BN_CLICKED || @@ -1714,6 +1925,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, cfg.alwaysontop = IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP); break; + case IDC_FULLSCREENONALTENTER: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.fullscreenonaltenter = + IsDlgButtonChecked(hwnd, IDC_FULLSCREENONALTENTER); + break; case IDC_SCROLLKEY: if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) @@ -1825,6 +2042,19 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, cfg.beep = BELL_VISUAL; } break; + case IDC_B_IND_DISABLED: + case IDC_B_IND_FLASH: + case IDC_B_IND_STEADY: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) { + if (LOWORD(wParam) == IDC_B_IND_DISABLED) + cfg.beep_ind = B_IND_DISABLED; + if (LOWORD(wParam) == IDC_B_IND_FLASH) + cfg.beep_ind = B_IND_FLASH; + if (LOWORD(wParam) == IDC_B_IND_STEADY) + cfg.beep_ind = B_IND_STEADY; + } + break; case IDC_BELL_WAVEBROWSE: memset(&of, 0, sizeof(of)); #ifdef OPENFILENAME_SIZE_VERSION_400 @@ -1904,6 +2134,13 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, cfg.sunken_edge = IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE); break; + case IDC_WINBEDIT: + if (HIWORD(wParam) == EN_CHANGE) + MyGetDlgItemInt(hwnd, IDC_WINBEDIT, + &cfg.window_border); + if (cfg.window_border > 32) + cfg.window_border = 32; + break; case IDC_CURBLOCK: if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) @@ -1931,11 +2168,27 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, cfg.scrollbar = IsDlgButtonChecked(hwnd, IDC_SCROLLBAR); break; - case IDC_LOCKSIZE: + case IDC_SCROLLBARFULLSCREEN: if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) - cfg.locksize = - IsDlgButtonChecked(hwnd, IDC_LOCKSIZE); + cfg.scrollbar_in_fullscreen = + IsDlgButtonChecked(hwnd, IDC_SCROLLBARFULLSCREEN); + break; + case IDC_RESIZETERM: + case IDC_RESIZEFONT: + case IDC_RESIZENONE: + case IDC_RESIZEEITHER: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) { + cfg.resize_action = + IsDlgButtonChecked(hwnd, + IDC_RESIZETERM) ? RESIZE_TERM : + IsDlgButtonChecked(hwnd, + IDC_RESIZEFONT) ? RESIZE_FONT : + IsDlgButtonChecked(hwnd, + IDC_RESIZEEITHER) ? RESIZE_EITHER : + RESIZE_DISABLED; + } break; case IDC_WINEDIT: if (HIWORD(wParam) == EN_CHANGE) @@ -2145,21 +2398,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, cfg.agentfwd = IsDlgButtonChecked(hwnd, IDC_AGENTFWD); break; - case IDC_CIPHER3DES: - case IDC_CIPHERBLOWF: - case IDC_CIPHERDES: - case IDC_CIPHERAES: - if (HIWORD(wParam) == BN_CLICKED || - HIWORD(wParam) == BN_DOUBLECLICKED) { - if (IsDlgButtonChecked(hwnd, IDC_CIPHER3DES)) - cfg.cipher = CIPHER_3DES; - else if (IsDlgButtonChecked(hwnd, IDC_CIPHERBLOWF)) - cfg.cipher = CIPHER_BLOWFISH; - else if (IsDlgButtonChecked(hwnd, IDC_CIPHERDES)) - cfg.cipher = CIPHER_DES; - else if (IsDlgButtonChecked(hwnd, IDC_CIPHERAES)) - cfg.cipher = CIPHER_AES; - } + case IDC_CIPHERLIST: + case IDC_CIPHERUP: + case IDC_CIPHERDN: + handle_prefslist(&cipherlist, + cfg.ssh_cipherlist, CIPHER_MAX, + 0, hwnd, wParam, lParam); break; case IDC_SSHPROT1: case IDC_SSHPROT2: @@ -2177,6 +2421,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, cfg.try_tis_auth = IsDlgButtonChecked(hwnd, IDC_AUTHTIS); break; + case IDC_AUTHKI: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.try_ki_auth = + IsDlgButtonChecked(hwnd, IDC_AUTHKI); + break; case IDC_PKEDIT: if (HIWORD(wParam) == EN_CHANGE) GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile, @@ -2203,7 +2453,7 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, of.nMaxFile = sizeof(filename); of.lpstrFileTitle = NULL; of.lpstrInitialDir = NULL; - of.lpstrTitle = "Select Public Key File"; + of.lpstrTitle = "Select Private Key File"; of.Flags = 0; if (GetOpenFileName(&of)) { strcpy(cfg.keyfile, filename); @@ -2212,10 +2462,21 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, break; case IDC_RAWCNP: cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP); + break; + case IDC_RTFPASTE: + cfg.rtf_paste = IsDlgButtonChecked(hwnd, IDC_RTFPASTE); + break; case IDC_MBWINDOWS: case IDC_MBXTERM: cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM); break; + case IDC_SELTYPELEX: + case IDC_SELTYPERECT: + cfg.rect_select = IsDlgButtonChecked(hwnd, IDC_SELTYPERECT); + break; + case IDC_MOUSEOVERRIDE: + cfg.mouse_override = IsDlgButtonChecked(hwnd, IDC_MOUSEOVERRIDE); + break; case IDC_CCSET: { BOOL ok; @@ -2328,30 +2589,27 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, } break; case IDC_CODEPAGE: - if (HIWORD(wParam) == EN_CHANGE) + if (HIWORD(wParam) == CBN_SELCHANGE) { + int index = SendDlgItemMessage(hwnd, IDC_CODEPAGE, + CB_GETCURSEL, 0, 0); + SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_GETLBTEXT, + index, (LPARAM)cfg.line_codepage); + } else if (HIWORD(wParam) == CBN_EDITCHANGE) { GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage, sizeof(cfg.line_codepage) - 1); - if (HIWORD(wParam) == EN_KILLFOCUS) { - int cp = decode_codepage(cfg.line_codepage); - char buf[256]; - if (cp < -1) { - if (cp == -2) - sprintf(buf, - "Unable to identify character set '%s', " - "translation disabled.", - cfg.line_codepage); - if (cp == -3) - sprintf(buf, - "Character set '%s' is a DBCS, " - "translation is not available.", - cfg.line_codepage); - MessageBox(hwnd, buf, "PuTTY Error", - MB_ICONERROR | MB_OK); - } - strcpy(cfg.line_codepage, cp_name(cp)); + } else if (HIWORD(wParam) == CBN_KILLFOCUS) { + strcpy(cfg.line_codepage, + cp_name(decode_codepage(cfg.line_codepage))); SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage); } break; + case IDC_CAPSLOCKCYR: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) { + cfg.xlat_capslockcyr = + IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR); + } + break; case IDC_VTXWINDOWS: case IDC_VTOEMANSI: case IDC_VTOEMONLY: @@ -2373,11 +2631,101 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, cfg.x11_forward = IsDlgButtonChecked(hwnd, IDC_X11_FORWARD); break; + case IDC_LPORT_ALL: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.lport_acceptall = + IsDlgButtonChecked(hwnd, IDC_LPORT_ALL); + break; case IDC_X11_DISPLAY: if (HIWORD(wParam) == EN_CHANGE) GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display, sizeof(cfg.x11_display) - 1); break; + case IDC_PFWDADD: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) { + char str[sizeof(cfg.portfwd)]; + char *p; + if (IsDlgButtonChecked(hwnd, IDC_PFWDLOCAL)) + str[0] = 'L'; + else + str[0] = 'R'; + GetDlgItemText(hwnd, IDC_SPORTEDIT, str+1, + sizeof(str) - 2); + if (!str[1]) { + MessageBox(hwnd, + "You need to specify a source port number", + "PuTTY Error", MB_OK | MB_ICONERROR); + break; + } + p = str + strlen(str); + *p++ = '\t'; + GetDlgItemText(hwnd, IDC_DPORTEDIT, p, + sizeof(str) - 1 - (p - str)); + if (!*p || !strchr(p, ':')) { + MessageBox(hwnd, + "You need to specify a destination address\n" + "in the form \"host.name:port\"", + "PuTTY Error", MB_OK | MB_ICONERROR); + break; + } + p = cfg.portfwd; + while (*p) { + while (*p) + p++; + p++; + } + if ((p - cfg.portfwd) + strlen(str) + 2 < + sizeof(cfg.portfwd)) { + strcpy(p, str); + p[strlen(str) + 1] = '\0'; + SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING, + 0, (LPARAM) str); + SetDlgItemText(hwnd, IDC_SPORTEDIT, ""); + SetDlgItemText(hwnd, IDC_DPORTEDIT, ""); + } else { + MessageBox(hwnd, "Too many forwardings", + "PuTTY Error", MB_OK | MB_ICONERROR); + } + } + break; + case IDC_PFWDREMOVE: + if (HIWORD(wParam) != BN_CLICKED && + HIWORD(wParam) != BN_DOUBLECLICKED) break; + i = SendDlgItemMessage(hwnd, IDC_PFWDLIST, + LB_GETCURSEL, 0, 0); + if (i == LB_ERR) + MessageBeep(0); + else { + char *p, *q; + + SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_DELETESTRING, + i, 0); + p = cfg.portfwd; + while (i > 0) { + if (!*p) + goto disaster2; + while (*p) + p++; + p++; + i--; + } + q = p; + if (!*p) + goto disaster2; + while (*p) + p++; + p++; + while (*p) { + while (*p) + *q++ = *p++; + *q++ = *p++; + } + *q = '\0'; + disaster2:; + } + break; } return 0; case WM_CLOSE: @@ -2389,6 +2737,26 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, if (wParam == SIZE_MAXIMIZED) force_normal(hwnd); return 0; + + default: + /* + * Handle application-defined messages eg. DragListBox + */ + /* First find out what the number is (once). */ + if (draglistmsg == WM_NULL) + draglistmsg = RegisterWindowMessage (DRAGLISTMSGSTRING); + + if (msg == draglistmsg) { + /* Only process once dialog is fully formed. */ + if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) { + case IDC_CIPHERLIST: + return handle_prefslist(&cipherlist, + cfg.ssh_cipherlist, CIPHER_MAX, + 1, hwnd, wParam, lParam); + } + } + return 0; + } return 0; } @@ -2400,8 +2768,7 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, } if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) { EnableWindow(hwnd, 0); - DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), - GetParent(hwnd), AboutProc); + DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc); EnableWindow(hwnd, 1); SetActiveWindow(hwnd); } @@ -2426,6 +2793,7 @@ void defuse_showwindow(void) hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), NULL, NullDlgProc); ShowWindow(hwnd, SW_HIDE); + SetActiveWindow(hwnd); DestroyWindow(hwnd); } } @@ -2512,7 +2880,9 @@ void verify_ssh_host_key(char *host, int port, char *keytype, "%s\n" "If you trust this host, hit Yes to add the key to\n" "PuTTY's cache and carry on connecting.\n" - "If you do not trust this host, hit No to abandon the\n" + "If you want to carry on connecting just once, without\n" + "adding the key to the cache, hit No.\n" + "If you do not trust this host, hit Cancel to abandon the\n" "connection.\n"; static const char wrongmsg[] = @@ -2534,7 +2904,6 @@ void verify_ssh_host_key(char *host, int port, char *keytype, static const char mbtitle[] = "PuTTY Security Alert"; - char message[160 + /* sensible fingerprint max size */ (sizeof(absentmsg) > sizeof(wrongmsg) ? @@ -2561,14 +2930,45 @@ void verify_ssh_host_key(char *host, int port, char *keytype, int mbret; sprintf(message, absentmsg, fingerprint); mbret = MessageBox(NULL, message, mbtitle, - MB_ICONWARNING | MB_YESNO); - if (mbret == IDNO) + MB_ICONWARNING | MB_YESNOCANCEL); + if (mbret == IDYES) + store_host_key(host, port, keytype, keystr); + if (mbret == IDCANCEL) exit(0); - store_host_key(host, port, keytype, keystr); } } /* + * Ask whether the selected cipher is acceptable (since it was + * below the configured 'warn' threshold). + * cs: 0 = both ways, 1 = client->server, 2 = server->client + */ +void askcipher(char *ciphername, int cs) +{ + static const char mbtitle[] = "PuTTY Security Alert"; + static const char msg[] = + "The first %.35scipher supported by the server\n" + "is %.64s, which is below the configured\n" + "warning threshold.\n" + "Do you want to continue with this connection?\n"; + /* guessed cipher name + type max length */ + char message[100 + sizeof(msg)]; + int mbret; + + sprintf(message, msg, + (cs == 0) ? "" : + (cs == 1) ? "client-to-server " : + "server-to-client ", + ciphername); + mbret = MessageBox(NULL, message, mbtitle, + MB_ICONWARNING | MB_YESNO); + if (mbret == IDYES) + return; + else + exit(0); +} + +/* * Ask whether to wipe a session log file before writing to it. * Returns 2 for wipe, 1 for append, 0 for cancel (don't log). */ @@ -2598,3 +2998,23 @@ int askappend(char *filename) else return 0; } + +/* + * Warn about the obsolescent key file format. + */ +void old_keyfile_warning(void) +{ + static const char mbtitle[] = "PuTTY Key File Warning"; + static const char message[] = + "You are loading an SSH 2 private key which has an\n" + "old version of the file format. This means your key\n" + "file is not fully tamperproof. Future versions of\n" + "PuTTY may stop supporting this private key format,\n" + "so we recommend you convert your key to the new\n" + "format.\n" + "\n" + "You can perform this conversion by loading the key\n" + "into PuTTYgen and then saving it again."; + + MessageBox(NULL, message, mbtitle, MB_OK); +}