mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-04-20 04:28:07 -05:00
Implement `portfwd-loopback-choice'. Works on local side in Unix as
well, though it's a lot less useful since you still can't bind to low-numbered ports of odd loopback IPs. Should work in principle for SSH2 remote forwardings as well as local ones, but OpenSSH seems unwilling to cooperate. [originally from svn r2344]
This commit is contained in:
parent
8cb52a26e1
commit
99b870dbc6
21
cmdline.c
21
cmdline.c
@ -160,7 +160,7 @@ int cmdline_process_param(char *p, char *value, int need_save)
|
|||||||
cfg.username[sizeof(cfg.username) - 1] = '\0';
|
cfg.username[sizeof(cfg.username) - 1] = '\0';
|
||||||
}
|
}
|
||||||
if ((!strcmp(p, "-L") || !strcmp(p, "-R"))) {
|
if ((!strcmp(p, "-L") || !strcmp(p, "-R"))) {
|
||||||
char *fwd, *ptr, *q;
|
char *fwd, *ptr, *q, *qq;
|
||||||
int i=0;
|
int i=0;
|
||||||
RETURN(2);
|
RETURN(2);
|
||||||
UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER);
|
UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER);
|
||||||
@ -180,8 +180,23 @@ int cmdline_process_param(char *p, char *value, int need_save)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
strncpy(ptr+1, fwd, sizeof(cfg.portfwd) - i);
|
strncpy(ptr+1, fwd, sizeof(cfg.portfwd) - i);
|
||||||
q = strchr(ptr, ':');
|
/*
|
||||||
if (q) *q = '\t'; /* replace first : with \t */
|
* We expect _at least_ two colons in this string. The
|
||||||
|
* possible formats are `sourceport:desthost:destport', or
|
||||||
|
* `sourceip:sourceport:desthost:destport' if you're
|
||||||
|
* specifying a particular loopback address. We need to
|
||||||
|
* replace the one between source and dest with a \t; this
|
||||||
|
* means we must find the second-to-last colon in the
|
||||||
|
* string.
|
||||||
|
*/
|
||||||
|
q = qq = strchr(ptr, ':');
|
||||||
|
while (qq) {
|
||||||
|
char *qqq = strchr(qq+1, ':');
|
||||||
|
if (qqq)
|
||||||
|
q = qq;
|
||||||
|
qq = qqq;
|
||||||
|
}
|
||||||
|
if (q) *q = '\t'; /* replace second-last colon with \t */
|
||||||
cfg.portfwd[sizeof(cfg.portfwd) - 1] = '\0';
|
cfg.portfwd[sizeof(cfg.portfwd) - 1] = '\0';
|
||||||
cfg.portfwd[sizeof(cfg.portfwd) - 2] = '\0';
|
cfg.portfwd[sizeof(cfg.portfwd) - 2] = '\0';
|
||||||
ptr[strlen(ptr)+1] = '\000'; /* append two '\000' */
|
ptr[strlen(ptr)+1] = '\000'; /* append two '\000' */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
\versionid $Id: config.but,v 1.44 2002/10/22 09:40:38 simon Exp $
|
\versionid $Id: config.but,v 1.45 2002/12/18 11:39:25 simon Exp $
|
||||||
|
|
||||||
\C{config} Configuring PuTTY
|
\C{config} Configuring PuTTY
|
||||||
|
|
||||||
@ -1881,6 +1881,19 @@ in the list box.
|
|||||||
To remove a port forwarding, simply select its details in the list
|
To remove a port forwarding, simply select its details in the list
|
||||||
box, and click the \q{Remove} button.
|
box, and click the \q{Remove} button.
|
||||||
|
|
||||||
|
In the \q{Source port} box, you can also optionally enter an IP
|
||||||
|
address to listen on. Typically a Windows machine can be asked to
|
||||||
|
listen on any single IP address in the \cw{127.*.*.*} range, and all
|
||||||
|
of these are loopback addresses available only to the local machine.
|
||||||
|
So if you forward (for example) \c{127.0.0.5:79} to a remote
|
||||||
|
machine's \cw{finger} port, then you should be able to run commands
|
||||||
|
such as \c{finger fred@127.0.0.5}. This can be useful if the program
|
||||||
|
connecting to the forwarded port doesn't allow you to change the
|
||||||
|
port number it uses. This feature is available for local-to-remote
|
||||||
|
forwarded ports; SSH1 is unable to support it for remote-to-local
|
||||||
|
ports, while SSH2 can support it in theory but servers will not
|
||||||
|
necessarily cooperate.
|
||||||
|
|
||||||
\S{config-ssh-portfwd-localhost} Controlling the visibility of
|
\S{config-ssh-portfwd-localhost} Controlling the visibility of
|
||||||
forwarded ports
|
forwarded ports
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
\versionid $Id: using.but,v 1.8 2002/09/11 17:30:36 jacob Exp $
|
\versionid $Id: using.but,v 1.9 2002/12/18 11:39:25 simon Exp $
|
||||||
|
|
||||||
\C{using} Using PuTTY
|
\C{using} Using PuTTY
|
||||||
|
|
||||||
@ -254,7 +254,8 @@ to a port on a remote server, you need to:
|
|||||||
|
|
||||||
\b Choose a port number on your local machine where PuTTY should
|
\b Choose a port number on your local machine where PuTTY should
|
||||||
listen for incoming connections. There are likely to be plenty of
|
listen for incoming connections. There are likely to be plenty of
|
||||||
unused port numbers above 3000.
|
unused port numbers above 3000. (You can also use a local loopback
|
||||||
|
address here; see \k{config-ssh-portfwd} for more details.)
|
||||||
|
|
||||||
\b Now, before you start your SSH connection, go to the Tunnels
|
\b Now, before you start your SSH connection, go to the Tunnels
|
||||||
panel (see \k{config-ssh-portfwd}). Make sure the \q{Local} radio
|
panel (see \k{config-ssh-portfwd}). Make sure the \q{Local} radio
|
||||||
|
@ -67,7 +67,7 @@ struct plug_function_table {
|
|||||||
Socket new_connection(SockAddr addr, char *hostname,
|
Socket new_connection(SockAddr addr, char *hostname,
|
||||||
int port, int privport,
|
int port, int privport,
|
||||||
int oobinline, int nodelay, Plug plug);
|
int oobinline, int nodelay, Plug plug);
|
||||||
Socket new_listener(int port, Plug plug, int local_host_only);
|
Socket new_listener(char *srcaddr, int port, Plug plug, int local_host_only);
|
||||||
|
|
||||||
/* socket functions */
|
/* socket functions */
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ void sk_addr_free(SockAddr addr);
|
|||||||
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
||||||
int nodelay, Plug p);
|
int nodelay, Plug p);
|
||||||
|
|
||||||
Socket sk_newlistener(int port, Plug plug, int local_host_only);
|
Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only);
|
||||||
|
|
||||||
Socket sk_register(void *sock, Plug plug);
|
Socket sk_register(void *sock, Plug plug);
|
||||||
|
|
||||||
|
@ -203,9 +203,10 @@ static int pfd_accepting(Plug p, void *sock)
|
|||||||
|
|
||||||
|
|
||||||
/* Add a new forwarding from port -> desthost:destport
|
/* Add a new forwarding from port -> desthost:destport
|
||||||
sets up a listener on the local machine on port
|
sets up a listener on the local machine on (srcaddr:)port
|
||||||
*/
|
*/
|
||||||
char *pfd_addforward(char *desthost, int destport, int port, void *backhandle)
|
char *pfd_addforward(char *desthost, int destport, char *srcaddr, int port,
|
||||||
|
void *backhandle)
|
||||||
{
|
{
|
||||||
static struct plug_function_table fn_table = {
|
static struct plug_function_table fn_table = {
|
||||||
pfd_closing,
|
pfd_closing,
|
||||||
@ -231,7 +232,7 @@ char *pfd_addforward(char *desthost, int destport, int port, void *backhandle)
|
|||||||
pr->waiting = NULL;
|
pr->waiting = NULL;
|
||||||
pr->backhandle = backhandle;
|
pr->backhandle = backhandle;
|
||||||
|
|
||||||
pr->s = s = new_listener(port, (Plug) pr, !cfg.lport_acceptall);
|
pr->s = s = new_listener(srcaddr, port, (Plug) pr, !cfg.lport_acceptall);
|
||||||
if ((err = sk_socket_error(s))) {
|
if ((err = sk_socket_error(s))) {
|
||||||
sfree(pr);
|
sfree(pr);
|
||||||
return err;
|
return err;
|
||||||
|
4
proxy.c
4
proxy.c
@ -404,13 +404,13 @@ Socket new_connection(SockAddr addr, char *hostname,
|
|||||||
return sk_new(addr, port, privport, oobinline, nodelay, plug);
|
return sk_new(addr, port, privport, oobinline, nodelay, plug);
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket new_listener(int port, Plug plug, int local_host_only)
|
Socket new_listener(char *srcaddr, int port, Plug plug, int local_host_only)
|
||||||
{
|
{
|
||||||
/* TODO: SOCKS (and potentially others) support inbound
|
/* TODO: SOCKS (and potentially others) support inbound
|
||||||
* TODO: connections via the proxy. support them.
|
* TODO: connections via the proxy. support them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return sk_newlistener(port, plug, local_host_only);
|
return sk_newlistener(srcaddr, port, plug, local_host_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
|
99
ssh.c
99
ssh.c
@ -299,8 +299,8 @@ extern void x11_unthrottle(Socket s);
|
|||||||
extern void x11_override_throttle(Socket s, int enable);
|
extern void x11_override_throttle(Socket s, int enable);
|
||||||
|
|
||||||
extern char *pfd_newconnect(Socket * s, char *hostname, int port, void *c);
|
extern char *pfd_newconnect(Socket * s, char *hostname, int port, void *c);
|
||||||
extern char *pfd_addforward(char *desthost, int destport, int port,
|
extern char *pfd_addforward(char *desthost, int destport, char *srcaddr,
|
||||||
void *backhandle);
|
int port, void *backhandle);
|
||||||
extern void pfd_close(Socket s);
|
extern void pfd_close(Socket s);
|
||||||
extern int pfd_send(Socket s, char *data, int len);
|
extern int pfd_send(Socket s, char *data, int len);
|
||||||
extern void pfd_confirm(Socket s);
|
extern void pfd_confirm(Socket s);
|
||||||
@ -3071,28 +3071,46 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||||||
char type;
|
char type;
|
||||||
int n;
|
int n;
|
||||||
int sport,dport,sserv,dserv;
|
int sport,dport,sserv,dserv;
|
||||||
char sports[256], dports[256], host[256];
|
char sports[256], dports[256], saddr[256], host[256];
|
||||||
|
|
||||||
ssh->rportfwds = newtree234(ssh_rportcmp_ssh1);
|
ssh->rportfwds = newtree234(ssh_rportcmp_ssh1);
|
||||||
/* Add port forwardings. */
|
/* Add port forwardings. */
|
||||||
ssh->portfwd_strptr = cfg.portfwd;
|
ssh->portfwd_strptr = cfg.portfwd;
|
||||||
while (*ssh->portfwd_strptr) {
|
while (*ssh->portfwd_strptr) {
|
||||||
type = *ssh->portfwd_strptr++;
|
type = *ssh->portfwd_strptr++;
|
||||||
|
saddr[0] = '\0';
|
||||||
n = 0;
|
n = 0;
|
||||||
while (*ssh->portfwd_strptr && *ssh->portfwd_strptr != '\t')
|
while (*ssh->portfwd_strptr && *ssh->portfwd_strptr != '\t') {
|
||||||
sports[n++] = *ssh->portfwd_strptr++;
|
if (*ssh->portfwd_strptr == ':') {
|
||||||
|
/*
|
||||||
|
* We've seen a colon in the middle of the
|
||||||
|
* source port number. This means that
|
||||||
|
* everything we've seen until now is the
|
||||||
|
* source _address_, so we'll move it into
|
||||||
|
* saddr and start sports from the beginning
|
||||||
|
* again.
|
||||||
|
*/
|
||||||
|
ssh->portfwd_strptr++;
|
||||||
|
sports[n] = '\0';
|
||||||
|
strcpy(saddr, sports);
|
||||||
|
n = 0;
|
||||||
|
}
|
||||||
|
if (n < 255) sports[n++] = *ssh->portfwd_strptr++;
|
||||||
|
}
|
||||||
sports[n] = 0;
|
sports[n] = 0;
|
||||||
if (*ssh->portfwd_strptr == '\t')
|
if (*ssh->portfwd_strptr == '\t')
|
||||||
ssh->portfwd_strptr++;
|
ssh->portfwd_strptr++;
|
||||||
n = 0;
|
n = 0;
|
||||||
while (*ssh->portfwd_strptr && *ssh->portfwd_strptr != ':')
|
while (*ssh->portfwd_strptr && *ssh->portfwd_strptr != ':') {
|
||||||
host[n++] = *ssh->portfwd_strptr++;
|
if (n < 255) host[n++] = *ssh->portfwd_strptr++;
|
||||||
|
}
|
||||||
host[n] = 0;
|
host[n] = 0;
|
||||||
if (*ssh->portfwd_strptr == ':')
|
if (*ssh->portfwd_strptr == ':')
|
||||||
ssh->portfwd_strptr++;
|
ssh->portfwd_strptr++;
|
||||||
n = 0;
|
n = 0;
|
||||||
while (*ssh->portfwd_strptr)
|
while (*ssh->portfwd_strptr) {
|
||||||
dports[n++] = *ssh->portfwd_strptr++;
|
if (n < 255) dports[n++] = *ssh->portfwd_strptr++;
|
||||||
|
}
|
||||||
dports[n] = 0;
|
dports[n] = 0;
|
||||||
ssh->portfwd_strptr++;
|
ssh->portfwd_strptr++;
|
||||||
dport = atoi(dports);
|
dport = atoi(dports);
|
||||||
@ -3117,9 +3135,12 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||||||
}
|
}
|
||||||
if (sport && dport) {
|
if (sport && dport) {
|
||||||
if (type == 'L') {
|
if (type == 'L') {
|
||||||
pfd_addforward(host, dport, sport, ssh);
|
pfd_addforward(host, dport, *saddr ? saddr : NULL,
|
||||||
logeventf(ssh, "Local port %.*s%.*s%d%.*s forwarding to"
|
sport, ssh);
|
||||||
" %s:%.*s%.*s%d%.*s",
|
logeventf(ssh, "Local port %.*s%.*s%.*s%.*s%d%.*s"
|
||||||
|
" forwarding to %s:%.*s%.*s%d%.*s",
|
||||||
|
(int)(*saddr?strlen(saddr):0), *saddr?saddr:NULL,
|
||||||
|
(int)(*saddr?1:0), ":",
|
||||||
(int)(sserv ? strlen(sports) : 0), sports,
|
(int)(sserv ? strlen(sports) : 0), sports,
|
||||||
sserv, "(", sport, sserv, ")",
|
sserv, "(", sport, sserv, ")",
|
||||||
host,
|
host,
|
||||||
@ -3130,6 +3151,11 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||||||
pf = smalloc(sizeof(*pf));
|
pf = smalloc(sizeof(*pf));
|
||||||
strcpy(pf->dhost, host);
|
strcpy(pf->dhost, host);
|
||||||
pf->dport = dport;
|
pf->dport = dport;
|
||||||
|
if (saddr) {
|
||||||
|
logeventf(ssh,
|
||||||
|
"SSH1 cannot handle source address spec \"%s:%d\"; ignoring",
|
||||||
|
saddr, sport);
|
||||||
|
}
|
||||||
if (add234(ssh->rportfwds, pf) != pf) {
|
if (add234(ssh->rportfwds, pf) != pf) {
|
||||||
logeventf(ssh,
|
logeventf(ssh,
|
||||||
"Duplicate remote port forwarding to %s:%d",
|
"Duplicate remote port forwarding to %s:%d",
|
||||||
@ -5102,28 +5128,46 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||||||
char type;
|
char type;
|
||||||
int n;
|
int n;
|
||||||
int sport,dport,sserv,dserv;
|
int sport,dport,sserv,dserv;
|
||||||
char sports[256], dports[256], host[256];
|
char sports[256], dports[256], saddr[256], host[256];
|
||||||
|
|
||||||
ssh->rportfwds = newtree234(ssh_rportcmp_ssh2);
|
ssh->rportfwds = newtree234(ssh_rportcmp_ssh2);
|
||||||
/* Add port forwardings. */
|
/* Add port forwardings. */
|
||||||
ssh->portfwd_strptr = cfg.portfwd;
|
ssh->portfwd_strptr = cfg.portfwd;
|
||||||
while (*ssh->portfwd_strptr) {
|
while (*ssh->portfwd_strptr) {
|
||||||
type = *ssh->portfwd_strptr++;
|
type = *ssh->portfwd_strptr++;
|
||||||
|
saddr[0] = '\0';
|
||||||
n = 0;
|
n = 0;
|
||||||
while (*ssh->portfwd_strptr && *ssh->portfwd_strptr != '\t')
|
while (*ssh->portfwd_strptr && *ssh->portfwd_strptr != '\t') {
|
||||||
sports[n++] = *ssh->portfwd_strptr++;
|
if (*ssh->portfwd_strptr == ':') {
|
||||||
|
/*
|
||||||
|
* We've seen a colon in the middle of the
|
||||||
|
* source port number. This means that
|
||||||
|
* everything we've seen until now is the
|
||||||
|
* source _address_, so we'll move it into
|
||||||
|
* saddr and start sports from the beginning
|
||||||
|
* again.
|
||||||
|
*/
|
||||||
|
ssh->portfwd_strptr++;
|
||||||
|
sports[n] = '\0';
|
||||||
|
strcpy(saddr, sports);
|
||||||
|
n = 0;
|
||||||
|
}
|
||||||
|
if (n < 255) sports[n++] = *ssh->portfwd_strptr++;
|
||||||
|
}
|
||||||
sports[n] = 0;
|
sports[n] = 0;
|
||||||
if (*ssh->portfwd_strptr == '\t')
|
if (*ssh->portfwd_strptr == '\t')
|
||||||
ssh->portfwd_strptr++;
|
ssh->portfwd_strptr++;
|
||||||
n = 0;
|
n = 0;
|
||||||
while (*ssh->portfwd_strptr && *ssh->portfwd_strptr != ':')
|
while (*ssh->portfwd_strptr && *ssh->portfwd_strptr != ':') {
|
||||||
host[n++] = *ssh->portfwd_strptr++;
|
if (n < 255) host[n++] = *ssh->portfwd_strptr++;
|
||||||
|
}
|
||||||
host[n] = 0;
|
host[n] = 0;
|
||||||
if (*ssh->portfwd_strptr == ':')
|
if (*ssh->portfwd_strptr == ':')
|
||||||
ssh->portfwd_strptr++;
|
ssh->portfwd_strptr++;
|
||||||
n = 0;
|
n = 0;
|
||||||
while (*ssh->portfwd_strptr)
|
while (*ssh->portfwd_strptr) {
|
||||||
dports[n++] = *ssh->portfwd_strptr++;
|
if (n < 255) dports[n++] = *ssh->portfwd_strptr++;
|
||||||
|
}
|
||||||
dports[n] = 0;
|
dports[n] = 0;
|
||||||
ssh->portfwd_strptr++;
|
ssh->portfwd_strptr++;
|
||||||
dport = atoi(dports);
|
dport = atoi(dports);
|
||||||
@ -5148,9 +5192,12 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||||||
}
|
}
|
||||||
if (sport && dport) {
|
if (sport && dport) {
|
||||||
if (type == 'L') {
|
if (type == 'L') {
|
||||||
pfd_addforward(host, dport, sport, ssh);
|
pfd_addforward(host, dport, *saddr ? saddr : NULL,
|
||||||
logeventf(ssh, "Local port %.*s%.*s%d%.*s forwarding to"
|
sport, ssh);
|
||||||
" %s:%.*s%.*s%d%.*s",
|
logeventf(ssh, "Local port %.*s%.*s%.*s%.*s%d%.*s"
|
||||||
|
" forwarding to %s:%.*s%.*s%d%.*s",
|
||||||
|
(int)(*saddr?strlen(saddr):0), *saddr?saddr:NULL,
|
||||||
|
(int)(*saddr?1:0), ":",
|
||||||
(int)(sserv ? strlen(sports) : 0), sports,
|
(int)(sserv ? strlen(sports) : 0), sports,
|
||||||
sserv, "(", sport, sserv, ")",
|
sserv, "(", sport, sserv, ")",
|
||||||
host,
|
host,
|
||||||
@ -5167,8 +5214,12 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||||||
" to %s:%d", host, dport);
|
" to %s:%d", host, dport);
|
||||||
sfree(pf);
|
sfree(pf);
|
||||||
} else {
|
} else {
|
||||||
logeventf(ssh, "Requesting remote port %.*s%.*s%d%.*s"
|
logeventf(ssh, "Requesting remote port "
|
||||||
|
"%.*s%.*s%.*s%.*s%d%.*s"
|
||||||
" forward to %s:%.*s%.*s%d%.*s",
|
" forward to %s:%.*s%.*s%d%.*s",
|
||||||
|
(int)(*saddr?strlen(saddr):0),
|
||||||
|
*saddr?saddr:NULL,
|
||||||
|
(int)(*saddr?1:0), ":",
|
||||||
(int)(sserv ? strlen(sports) : 0), sports,
|
(int)(sserv ? strlen(sports) : 0), sports,
|
||||||
sserv, "(", sport, sserv, ")",
|
sserv, "(", sport, sserv, ")",
|
||||||
host,
|
host,
|
||||||
@ -5177,6 +5228,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||||||
ssh2_pkt_init(ssh, SSH2_MSG_GLOBAL_REQUEST);
|
ssh2_pkt_init(ssh, SSH2_MSG_GLOBAL_REQUEST);
|
||||||
ssh2_pkt_addstring(ssh, "tcpip-forward");
|
ssh2_pkt_addstring(ssh, "tcpip-forward");
|
||||||
ssh2_pkt_addbool(ssh, 1);/* want reply */
|
ssh2_pkt_addbool(ssh, 1);/* want reply */
|
||||||
|
if (*saddr)
|
||||||
|
ssh2_pkt_addstring(ssh, saddr);
|
||||||
if (cfg.rport_acceptall)
|
if (cfg.rport_acceptall)
|
||||||
ssh2_pkt_addstring(ssh, "0.0.0.0");
|
ssh2_pkt_addstring(ssh, "0.0.0.0");
|
||||||
else
|
else
|
||||||
|
30
unix/uxnet.c
30
unix/uxnet.c
@ -21,6 +21,8 @@
|
|||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "tree234.h"
|
#include "tree234.h"
|
||||||
|
|
||||||
|
#define ipv4_is_loopback(addr) (inet_netof(addr) == IN_LOOPBACKNET)
|
||||||
|
|
||||||
struct Socket_tag {
|
struct Socket_tag {
|
||||||
struct socket_function_table *fn;
|
struct socket_function_table *fn;
|
||||||
/* the above variable absolutely *must* be the first in this structure */
|
/* the above variable absolutely *must* be the first in this structure */
|
||||||
@ -474,7 +476,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
|||||||
return (Socket) ret;
|
return (Socket) ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket sk_newlistener(int port, Plug plug, int local_host_only)
|
Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
|
||||||
{
|
{
|
||||||
static struct socket_function_table fn_table = {
|
static struct socket_function_table fn_table = {
|
||||||
sk_tcp_plug,
|
sk_tcp_plug,
|
||||||
@ -534,6 +536,8 @@ Socket sk_newlistener(int port, Plug plug, int local_host_only)
|
|||||||
if (addr->family == AF_INET6) {
|
if (addr->family == AF_INET6) {
|
||||||
memset(&a6, 0, sizeof(a6));
|
memset(&a6, 0, sizeof(a6));
|
||||||
a6.sin6_family = AF_INET6;
|
a6.sin6_family = AF_INET6;
|
||||||
|
/* FIXME: srcaddr is ignored for IPv6, because I (SGT) don't
|
||||||
|
* know how to do it. :-) */
|
||||||
if (local_host_only)
|
if (local_host_only)
|
||||||
a6.sin6_addr = in6addr_loopback;
|
a6.sin6_addr = in6addr_loopback;
|
||||||
else
|
else
|
||||||
@ -542,11 +546,32 @@ Socket sk_newlistener(int port, Plug plug, int local_host_only)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
int got_addr = 0;
|
||||||
a.sin_family = AF_INET;
|
a.sin_family = AF_INET;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind to source address. First try an explicitly
|
||||||
|
* specified one...
|
||||||
|
*/
|
||||||
|
if (srcaddr) {
|
||||||
|
a.sin_addr.s_addr = inet_addr(srcaddr);
|
||||||
|
if (a.sin_addr.s_addr != INADDR_NONE) {
|
||||||
|
/* Override localhost_only with specified listen addr. */
|
||||||
|
ret->localhost_only = ipv4_is_loopback(a.sin_addr);
|
||||||
|
got_addr = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ... and failing that, go with one of the standard ones.
|
||||||
|
*/
|
||||||
|
if (!got_addr) {
|
||||||
if (local_host_only)
|
if (local_host_only)
|
||||||
a.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
a.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
else
|
else
|
||||||
a.sin_addr.s_addr = htonl(INADDR_ANY);
|
a.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
}
|
||||||
|
|
||||||
a.sin_port = htons((short)port);
|
a.sin_port = htons((short)port);
|
||||||
}
|
}
|
||||||
#ifdef IPV6
|
#ifdef IPV6
|
||||||
@ -763,8 +788,7 @@ int select_result(int fd, int event)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->localhost_only &&
|
if (s->localhost_only && !ipv4_is_loopback(isa.sin_addr)) {
|
||||||
ntohl(isa.sin_addr.s_addr) != INADDR_LOOPBACK) {
|
|
||||||
close(t); /* someone let nonlocal through?! */
|
close(t); /* someone let nonlocal through?! */
|
||||||
} else if (plug_accepting(s->plug, (void*)t)) {
|
} else if (plug_accepting(s->plug, (void*)t)) {
|
||||||
close(t); /* denied or error */
|
close(t); /* denied or error */
|
||||||
|
31
winnet.c
31
winnet.c
@ -55,6 +55,9 @@
|
|||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "tree234.h"
|
#include "tree234.h"
|
||||||
|
|
||||||
|
#define ipv4_is_loopback(addr) \
|
||||||
|
((ntohl(addr.s_addr) & 0xFF000000L) == 0x7F000000L)
|
||||||
|
|
||||||
struct Socket_tag {
|
struct Socket_tag {
|
||||||
struct socket_function_table *fn;
|
struct socket_function_table *fn;
|
||||||
/* the above variable absolutely *must* be the first in this structure */
|
/* the above variable absolutely *must* be the first in this structure */
|
||||||
@ -654,7 +657,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
|||||||
return (Socket) ret;
|
return (Socket) ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket sk_newlistener(int port, Plug plug, int local_host_only)
|
Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
|
||||||
{
|
{
|
||||||
static struct socket_function_table fn_table = {
|
static struct socket_function_table fn_table = {
|
||||||
sk_tcp_plug,
|
sk_tcp_plug,
|
||||||
@ -716,6 +719,8 @@ Socket sk_newlistener(int port, Plug plug, int local_host_only)
|
|||||||
if (addr->family == AF_INET6) {
|
if (addr->family == AF_INET6) {
|
||||||
memset(&a6, 0, sizeof(a6));
|
memset(&a6, 0, sizeof(a6));
|
||||||
a6.sin6_family = AF_INET6;
|
a6.sin6_family = AF_INET6;
|
||||||
|
/* FIXME: srcaddr is ignored for IPv6, because I (SGT) don't
|
||||||
|
* know how to do it. :-) */
|
||||||
if (local_host_only)
|
if (local_host_only)
|
||||||
a6.sin6_addr = in6addr_loopback;
|
a6.sin6_addr = in6addr_loopback;
|
||||||
else
|
else
|
||||||
@ -724,11 +729,32 @@ Socket sk_newlistener(int port, Plug plug, int local_host_only)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
int got_addr = 0;
|
||||||
a.sin_family = AF_INET;
|
a.sin_family = AF_INET;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind to source address. First try an explicitly
|
||||||
|
* specified one...
|
||||||
|
*/
|
||||||
|
if (srcaddr) {
|
||||||
|
a.sin_addr.s_addr = inet_addr(srcaddr);
|
||||||
|
if (a.sin_addr.s_addr != INADDR_NONE) {
|
||||||
|
/* Override localhost_only with specified listen addr. */
|
||||||
|
ret->localhost_only = ipv4_is_loopback(a.sin_addr);
|
||||||
|
got_addr = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ... and failing that, go with one of the standard ones.
|
||||||
|
*/
|
||||||
|
if (!got_addr) {
|
||||||
if (local_host_only)
|
if (local_host_only)
|
||||||
a.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
a.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
else
|
else
|
||||||
a.sin_addr.s_addr = htonl(INADDR_ANY);
|
a.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
}
|
||||||
|
|
||||||
a.sin_port = htons((short)port);
|
a.sin_port = htons((short)port);
|
||||||
}
|
}
|
||||||
#ifdef IPV6
|
#ifdef IPV6
|
||||||
@ -1047,8 +1073,7 @@ int select_result(WPARAM wParam, LPARAM lParam)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->localhost_only &&
|
if (s->localhost_only && !ipv4_is_loopback(isa.sin_addr)) {
|
||||||
ntohl(isa.sin_addr.s_addr) != INADDR_LOOPBACK) {
|
|
||||||
closesocket(t); /* dodgy WinSock let nonlocal through */
|
closesocket(t); /* dodgy WinSock let nonlocal through */
|
||||||
} else if (plug_accepting(s->plug, (void*)t)) {
|
} else if (plug_accepting(s->plug, (void*)t)) {
|
||||||
closesocket(t); /* denied or error */
|
closesocket(t); /* denied or error */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user