SSH port forwarding! How cool is that?
[u/mdw/putty] / windlg.c
index 641dd65..550e479 100644 (file)
--- a/windlg.c
+++ b/windlg.c
@@ -328,6 +328,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,
@@ -499,10 +503,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
@@ -614,6 +632,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);
@@ -654,11 +677,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);
@@ -726,6 +756,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 {
@@ -861,7 +894,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 +909,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);
@@ -1181,17 +1218,30 @@ static void create_controls(HWND hwnd, int dlgtype, int panel)
     }
 
     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);
+
        }
     }
 }
@@ -1825,6 +1875,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
@@ -2373,11 +2436,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:
@@ -2400,8 +2553,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 +2578,7 @@ void defuse_showwindow(void)
        hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
                            NULL, NullDlgProc);
        ShowWindow(hwnd, SW_HIDE);
+       SetActiveWindow(hwnd);
        DestroyWindow(hwnd);
     }
 }
@@ -2512,7 +2665,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 +2689,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,10 +2715,11 @@ 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);
     }
 }