From b804e1e5b96705b2f1d5bb31892a9353f9b7224c Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 18 Dec 2002 12:18:54 +0000 Subject: [PATCH] Stop proxying connections to localhost by default; should fix `x11-proxy-crash'. git-svn-id: svn://svn.tartarus.org/sgt/putty@2348 cda61777-01e9-0310-a592-d414129be87e --- doc/config.but | 8 +++++++- network.h | 2 ++ proxy.c | 8 ++++++++ putty.h | 1 + settings.c | 2 ++ unix/uxnet.c | 20 ++++++++++++++++++++ windlg.c | 11 +++++++++++ winnet.c | 20 ++++++++++++++++++++ 8 files changed, 71 insertions(+), 1 deletion(-) diff --git a/doc/config.but b/doc/config.but index bbe8495f..dfe7da5c 100644 --- a/doc/config.but +++ b/doc/config.but @@ -1,4 +1,4 @@ -\versionid $Id: config.but,v 1.45 2002/12/18 11:39:25 simon Exp $ +\versionid $Id: config.but,v 1.46 2002/12/18 12:18:54 simon Exp $ \C{config} Configuring PuTTY @@ -1439,6 +1439,12 @@ from proxying. This excludes both of the above ranges at once. +Connections to the local host (the host name \c{localhost}, and any +loopback IP address) are never proxied, even if the proxy exclude +list does not explicitly contain them. It is very unlikely that this +behaviour would ever cause problems, but if it does you can change +it by enabling \q{Consider proxying local host connections}. + \S{config-proxy-auth} Username and password \cfg{winhelp-topic}{proxy.auth} diff --git a/network.h b/network.h index 744492fe..17a73217 100644 --- a/network.h +++ b/network.h @@ -76,6 +76,8 @@ void sk_cleanup(void); /* called just before program exit */ SockAddr sk_namelookup(char *host, char **canonicalname); void sk_getaddr(SockAddr addr, char *buf, int buflen); +int sk_hostname_is_local(char *name); +int sk_address_is_local(SockAddr addr); enum { ADDRTYPE_IPV4, ADDRTYPE_IPV6 }; int sk_addrtype(SockAddr addr); void sk_addrcopy(SockAddr addr, char *buf); diff --git a/proxy.c b/proxy.c index 83bb19f8..7c608c92 100644 --- a/proxy.c +++ b/proxy.c @@ -247,6 +247,14 @@ static int proxy_for_destination (SockAddr addr, char * hostname, int port) int hostip_len, hostname_len; char * exclude_list; + /* + * Check the host name and IP against the hard-coded + * representations of `localhost'. + */ + if (!cfg.even_proxy_localhost && + (sk_hostname_is_local(hostname) || sk_address_is_local(addr))) + return 0; /* do not proxy */ + /* we want a string representation of the IP address for comparisons */ sk_getaddr(addr, hostip, 64); diff --git a/putty.h b/putty.h index 95f263b7..144ed063 100644 --- a/putty.h +++ b/putty.h @@ -214,6 +214,7 @@ struct config_tag { int tcp_nodelay; /* Proxy options */ char proxy_exclude_list[512]; + int even_proxy_localhost; enum { PROXY_NONE, PROXY_HTTP, PROXY_SOCKS, PROXY_TELNET } proxy_type; char proxy_host[512]; int proxy_port; diff --git a/settings.c b/settings.c index 28b44c05..fe90f117 100644 --- a/settings.c +++ b/settings.c @@ -150,6 +150,7 @@ void save_settings(char *section, int do_host, Config * cfg) /* proxy settings */ write_setting_s(sesskey, "ProxyExcludeList", cfg->proxy_exclude_list); + write_setting_i(sesskey, "ProxyLocalhost", cfg->even_proxy_localhost); write_setting_i(sesskey, "ProxyType", cfg->proxy_type); write_setting_s(sesskey, "ProxyHost", cfg->proxy_host); write_setting_i(sesskey, "ProxyPort", cfg->proxy_port); @@ -383,6 +384,7 @@ void load_settings(char *section, int do_host, Config * cfg) /* proxy settings */ gpps(sesskey, "ProxyExcludeList", "", cfg->proxy_exclude_list, sizeof(cfg->proxy_exclude_list)); + gppi(sesskey, "ProxyLocalhost", 0, &cfg->even_proxy_localhost); gppi(sesskey, "ProxyType", PROXY_NONE, &i); cfg->proxy_type = i; gpps(sesskey, "ProxyHost", "proxy", cfg->proxy_host, sizeof(cfg->proxy_host)); diff --git a/unix/uxnet.c b/unix/uxnet.c index 7a9630ad..cad943a8 100644 --- a/unix/uxnet.c +++ b/unix/uxnet.c @@ -209,6 +209,26 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen) #endif } +int sk_hostname_is_local(char *name) +{ + return !strcmp(name, "localhost"); +} + +int sk_address_is_local(SockAddr addr) +{ +#ifdef IPV6 + if (addr->family == AF_INET) { +#endif + struct in_addr a; + a.s_addr = htonl(addr->address); + return ipv4_is_loopback(a); +#ifdef IPV6 + } else { + FIXME; /* someone who can compile for IPV6 had better do this bit */ + } +#endif +} + int sk_addrtype(SockAddr addr) { return (addr->family == AF_INET ? ADDRTYPE_IPV4 : ADDRTYPE_IPV6); diff --git a/windlg.c b/windlg.c index 89ead9a2..40880ec9 100644 --- a/windlg.c +++ b/windlg.c @@ -454,6 +454,7 @@ enum { IDCX_ABOUT = IDC_PROXYPORTEDIT, IDC_PROXYEXCLUDESTATIC, IDC_PROXYEXCLUDEEDIT, + IDC_PROXYLOCALHOST, IDC_PROXYUSERSTATIC, IDC_PROXYUSEREDIT, IDC_PROXYPASSSTATIC, @@ -882,6 +883,7 @@ char *help_context_cmd(int id) return "JI(`',`proxy.main')"; case IDC_PROXYEXCLUDESTATIC: case IDC_PROXYEXCLUDEEDIT: + case IDC_PROXYLOCALHOST: return "JI(`',`proxy.exclude')"; case IDC_PROXYUSERSTATIC: case IDC_PROXYUSEREDIT: @@ -1349,6 +1351,7 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) SetDlgItemText(hwnd, IDC_PROXYHOSTEDIT, cfg.proxy_host); SetDlgItemInt(hwnd, IDC_PROXYPORTEDIT, cfg.proxy_port, FALSE); SetDlgItemText(hwnd, IDC_PROXYEXCLUDEEDIT, cfg.proxy_exclude_list); + CheckDlgButton(hwnd, IDC_PROXYLOCALHOST, cfg.even_proxy_localhost); SetDlgItemText(hwnd, IDC_PROXYTELNETCMDEDIT, cfg.proxy_telnet_command); SetDlgItemText(hwnd, IDC_PROXYUSEREDIT, cfg.proxy_username); SetDlgItemText(hwnd, IDC_PROXYPASSEDIT, cfg.proxy_password); @@ -1868,6 +1871,8 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) multiedit(&cp, "&Exclude Hosts/IPs", IDC_PROXYEXCLUDESTATIC, IDC_PROXYEXCLUDEEDIT, 100, NULL); + checkbox(&cp, "Consider pro&xying local host connections", + IDC_PROXYLOCALHOST); staticedit(&cp, "&Username", IDC_PROXYUSERSTATIC, IDC_PROXYUSEREDIT, 60); staticpassedit(&cp, "Pass&word", IDC_PROXYPASSSTATIC, @@ -3023,6 +3028,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, IsDlgButtonChecked(hwnd, IDC_PROXYSOCKSVER4) ? 4 : 5; } break; + case IDC_PROXYLOCALHOST: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.even_proxy_localhost = + IsDlgButtonChecked(hwnd, IDC_PROXYLOCALHOST); + break; case IDC_PROXYTYPENONE: case IDC_PROXYTYPEHTTP: case IDC_PROXYTYPESOCKS: diff --git a/winnet.c b/winnet.c index 9d3f66c2..b66cde6a 100644 --- a/winnet.c +++ b/winnet.c @@ -371,6 +371,26 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen) #endif } +int sk_hostname_is_local(char *name) +{ + return !strcmp(name, "localhost"); +} + +int sk_address_is_local(SockAddr addr) +{ +#ifdef IPV6 + if (addr->family == AF_INET) { +#endif + struct in_addr a; + a.s_addr = htonl(addr->address); + return ipv4_is_loopback(a); +#ifdef IPV6 + } else { + FIXME; /* someone who can compile for IPV6 had better do this bit */ + } +#endif +} + int sk_addrtype(SockAddr addr) { return (addr->family == AF_INET ? ADDRTYPE_IPV4 : ADDRTYPE_IPV6); -- 2.11.0